Skip to content

Commit 130ae65

Browse files
Anna SchumakerTrond Myklebust
authored andcommitted
NFS: Add support for sending GDD_GETATTR
I add this to the existing GETATTR compound as an option extra step that we can send if the "dir_deleg" flag is set to 'true'. Actually enabling this value will happen in a later patch. Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
1 parent e0f8058 commit 130ae65

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

fs/nfs/nfs4xdr.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,20 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
393393
XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5)
394394
#define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4)
395395
#define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4)
396+
#define encode_get_dir_deleg_maxsz (op_encode_hdr_maxsz + \
397+
4 /* gdda_signal_deleg_avail */ + \
398+
8 /* gdda_notification_types */ + \
399+
nfstime4_maxsz /* gdda_child_attr_delay */ + \
400+
nfstime4_maxsz /* gdda_dir_attr_delay */ + \
401+
nfs4_fattr_bitmap_maxsz /* gdda_child_attributes */ + \
402+
nfs4_fattr_bitmap_maxsz /* gdda_dir_attributes */)
403+
#define decode_get_dir_deleg_maxsz (op_decode_hdr_maxsz + \
404+
4 /* gddrnf_status */ + \
405+
encode_verifier_maxsz /* gddr_cookieverf */ + \
406+
encode_stateid_maxsz /* gddr_stateid */ + \
407+
8 /* gddr_notification */ + \
408+
nfs4_fattr_maxsz /* gddr_child_attributes */ + \
409+
nfs4_fattr_maxsz /* gddr_dir_attributes */)
396410
#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + \
397411
XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
398412
1 /* layout type */ + \
@@ -444,6 +458,8 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
444458
#else /* CONFIG_NFS_V4_1 */
445459
#define encode_sequence_maxsz 0
446460
#define decode_sequence_maxsz 0
461+
#define encode_get_dir_deleg_maxsz 0
462+
#define decode_get_dir_deleg_maxsz 0
447463
#define encode_layoutreturn_maxsz 0
448464
#define decode_layoutreturn_maxsz 0
449465
#define encode_layoutget_maxsz 0
@@ -631,11 +647,13 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
631647
#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \
632648
encode_sequence_maxsz + \
633649
encode_putfh_maxsz + \
650+
encode_get_dir_deleg_maxsz + \
634651
encode_getattr_maxsz + \
635652
encode_renew_maxsz)
636653
#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \
637654
decode_sequence_maxsz + \
638655
decode_putfh_maxsz + \
656+
decode_get_dir_deleg_maxsz + \
639657
decode_getattr_maxsz + \
640658
decode_renew_maxsz)
641659
#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \
@@ -2007,6 +2025,33 @@ static void encode_sequence(struct xdr_stream *xdr,
20072025
}
20082026

