Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Anna Schumaker and committed by
Trond Myklebust
130ae65c e0f8058f

+113
+106
fs/nfs/nfs4xdr.c
··· 393 393 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) 394 394 #define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4) 395 395 #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 */) 396 410 #define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + \ 397 411 XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \ 398 412 1 /* layout type */ + \ ··· 458 444 #else /* CONFIG_NFS_V4_1 */ 459 445 #define encode_sequence_maxsz 0 460 446 #define decode_sequence_maxsz 0 447 + #define encode_get_dir_deleg_maxsz 0 448 + #define decode_get_dir_deleg_maxsz 0 461 449 #define encode_layoutreturn_maxsz 0 462 450 #define decode_layoutreturn_maxsz 0 463 451 #define encode_layoutget_maxsz 0 ··· 647 631 #define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ 648 632 encode_sequence_maxsz + \ 649 633 encode_putfh_maxsz + \ 634 + encode_get_dir_deleg_maxsz + \ 650 635 encode_getattr_maxsz + \ 651 636 encode_renew_maxsz) 652 637 #define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \ 653 638 decode_sequence_maxsz + \ 654 639 decode_putfh_maxsz + \ 640 + decode_get_dir_deleg_maxsz + \ 655 641 decode_getattr_maxsz + \ 656 642 decode_renew_maxsz) 657 643 #define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \ ··· 2026 2008 2027 2009 #ifdef CONFIG_NFS_V4_1 2028 2010 static void 2011 + encode_get_dir_delegation(struct xdr_stream *xdr, struct compound_hdr *hdr) 2012 + { 2013 + struct timespec64 ts = { 0, 0 }; 2014 + u32 notifications[1] = { 0 }; 2015 + u32 attributes[1] = { 0 }; 2016 + __be32 *p; 2017 + 2018 + encode_op_hdr(xdr, OP_GET_DIR_DELEGATION, decode_get_dir_deleg_maxsz, hdr); 2019 + 2020 + /* We don't handle CB_RECALLABLE_OBJ_AVAIL yet. */ 2021 + xdr_stream_encode_bool(xdr, false); 2022 + 2023 + xdr_encode_bitmap4(xdr, notifications, ARRAY_SIZE(notifications)); 2024 + 2025 + /* Request no delay on attribute updates */ 2026 + p = reserve_space(xdr, 12 + 12); 2027 + p = xdr_encode_nfstime4(p, &ts); 2028 + xdr_encode_nfstime4(p, &ts); 2029 + 2030 + /* Requested child attributes */ 2031 + xdr_encode_bitmap4(xdr, attributes, ARRAY_SIZE(attributes)); 2032 + 2033 + /* Requested dir attributes */ 2034 + xdr_encode_bitmap4(xdr, attributes, ARRAY_SIZE(attributes)); 2035 + } 2036 + 2037 + static void 2029 2038 encode_getdeviceinfo(struct xdr_stream *xdr, 2030 2039 const struct nfs4_getdeviceinfo_args *args, 2031 2040 struct compound_hdr *hdr) ··· 2187 2142 encode_nfs4_stateid(xdr, &args->stateid); 2188 2143 } 2189 2144 #else 2145 + static inline void 2146 + encode_get_dir_delegation(struct xdr_stream *xdr, struct compound_hdr *hdr) 2147 + { 2148 + } 2149 + 2190 2150 static inline void 2191 2151 encode_layoutreturn(struct xdr_stream *xdr, 2192 2152 const struct nfs4_layoutreturn_args *args, ··· 2406 2356 encode_compound_hdr(xdr, req, &hdr); 2407 2357 encode_sequence(xdr, &args->seq_args, &hdr); 2408 2358 encode_putfh(xdr, args->fh, &hdr); 2359 + if (args->get_dir_deleg) 2360 + encode_get_dir_delegation(xdr, &hdr); 2409 2361 encode_getfattr(xdr, args->bitmask, &hdr); 2410 2362 encode_nops(&hdr); 2411 2363 } ··· 6046 5994 return decode_stateid(xdr, stateid); 6047 5995 } 6048 5996 5997 + static int decode_get_dir_delegation(struct xdr_stream *xdr, 5998 + struct nfs4_getattr_res *res) 5999 + { 6000 + struct nfs4_gdd_res *gdd_res = res->gdd_res; 6001 + nfs4_verifier cookieverf; 6002 + u32 bitmap[1]; 6003 + int status; 6004 + 6005 + status = decode_op_hdr(xdr, OP_GET_DIR_DELEGATION); 6006 + if (status) 6007 + return status; 6008 + 6009 + if (xdr_stream_decode_u32(xdr, &gdd_res->status)) 6010 + return -EIO; 6011 + 6012 + if (gdd_res->status == GDD4_UNAVAIL) 6013 + return xdr_inline_decode(xdr, 4) ? 0 : -EIO; 6014 + 6015 + status = decode_verifier(xdr, &cookieverf); 6016 + if (status) 6017 + return status; 6018 + 6019 + status = decode_delegation_stateid(xdr, &gdd_res->deleg); 6020 + if (status) 6021 + return status; 6022 + 6023 + /* Decode supported notification types. */ 6024 + status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap)); 6025 + if (status < 0) 6026 + return status; 6027 + 6028 + /* Decode supported child attributes. */ 6029 + status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap)); 6030 + if (status < 0) 6031 + return status; 6032 + 6033 + /* Decode supported attributes. */ 6034 + status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap)); 6035 + if (status < 0) 6036 + return status; 6037 + return 0; 6038 + } 6039 + 6049 6040 static int decode_getdeviceinfo(struct xdr_stream *xdr, 6050 6041 struct nfs4_getdeviceinfo_res *res) 6051 6042 { ··· 6303 6208 return res->status; 6304 6209 } 6305 6210 #else 6211 + static int decode_get_dir_delegation(struct xdr_stream *xdr, 6212 + struct nfs4_getattr_res *res) 6213 + { 6214 + return 0; 6215 + } 6216 + 6306 6217 static inline 6307 6218 int decode_layoutreturn(struct xdr_stream *xdr, 6308 6219 struct nfs4_layoutreturn_res *res) ··· 6626 6525 status = decode_putfh(xdr); 6627 6526 if (status) 6628 6527 goto out; 6528 + if (res->gdd_res) { 6529 + status = decode_get_dir_delegation(xdr, res); 6530 + if (status) 6531 + goto out; 6532 + } 6629 6533 status = decode_getfattr(xdr, res->fattr, res->server); 6630 6534 out: 6631 6535 return status;
+7
include/linux/nfs_xdr.h
··· 1092 1092 struct nfs4_sequence_args seq_args; 1093 1093 const struct nfs_fh * fh; 1094 1094 const u32 * bitmask; 1095 + bool get_dir_deleg; 1096 + }; 1097 + 1098 + struct nfs4_gdd_res { 1099 + u32 status; 1100 + nfs4_stateid deleg; 1095 1101 }; 1096 1102 1097 1103 struct nfs4_getattr_res { 1098 1104 struct nfs4_sequence_res seq_res; 1099 1105 const struct nfs_server * server; 1100 1106 struct nfs_fattr * fattr; 1107 + struct nfs4_gdd_res * gdd_res; 1101 1108 }; 1102 1109 1103 1110 struct nfs4_link_arg {