20092027
#ifdef CONFIG_NFS_V4_1
2028+
static void
2029+
encode_get_dir_delegation(struct xdr_stream *xdr, struct compound_hdr *hdr)
2030+
{
2031+
struct timespec64 ts = { 0, 0 };
2032+
u32 notifications[1] = { 0 };
2033+
u32 attributes[1] = { 0 };
2034+
__be32 *p;
2035+
2036+
encode_op_hdr(xdr, OP_GET_DIR_DELEGATION, decode_get_dir_deleg_maxsz, hdr);
2037+
2038+
/* We don't handle CB_RECALLABLE_OBJ_AVAIL yet. */
2039+
xdr_stream_encode_bool(xdr, false);
2040+
2041+
xdr_encode_bitmap4(xdr, notifications, ARRAY_SIZE(notifications));
2042+
2043+
/* Request no delay on attribute updates */
2044+
p = reserve_space(xdr, 12 + 12);
2045+
p = xdr_encode_nfstime4(p, &ts);
2046+
xdr_encode_nfstime4(p, &ts);
2047+
2048+
/* Requested child attributes */
2049+
xdr_encode_bitmap4(xdr, attributes, ARRAY_SIZE(attributes));
2050+
2051+
/* Requested dir attributes */
2052+
xdr_encode_bitmap4(xdr, attributes, ARRAY_SIZE(attributes));
2053+
}
2054+
20102055
static void
20112056
encode_getdeviceinfo(struct xdr_stream *xdr,
20122057
const struct nfs4_getdeviceinfo_args *args,
@@ -2142,6 +2187,11 @@ static void encode_free_stateid(struct xdr_stream *xdr,
21422187
encode_nfs4_stateid(xdr, &args->stateid);
21432188
}
21442189
#else
2190+
static inline void
2191+
encode_get_dir_delegation(struct xdr_stream *xdr, struct compound_hdr *hdr)
2192+
{
2193+
}
2194+
21452195
static inline void
21462196
encode_layoutreturn(struct xdr_stream *xdr,
21472197
const struct nfs4_layoutreturn_args *args,
@@ -2356,6 +2406,8 @@ static void nfs4_xdr_enc_getattr(struct rpc_rqst *req, struct xdr_stream *xdr,
23562406
encode_compound_hdr(xdr, req, &hdr);
23572407
encode_sequence(xdr, &args->seq_args, &hdr);
23582408
encode_putfh(xdr, args->fh, &hdr);
2409+
if (args->get_dir_deleg)
2410+
encode_get_dir_delegation(xdr, &hdr);
23592411
encode_getfattr(xdr, args->bitmask, &hdr);
23602412
encode_nops(&hdr);
23612413
}
@@ -5994,6 +6046,49 @@ static int decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
59946046
return decode_stateid(xdr, stateid);
59956047
}
59966048

6049+
static int decode_get_dir_delegation(struct xdr_stream *xdr,
6050+
struct nfs4_getattr_res *res)
6051+
{
6052+
struct nfs4_gdd_res *gdd_res = res->gdd_res;
6053+
nfs4_verifier cookieverf;
6054+
u32 bitmap[1];
6055+
int status;
6056+
6057+
status = decode_op_hdr(xdr, OP_GET_DIR_DELEGATION);
6058+
if (status)
6059+
return status;
6060+
6061+
if (xdr_stream_decode_u32(xdr, &gdd_res->status))
6062+
return -EIO;
6063+
6064+
if (gdd_res->status == GDD4_UNAVAIL)
6065+
return xdr_inline_decode(xdr, 4) ? 0 : -EIO;
6066+
6067+
status = decode_verifier(xdr, &cookieverf);
6068+
if (status)
6069+
return status;
6070+
6071+
status = decode_delegation_stateid(xdr, &gdd_res->deleg);
6072+
if (status)
6073+
return status;
6074+
6075+
/* Decode supported notification types. */
6076+
status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap));
6077+
if (status < 0)
6078+
return status;
6079+
6080+
/* Decode supported child attributes. */
6081+
status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap));
6082+
if (status < 0)
6083+
return status;
6084+
6085+
/* Decode supported attributes. */
6086+
status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap));
6087+
if (status < 0)
6088+
return status;
6089+
return 0;
6090+
}
6091+
59976092
static int decode_getdeviceinfo(struct xdr_stream *xdr,
59986093
struct nfs4_getdeviceinfo_res *res)
59996094
{
@@ -6208,6 +6303,12 @@ static int decode_free_stateid(struct xdr_stream *xdr,
62086303
return res->status;
62096304
}
62106305
#else
6306+
static int decode_get_dir_delegation(struct xdr_stream *xdr,
6307+
struct nfs4_getattr_res *res)
6308+
{
6309+
return 0;
6310+
}
6311+
62116312
static inline
62126313
int decode_layoutreturn(struct xdr_stream *xdr,
62136314
struct nfs4_layoutreturn_res *res)
@@ -6525,6 +6626,11 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
65256626
status = decode_putfh(xdr);
65266627
if (status)
65276628
goto out;
6629+
if (res->gdd_res) {
6630+
status = decode_get_dir_delegation(xdr, res);
6631+
if (status)
6632+
goto out;
6633+
}
65286634
status = decode_getfattr(xdr, res->fattr, res->server);
65296635
out:
65306636
return status;

include/linux/nfs_xdr.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,12 +1092,19 @@ struct nfs4_getattr_arg {
10921092
struct nfs4_sequence_args seq_args;
10931093
const struct nfs_fh * fh;
10941094
const u32 * bitmask;
1095+
bool get_dir_deleg;
1096+
};
1097+
1098+
struct nfs4_gdd_res {
1099+
u32 status;
1100+
nfs4_stateid deleg;
10951101
};
10961102

10971103
struct nfs4_getattr_res {
10981104
struct nfs4_sequence_res seq_res;
10991105
const struct nfs_server * server;
11001106
struct nfs_fattr * fattr;
1107+
struct nfs4_gdd_res * gdd_res;
11011108
};
11021109

11031110
struct nfs4_link_arg {

0 commit comments

Comments
 (0)