nfs41 client patches for review
Subsystems (4)
cover nfs41 client patches for review
Trond,
Here's the patch series for nfs41 client side, rebased over 2.6.28 for review.
I've cleaned up the patch as much as I could in the given time frame but surely there's more work to be done.
I encourage others to comment on the patches as well.
Thanks,
Benny
pre-nfs41 patches:
[RFC 01/85] sunrpc: get rid of rpc_rqst.rq_bufsize
[RFC 02/85] nfs: return compound hdr.status when there are no op replies [RFC 03/85] nfs: remove incorrect usage of nfs4 compound response hdr.status [RFC 04/85] FIXME: NFS: Increment operation number in each encode_* routine
general defs:
[RFC 05/85] nfs41: Add Kconfig symbols for NFSv4.1
[RFC 06/85] nfs41: common protocol definitions
[RFC 07/85] nfs41: define NFS4_MAX_MINOR_VERSION based on CONFIG_NFS_V4_1 [RFC 08/85] nfs41: client xdr definitions
basic support for minorversion != 0:
[RFC 09/85] nfs41: add mount command option minorvers
[RFC 10/85] nfs41: struct nfs_server minorversion
[RFC 11/85] nfs41: nfs_client.cl_minorversion
[RFC 12/85] nfs41: set nfs_client rpc_ops based on minorversion
[RFC 13/85] nfs41: use ptr to rpc procedures via struct nfs_client
[RFC 14/85] nfs41: sunrpc: support minorversion for rpc_clnt version table. [RFC 15/85] nfs41: Proper initialization of nfs_client_initdata.rpc_ops
[RFC 16/85] nfs41: pass recovery status from reclaimer kthread up to nfs4_wait_clnt_recover [RFC 17/85] nfs41: fallback to lower minorversion if nfs4_create_server fails
sessions basic functionality:
[RFC 18/85] nfs41: sessions client infrastructure [RFC 19/85] nfs41: share client sessions across mounts [RFC 20/85] nfs41: slot table init and destroy [RFC 21/85] nfs41: find slot
[RFC 22/85] nfs41: free slot
support for sequence for legacy ops:
[RFC 23/85] nfs41: minorversion support for xdr [RFC 24/85] nfs41: stubs for nfs41 procedures [RFC 25/85] nfs41: make nfs4_wait_bit_killable public [RFC 26/85] nfs41: introduce nfs4_call_sync [RFC 27/85] nfs41: nfs4_setup_sequence
[RFC 28/85] nfs41: setup_sequence method
[RFC 29/85] nfs41: nfs41_sequence_done
[RFC 30/85] nfs41: nfs41_call_sync_done
[RFC 31/85] nfs41: separate free slot from sequence done [RFC 32/85] nfs41: sequence setup/done support [RFC 33/85] nfs41: Support sessions with O_DIRECT.
nfs41 ops:
[RFC 34/85] nfs41: exchange_id operation
[RFC 35/85] nfs41: get_lease_time
[RFC 36/85] nfs41: create_session operation
[RFC 37/85] nfs41: destroy_session operation
[RFC 38/85] nfs41: sequence operation
session setup and recovery:
[RFC 39/85] nfs41: session recovery infrastructure
[RFC 40/85] nfs41: schedule async session reset
[RFC 41/85] nfs41: lease renewal
[RFC 42/85] nfs41: sunrpc: Export the call prepare state for session reset [RFC 43/85] nfs41: use rpc prepare call state for session reset [RFC 44/85] nfs41: kick start nfs41 session recovery when handling errors [RFC 45/85] nfs41: start session recovery from nfs4_setup_sequence [RFC 46/85] nfs41: introduce get_state_renewal_cred
[RFC 47/85] nfs41: get cred in exchange_id when cred arg is NULL [RFC 48/85] nfs41: establish sessions-based clientid
[RFC 49/85] nfs41: recover lease in _nfs4_lookup_root
[RFC 50/85] nfs41: schedule state recovery on BAD or DEAD session [RFC 51/85] nfs41: state reclaimer renew lease error handling [RFC 52/85] nfs41: increment_{open,lock}_seqid
backchannel:
[RFC 53/85] nfs41: Add ability to read RPC call direction on TCP stream. [RFC 54/85] nfs41: Skip past the RPC call direction
[RFC 55/85] nfs41: Refactor NFSv4 callback service
[RFC 56/85] nfs41: client callback structures
[RFC 57/85] nfs41: Initialize new rpc_xprt callback related fields [RFC 58/85] nfs41: New backchannel helper routines
[RFC 59/85] nfs41: New include/linux/sunrpc/bc_xprt.h
[RFC 60/85] nfs41: New xs_tcp_read_data()
[RFC 61/85] nfs41: Add backchannel processing support to RPC state machine [RFC 62/85] nfs41: Backchannel callback service helper routines [RFC 63/85] FIXME: nfs41: sunrpc: handle clnt==NULL in call_status
callback service:
[RFC 64/85] nfs41: Refactor svc_process()
[RFC 65/85] nfs41: Backchannel bc_svc_process()
[RFC 66/85] nfs41: Implement NFSv4.1 callback service process.
[RFC 67/85] nfs41: sunrpc: provide functions to create and destroy a svc_xprt for backchannel use [RFC 68/85] nfs41: sunrpc: add a struct svc_xprt pointer to struct svc_serv for backchannel use [RFC 69/85] nfs41: create a svc_xprt for nfs41 callback thread and use for incoming callbacks [RFC 70/85] nfs41: save svc_serv in nfs_callback_info
[RFC 71/85] nfs41: Add a reference to svc_serv during callback service bring up [RFC 72/85] nfs41: Allow NFSv4 and NFSv4.1 callback services to coexist
[RFC 73/85] nfs41: Setup the backchannel
[RFC 74/85] nfs41: Client indicates presence of NFSv4.1 callback channel.
[RFC 75/85] nfs41: Get the rpc_xprt * from the rpc_rqst instead of the rpc_clnt. [RFC 76/85] nfs41: Release backchannel resources associated with session
callback processing:
[RFC 77/85] nfs41: store minorversion in cb_compound_hdr_arg [RFC 78/85] nfs41: decode minorversion 1 cb_compound header [RFC 79/85] nfs41: callback numbers definitions
[RFC 80/85] nfs41: consider minorversion in callback_xdr:process_op [RFC 81/85] nfs41: define CB_NOTIFY_DEVICEID as not supported [RFC 82/85] nfs41: cb_sequence protocol level data structures [RFC 83/85] nfs41: cb_sequence proc implementation
[RFC 84/85] nfs41: cb_sequence xdr implementation
[RFC 85/85] nfs41: verify CB_SEQUENCE position in callback compound
RFC 2/85 nfs: return compound hdr.status when there are no op replies
When there are no op replies encoded in the compound reply hdr.status still contains the overall status of the compound rpc. This can happen, e.g., when the server returns a NFS4ERR_MINOR_VERS_MISMATCH error.
--- fs/nfs/nfs4xdr.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
fs/nfs/nfs4xdr.c +2 -0
@@ -2222,6 +2222,8 @@ static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) hdr->tag = (char *)p; p +=XDR_QUADLEN (hdr->taglen);READ32 (hdr->nops); +if (unlikely (hdr->nops <1 )) +return nfs4_stat_to_errno (hdr->status);return 0 ; }
Signature · 1 line
1.6.0.2
RFC 3/85 nfs: remove incorrect usage of nfs4 compound response hdr.status
In reply to Benny Halevy3 call sites look at hdr.status before returning success. hdr.status must be zero in this case so there's no point in this.
Currently, hdr.status is correctly processed at decode_op_hdr time if the op status cannot be decoded.
--- fs/nfs/nfs4xdr.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-)
fs/nfs/nfs4xdr.c +0 -6
@@ -4423,8 +4423,6 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinf status =decode_putfh (&xdr);if (!status) status =decode_fsinfo (&xdr, fsinfo); -if (!status) - status =nfs4_stat_to_errno (hdr.status);return status; }
@@ -4513,8 +4511,6 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p, status =decode_compound_hdr (&xdr, &hdr);if (!status) status =decode_setclientid (&xdr, clp); -if (!status) - status =nfs4_stat_to_errno (hdr.status);return status; }
@@ -4535,8 +4531,6 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str status =decode_putrootfh (&xdr);if (!status) status =decode_fsinfo (&xdr, fsinfo); -if (!status) - status =nfs4_stat_to_errno (hdr.status);return status; }
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 03/85] nfs: remove incorrect usage of nfs4 compound response hdr.status
Quoted 5 lines · Benny Halevy
3 call sites look at hdr.status before returning success. hdr.status must be zero in this case so there's no point in this.
Currently, hdr.status is correctly processed at
decode_op_hdrtime if the op status cannot be decoded.
review 11-14: send to Trond
Quoted 37 lines
Signed-off-by Benny Halevy <[email protected]>--- fs/nfs/nfs4xdr.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-)fs/nfs/nfs4xdr.c +0
-6@@ -4423,8 +4423,6 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinf status =decode_putfh (&xdr);if (!status) status =decode_fsinfo (&xdr, fsinfo); -if (!status) - status =nfs4_stat_to_errno (hdr.status);return status; }@@ -4513,8 +4511,6 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p, status =decode_compound_hdr (&xdr, &hdr);if (!status) status =decode_setclientid (&xdr, clp); -if (!status) - status =nfs4_stat_to_errno (hdr.status);return status; }@@ -4535,8 +4531,6 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str status =decode_putrootfh (&xdr);if (!status) status =decode_fsinfo (&xdr, fsinfo); -if (!status) - status =nfs4_stat_to_errno (hdr.status);return status; }
RFC 4/85 FIXME: NFS: Increment operation number in each encode_* routine
In reply to Benny HalevyFrom: Andy Adamson <[email protected]>
FIXME: bhalevy: is this a good opportunity for a cleanup-only patch to fix whitespacing?
Pass in the compound_hdr and bump the number of operations in each encode_* subroutine so as to allow us to more easily construct new compound statements.
Fix tabs, do not fix 'do not use assignment in if condition' warnings.
--- fs/nfs/nfs4xdr.c | 630 ++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 401 insertions(+), 229 deletions(-)
fs/nfs/nfs4xdr.c +401 -229
@@ -578,9 +578,10 @@ static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *xdr_encode_opaque (p, str, len); } -static int encode_compound_hdr (struct xdr_stream *xdr,struct compound_hdr *hdr) +static __u32 * +encode_compound_hdr (struct xdr_stream *xdr,struct compound_hdr *hdr) { -__be32 *p; +__be32 *p, *nops;dprintk ("encode_compound: tag=%.*s\n" , (int )hdr->taglen, hdr->tag);BUG_ON (hdr->taglen >NFS4_MAXTAGLEN );
@@ -588,8 +589,14 @@ static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)WRITE32 (hdr->taglen);WRITEMEM (hdr->tag, hdr->taglen);WRITE32 (NFS4_MINOR_VERSION ); + nops = p;WRITE32 (hdr->nops); -return 0 ; +return nops; +} + +static inline void encode_nops (__be32 *nops,struct compound_hdr *hdr) +{ + *nops =htonl (hdr->nops); }static void encode_nfs4_verifier (struct xdr_stream *xdr,const nfs4_verifier *verf)
@@ -728,18 +735,22 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const sreturn status; } -static int encode_access (struct xdr_stream *xdr,u32 access) +static int +encode_access (struct xdr_stream *xdr,u32 access,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (8 );WRITE32 (OP_ACCESS );WRITE32 (access); - + hdr->nops++; +return 0 ; } -static int encode_close (struct xdr_stream *xdr,const struct nfs_closeargs *arg) +static int +encode_close (struct xdr_stream *xdr,const struct nfs_closeargs *arg, +struct compound_hdr *hdr) {__be32 *p;
@@ -747,23 +758,29 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg)WRITE32 (OP_CLOSE );WRITE32 (arg->seqid->sequence->counter);WRITEMEM (arg->stateid->data,NFS4_STATEID_SIZE ); + hdr->nops++;return 0 ; } -static int encode_commit (struct xdr_stream *xdr,const struct nfs_writeargs *args) +static int +encode_commit (struct xdr_stream *xdr,const struct nfs_writeargs *args, +struct compound_hdr *hdr) {__be32 *p; -RESERVE_SPACE (16 ); -WRITE32 (OP_COMMIT ); -WRITE64 (args->offset); -WRITE32 (args->count); +RESERVE_SPACE (16 ); +WRITE32 (OP_COMMIT ); +WRITE64 (args->offset); +WRITE32 (args->count); + hdr->nops++; -return 0 ; +return 0 ; } -static int encode_create (struct xdr_stream *xdr,const struct nfs4_create_arg *create) +static int +encode_create (struct xdr_stream *xdr,const struct nfs4_create_arg *create, +struct compound_hdr *hdr) {__be32 *p;
@@ -791,11 +808,14 @@ static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *cRESERVE_SPACE (4 + create->name->len);WRITE32 (create->name->len);WRITEMEM (create->name->name, create->name->len); + hdr->nops++;return encode_attrs (xdr, create->attrs, create->server); } -static int encode_getattr_one (struct xdr_stream *xdr,uint32_t bitmap) +static int +encode_getattr_one (struct xdr_stream *xdr,uint32_t bitmap, +struct compound_hdr *hdr) {__be32 *p;
@@ -803,10 +823,13 @@ static int encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap)WRITE32 (OP_GETATTR );WRITE32 (1 );WRITE32 (bitmap); + hdr->nops++;return 0 ; } -static int encode_getattr_two (struct xdr_stream *xdr,uint32_t bm0,uint32_t bm1) +static int +encode_getattr_two (struct xdr_stream *xdr,uint32_t bm0,uint32_t bm1, +struct compound_hdr *hdr) {__be32 *p;
@@ -815,40 +838,51 @@ static int encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1WRITE32 (2 );WRITE32 (bm0);WRITE32 (bm1); + hdr->nops++;return 0 ; } -static int encode_getfattr (struct xdr_stream *xdr,const u32 * bitmask) +static int +encode_getfattr (struct xdr_stream *xdr,const u32 *bitmask, +struct compound_hdr *hdr) {return encode_getattr_two (xdr, bitmask[0 ] & nfs4_fattr_bitmap[0 ], - bitmask[1 ] & nfs4_fattr_bitmap[1 ]); + bitmask[1 ] & nfs4_fattr_bitmap[1 ], hdr); } -static int encode_fsinfo (struct xdr_stream *xdr,const u32 * bitmask) +static int +encode_fsinfo (struct xdr_stream *xdr,const u32 *bitmask, +struct compound_hdr *hdr) {return encode_getattr_two (xdr, bitmask[0 ] & nfs4_fsinfo_bitmap[0 ], - bitmask[1 ] & nfs4_fsinfo_bitmap[1 ]); + bitmask[1 ] & nfs4_fsinfo_bitmap[1 ], hdr); } -static int encode_fs_locations (struct xdr_stream *xdr,const u32 * bitmask) +static int +encode_fs_locations (struct xdr_stream *xdr,const u32 *bitmask, +struct compound_hdr *hdr) {return encode_getattr_two (xdr, bitmask[0 ] & nfs4_fs_locations_bitmap[0 ], - bitmask[1 ] & nfs4_fs_locations_bitmap[1 ]); + bitmask[1 ] & nfs4_fs_locations_bitmap[1 ], + hdr); } -static int encode_getfh (struct xdr_stream *xdr) +static int encode_getfh (struct xdr_stream *xdr,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (4 );WRITE32 (OP_GETFH ); + hdr->nops++;return 0 ; } -static int encode_link (struct xdr_stream *xdr,const struct qstr *name) +static int +encode_link (struct xdr_stream *xdr,const struct qstr *name, +struct compound_hdr *hdr) {__be32 *p;
@@ -856,6 +890,7 @@ static int encode_link(struct xdr_stream *xdr, const struct qstr *name)WRITE32 (OP_LINK );WRITE32 (name->len);WRITEMEM (name->name, name->len); + hdr->nops++;return 0 ; }
@@ -878,7 +913,9 @@ static inline uint64_t nfs4_lock_length(struct file_lock *fl)* opcode,type,reclaim,offset,length,new_lock_owner = 32 * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40 */ -static int encode_lock (struct xdr_stream *xdr,const struct nfs_lock_args *args) +static int +encode_lock (struct xdr_stream *xdr,const struct nfs_lock_args *args, +struct compound_hdr *hdr) {__be32 *p;
@@ -904,11 +941,14 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args)WRITEMEM (args->lock_stateid->data,NFS4_STATEID_SIZE );WRITE32 (args->lock_seqid->sequence->counter); } + hdr->nops++;return 0 ; } -static int encode_lockt (struct xdr_stream *xdr,const struct nfs_lockt_args *args) +static int +encode_lockt (struct xdr_stream *xdr,const struct nfs_lockt_args *args, +struct compound_hdr *hdr) {__be32 *p;
@@ -921,11 +961,14 @@ static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *argWRITE32 (16 );WRITEMEM ("lock id:" ,8 );WRITE64 (args->lock_owner.id); + hdr->nops++;return 0 ; } -static int encode_locku (struct xdr_stream *xdr,const struct nfs_locku_args *args) +static int +encode_locku (struct xdr_stream *xdr,const struct nfs_locku_args *args, +struct compound_hdr *hdr) {__be32 *p;
@@ -936,11 +979,14 @@ static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *argWRITEMEM (args->stateid->data,NFS4_STATEID_SIZE );WRITE64 (args->fl->fl_start);WRITE64 (nfs4_lock_length (args->fl)); + hdr->nops++;return 0 ; } -static int encode_lookup (struct xdr_stream *xdr,const struct qstr *name) +static int +encode_lookup (struct xdr_stream *xdr,const struct qstr *name, +struct compound_hdr *hdr) {int len = name->len;__be32 *p;
@@ -949,6 +995,7 @@ static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name)WRITE32 (OP_LOOKUP );WRITE32 (len);WRITEMEM (name->name, len); + hdr->nops++;return 0 ; }
@@ -1072,7 +1119,9 @@ static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const strucencode_string (xdr, name->len, name->name); } -static int encode_open (struct xdr_stream *xdr,const struct nfs_openargs *arg) +static int +encode_open (struct xdr_stream *xdr,const struct nfs_openargs *arg, +struct compound_hdr *hdr) {encode_openhdr (xdr, arg);encode_opentype (xdr, arg);
@@ -1089,10 +1138,14 @@ static int encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg)default :BUG (); } + hdr->nops++;return 0 ; } -static int encode_open_confirm (struct xdr_stream *xdr,const struct nfs_open_confirmargs *arg) +static int +encode_open_confirm (struct xdr_stream *xdr, +const struct nfs_open_confirmargs *arg, +struct compound_hdr *hdr) {__be32 *p;
@@ -1100,11 +1153,14 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_conWRITE32 (OP_OPEN_CONFIRM );WRITEMEM (arg->stateid->data,NFS4_STATEID_SIZE );WRITE32 (arg->seqid->sequence->counter); + hdr->nops++;return 0 ; } -static int encode_open_downgrade (struct xdr_stream *xdr,const struct nfs_closeargs *arg) +static int +encode_open_downgrade (struct xdr_stream *xdr,const struct nfs_closeargs *arg, +struct compound_hdr *hdr) {__be32 *p;
@@ -1113,11 +1169,13 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeaWRITEMEM (arg->stateid->data,NFS4_STATEID_SIZE );WRITE32 (arg->seqid->sequence->counter);encode_share_access (xdr, arg->open_flags); + hdr->nops++;return 0 ; }static int -encode_putfh (struct xdr_stream *xdr,const struct nfs_fh *fh) +encode_putfh (struct xdr_stream *xdr,const struct nfs_fh *fh, +struct compound_hdr *hdr) {int len = fh->size;__be32 *p;
@@ -1126,21 +1184,24 @@ encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh)WRITE32 (OP_PUTFH );WRITE32 (len);WRITEMEM (fh->data, len); + hdr->nops++;return 0 ; } -static int encode_putrootfh (struct xdr_stream *xdr) +static int encode_putrootfh (struct xdr_stream *xdr,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (4 );WRITE32 (OP_PUTROOTFH ); + hdr->nops++;return 0 ; } -static void encode_stateid (struct xdr_stream *xdr,const struct nfs_open_context *ctx) +static void +encode_stateid (struct xdr_stream *xdr,const struct nfs_open_context *ctx) {nfs4_stateid stateid;__be32 *p;
@@ -1153,7 +1214,9 @@ static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_contextWRITEMEM (zero_stateid.data,NFS4_STATEID_SIZE ); } -static int encode_read (struct xdr_stream *xdr,const struct nfs_readargs *args) +static int +encode_read (struct xdr_stream *xdr,const struct nfs_readargs *args, +struct compound_hdr *hdr) {__be32 *p;
@@ -1165,11 +1228,14 @@ static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args)RESERVE_SPACE (12 );WRITE64 (args->offset);WRITE32 (args->count); + hdr->nops++;return 0 ; } -static int encode_readdir (struct xdr_stream *xdr,const struct nfs4_readdir_arg *readdir,struct rpc_rqst *req) +static int +encode_readdir (struct xdr_stream *xdr,const struct nfs4_readdir_arg *readdir, +struct rpc_rqst *req,struct compound_hdr *hdr) {uint32_t attrs[2 ] = {FATTR4_WORD0_RDATTR_ERROR |FATTR4_WORD0_FILEID ,
@@ -1191,6 +1257,7 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg attrs[1 ] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID ;WRITE32 (attrs[0 ] & readdir->bitmask[0 ]);WRITE32 (attrs[1 ] & readdir->bitmask[1 ]); + hdr->nops++; dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n", __func__, (unsigned long long)readdir->cookie,
@@ -1202,17 +1269,22 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_argreturn 0 ; } -static int encode_readlink (struct xdr_stream *xdr,const struct nfs4_readlink *readlink,struct rpc_rqst *req) +static int +encode_readlink (struct xdr_stream *xdr,const struct nfs4_readlink *readlink, +struct rpc_rqst *req,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (4 );WRITE32 (OP_READLINK ); + hdr->nops++;return 0 ; } -static int encode_remove (struct xdr_stream *xdr,const struct qstr *name) +static int +encode_remove (struct xdr_stream *xdr,const struct qstr *name, +struct compound_hdr *hdr) {__be32 *p;
@@ -1220,11 +1292,14 @@ static int encode_remove(struct xdr_stream *xdr, const struct qstr *name)WRITE32 (OP_REMOVE );WRITE32 (name->len);WRITEMEM (name->name, name->len); + hdr->nops++;return 0 ; } -static int encode_rename (struct xdr_stream *xdr,const struct qstr *oldname,const struct qstr *newname) +static int +encode_rename (struct xdr_stream *xdr,const struct qstr *oldname, +const struct qstr *newname,struct compound_hdr *hdr) {__be32 *p;
@@ -1236,34 +1311,40 @@ static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, conRESERVE_SPACE (4 + newname->len);WRITE32 (newname->len);WRITEMEM (newname->name, newname->len); + hdr->nops++;return 0 ; } -static int encode_renew (struct xdr_stream *xdr,const struct nfs_client *client_stateid) +static int +encode_renew (struct xdr_stream *xdr,const struct nfs_client *client_stateid, +struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (12 );WRITE32 (OP_RENEW );WRITE64 (client_stateid->cl_clientid); + hdr->nops++;return 0 ; }static int -encode_restorefh (struct xdr_stream *xdr) +encode_restorefh (struct xdr_stream *xdr,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (4 );WRITE32 (OP_RESTOREFH ); + hdr->nops++;return 0 ; }static int -encode_setacl (struct xdr_stream *xdr,struct nfs_setaclargs *arg) +encode_setacl (struct xdr_stream *xdr,struct nfs_setaclargs *arg, +struct compound_hdr *hdr) {__be32 *p;
@@ -1278,21 +1359,25 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)RESERVE_SPACE (4 );WRITE32 (arg->acl_len);xdr_write_pages (xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); + hdr->nops++;return 0 ; }static int -encode_savefh (struct xdr_stream *xdr) +encode_savefh (struct xdr_stream *xdr,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (4 );WRITE32 (OP_SAVEFH ); + hdr->nops++;return 0 ; } -static int encode_setattr (struct xdr_stream *xdr,const struct nfs_setattrargs *arg,const struct nfs_server *server) +static int +encode_setattr (struct xdr_stream *xdr,const struct nfs_setattrargs *arg, +const struct nfs_server *server,struct compound_hdr *hdr) {int status;__be32 *p;
@@ -1300,6 +1385,7 @@ static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *RESERVE_SPACE (4 +NFS4_STATEID_SIZE );WRITE32 (OP_SETATTR );WRITEMEM (arg->stateid.data,NFS4_STATEID_SIZE ); + hdr->nops++;if ((status =encode_attrs (xdr, arg->iap, server)))return status;
@@ -1307,7 +1393,10 @@ static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *return 0 ; } -static int encode_setclientid (struct xdr_stream *xdr,const struct nfs4_setclientid *setclientid) +static int +encode_setclientid (struct xdr_stream *xdr, +const struct nfs4_setclientid *setclientid, +struct compound_hdr *hdr) {__be32 *p;
@@ -1322,11 +1411,15 @@ static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclienencode_string (xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr);RESERVE_SPACE (4 );WRITE32 (setclientid->sc_cb_ident); + hdr->nops++;return 0 ; } -static int encode_setclientid_confirm (struct xdr_stream *xdr,const struct nfs_client *client_state) +static int +encode_setclientid_confirm (struct xdr_stream *xdr, +const struct nfs_client *client_state, +struct compound_hdr *hdr) {__be32 *p;
@@ -1334,11 +1427,14 @@ static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_cWRITE32 (OP_SETCLIENTID_CONFIRM );WRITE64 (client_state->cl_clientid);WRITEMEM (client_state->cl_confirm.data,NFS4_VERIFIER_SIZE ); + hdr->nops++;return 0 ; } -static int encode_write (struct xdr_stream *xdr,const struct nfs_writeargs *args) +static int +encode_write (struct xdr_stream *xdr,const struct nfs_writeargs *args, +struct compound_hdr *hdr) {__be32 *p;
@@ -1353,11 +1449,14 @@ static int encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *argsWRITE32 (args->count);xdr_write_pages (xdr, args->pages, args->pgbase, args->count); + hdr->nops++;return 0 ; } -static int encode_delegreturn (struct xdr_stream *xdr,const nfs4_stateid *stateid) +static int +encode_delegreturn (struct xdr_stream *xdr,const nfs4_stateid *stateid, +struct compound_hdr *hdr) {__be32 *p;
@@ -1365,6 +1464,7 @@ static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateiWRITE32 (OP_DELEGRETURN );WRITEMEM (stateid->data,NFS4_STATEID_SIZE ); + hdr->nops++;return 0 ; }
@@ -1379,20 +1479,22 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status !=0 ) goto out; - status =encode_access (&xdr, args->access); + status =encode_access (&xdr, args->access, &hdr);if (status !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1403,20 +1505,22 @@ static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =4 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->dir_fh)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out; -if ((status =encode_lookup (&xdr, args->name)) !=0 ) +if ((status =encode_lookup (&xdr, args->name, &hdr)) !=0 ) goto out; -if ((status =encode_getfh (&xdr)) !=0 ) +if ((status =encode_getfh (&xdr, &hdr)) !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1427,17 +1531,19 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struc {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putrootfh (&xdr)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putrootfh (&xdr, &hdr)) !=0 ) goto out; -if ((status =encode_getfh (&xdr)) ==0 ) - status =encode_getfattr (&xdr, args->bitmask); +if ((status =encode_getfh (&xdr, &hdr)) ==0 ) + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1448,18 +1554,20 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->fh)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->fh, &hdr)) !=0 ) goto out; -if ((status =encode_remove (&xdr, &args->name)) !=0 ) +if ((status =encode_remove (&xdr, &args->name, &hdr)) !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1470,26 +1578,29 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =7 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->old_dir)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->old_dir, &hdr)) !=0 ) goto out; -if ((status =encode_savefh (&xdr)) !=0 ) +if ((status =encode_savefh (&xdr, &hdr)) !=0 ) goto out; -if ((status =encode_putfh (&xdr, args->new_dir)) !=0 ) +if ((status =encode_putfh (&xdr, args->new_dir, &hdr)) !=0 ) goto out; -if ((status =encode_rename (&xdr, args->old_name, args->new_name)) !=0 ) +if ((status =encode_rename (&xdr, args->old_name, args->new_name, + &hdr)) !=0 ) goto out; -if ((status =encode_getfattr (&xdr, args->bitmask)) !=0 ) +if ((status =encode_getfattr (&xdr, args->bitmask, &hdr)) !=0 ) goto out; -if ((status =encode_restorefh (&xdr)) !=0 ) +if ((status =encode_restorefh (&xdr, &hdr)) !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1500,26 +1611,28 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_ {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =7 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->fh)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->fh, &hdr)) !=0 ) goto out; -if ((status =encode_savefh (&xdr)) !=0 ) +if ((status =encode_savefh (&xdr, &hdr)) !=0 ) goto out; -if ((status =encode_putfh (&xdr, args->dir_fh)) !=0 ) +if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out; -if ((status =encode_link (&xdr, args->name)) !=0 ) +if ((status =encode_link (&xdr, args->name, &hdr)) !=0 ) goto out; -if ((status =encode_getfattr (&xdr, args->bitmask)) !=0 ) +if ((status =encode_getfattr (&xdr, args->bitmask, &hdr)) !=0 ) goto out; -if ((status =encode_restorefh (&xdr)) !=0 ) +if ((status =encode_restorefh (&xdr, &hdr)) !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1530,26 +1643,28 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =7 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->dir_fh)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out; -if ((status =encode_savefh (&xdr)) !=0 ) +if ((status =encode_savefh (&xdr, &hdr)) !=0 ) goto out; -if ((status =encode_create (&xdr, args)) !=0 ) +if ((status =encode_create (&xdr, args, &hdr)) !=0 ) goto out; -if ((status =encode_getfh (&xdr)) !=0 ) +if ((status =encode_getfh (&xdr, &hdr)) !=0 ) goto out; -if ((status =encode_getfattr (&xdr, args->bitmask)) !=0 ) +if ((status =encode_getfattr (&xdr, args->bitmask, &hdr)) !=0 ) goto out; -if ((status =encode_restorefh (&xdr)) !=0 ) +if ((status =encode_restorefh (&xdr, &hdr)) !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1568,14 +1683,16 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->fh)) ==0 ) - status =encode_getfattr (&xdr, args->bitmask); + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->fh, &hdr)) ==0 ) + status =encode_getfattr (&xdr, args->bitmask, &hdr); +encode_nops (nops, &hdr);return status; }
@@ -1586,20 +1703,22 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closea {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_close (&xdr, args); + status =encode_close (&xdr, args, &hdr);if (status !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1610,32 +1729,34 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openarg {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =7 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_savefh (&xdr); + status =encode_savefh (&xdr, &hdr);if (status) goto out; - status =encode_open (&xdr, args); + status =encode_open (&xdr, args, &hdr);if (status) goto out; - status =encode_getfh (&xdr); + status =encode_getfh (&xdr, &hdr);if (status) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr);if (status) goto out; - status =encode_restorefh (&xdr); + status =encode_restorefh (&xdr, &hdr);if (status) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1646,17 +1767,19 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_open_confirm (&xdr, args); + status =encode_open_confirm (&xdr, args, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1667,20 +1790,22 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_ {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_open (&xdr, args); + status =encode_open (&xdr, args, &hdr);if (status) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1691,20 +1816,22 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct n {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_open_downgrade (&xdr, args); + status =encode_open_downgrade (&xdr, args, &hdr);if (status !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1715,17 +1842,19 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_ar {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_lock (&xdr, args); + status =encode_lock (&xdr, args, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1736,17 +1865,19 @@ static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_ {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_lockt (&xdr, args); + status =encode_lockt (&xdr, args, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1757,17 +1888,19 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_ {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_locku (&xdr, args); + status =encode_locku (&xdr, args, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1778,18 +1911,19 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;unsigned int replen;int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_readlink (&xdr, args, req); + status =encode_readlink (&xdr, args, req, &hdr);/* set up reply kvec * toplevel_status + taglen + rescount + OP_PUTFH + status
@@ -1800,6 +1934,7 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n args->pgbase, args->pglen); out: +encode_nops (nops, &hdr);return status; }
@@ -1810,18 +1945,19 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;int replen;int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_readdir (&xdr, args, req); + status =encode_readdir (&xdr, args, req, &hdr);/* set up reply kvec * toplevel_status + taglen + rescount + OP_PUTFH + status
@@ -1835,6 +1971,7 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf args->pgbase, args->count); out: +encode_nops (nops, &hdr);return status; }
@@ -1846,16 +1983,17 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargstruct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int replen, status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_read (&xdr, args); + status =encode_read (&xdr, args, &hdr);if (status) goto out;
@@ -1868,6 +2006,7 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readarg args->pages, args->pgbase, args->count); req->rq_rcv_buf.flags |=XDRBUF_READ ; out: +encode_nops (nops, &hdr);return status; }
@@ -1877,23 +2016,25 @@ out:static int nfs4_xdr_enc_setattr (struct rpc_rqst *req,__be32 *p,struct nfs_setattrargs *args) { -struct xdr_stream xdr; -struct compound_hdr hdr = { - .nops =3 , - }; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr = { + .nops =0 , + }; +int status; +__be32 *nops; -xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); -if (status) - goto out; - status =encode_setattr (&xdr, args, args->server); -if (status) - goto out; - status =encode_getfattr (&xdr, args->bitmask); +xdr_init_encode (&xdr, &req->rq_snd_buf, p); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr); +if (status) + goto out; + status =encode_setattr (&xdr, args, args->server, &hdr); +if (status) + goto out; + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: -return status; +encode_nops (nops, &hdr); +return status; }/*
@@ -1906,21 +2047,23 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,struct xdr_stream xdr;struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int replen, status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_getattr_two (&xdr,FATTR4_WORD0_ACL ,0 ); + status =encode_getattr_two (&xdr,FATTR4_WORD0_ACL ,0 , &hdr);/* set up reply buffer: */ replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) <<2 ;xdr_inline_pages (&req->rq_rcv_buf, replen, args->acl_pages, args->acl_pgbase, args->acl_len); out: +encode_nops (nops, &hdr);return status; }
@@ -1931,21 +2074,23 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writea {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_write (&xdr, args); + status =encode_write (&xdr, args, &hdr);if (status) goto out; req->rq_snd_buf.flags |=XDRBUF_WRITE ; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1956,20 +2101,22 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_write {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_commit (&xdr, args); + status =encode_commit (&xdr, args, &hdr);if (status) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -1980,15 +2127,17 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsin {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (!status) - status =encode_fsinfo (&xdr, args->bitmask); + status =encode_fsinfo (&xdr, args->bitmask, &hdr); +encode_nops (nops, &hdr);return status; }
@@ -1999,16 +2148,19 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct n {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (!status) status =encode_getattr_one (&xdr, - args->bitmask[0 ] & nfs4_pathconf_bitmap[0 ]); + args->bitmask[0 ] & nfs4_pathconf_bitmap[0 ], + &hdr); +encode_nops (nops, &hdr);return status; }
@@ -2019,17 +2171,19 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status ==0 ) status =encode_getattr_two (&xdr, args->bitmask[0 ] & nfs4_statfs_bitmap[0 ], - args->bitmask[1 ] & nfs4_statfs_bitmap[1 ]); + args->bitmask[1 ] & nfs4_statfs_bitmap[1 ], &hdr); +encode_nops (nops, &hdr);return status; }
@@ -2040,18 +2194,20 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, const struc {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, fhandle); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, fhandle, &hdr);if (status ==0 ) status =encode_getattr_one (&xdr,FATTR4_WORD0_SUPPORTED_ATTRS |FATTR4_WORD0_LINK_SUPPORT |FATTR4_WORD0_SYMLINK_SUPPORT | -FATTR4_WORD0_ACLSUPPORT ); +FATTR4_WORD0_ACLSUPPORT , &hdr); +encode_nops (nops, &hdr);return status; }
@@ -2062,12 +2218,16 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =1 , + .nops =0 , }; +int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -return encode_renew (&xdr, clp); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_renew (&xdr, clp, &hdr); +encode_nops (nops, &hdr); +return status; }/*
@@ -2077,12 +2237,16 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4 {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =1 , + .nops =0 , }; +int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -return encode_setclientid (&xdr, sc); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_setclientid (&xdr, sc, &hdr); +encode_nops (nops, &hdr); +return status; }/*
@@ -2092,18 +2256,20 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };const u32 lease_bitmap[2 ] = {FATTR4_WORD0_LEASE_TIME ,0 };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_setclientid_confirm (&xdr, clp); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_setclientid_confirm (&xdr, clp, &hdr);if (!status) - status =encode_putrootfh (&xdr); + status =encode_putrootfh (&xdr, &hdr);if (!status) - status =encode_fsinfo (&xdr, lease_bitmap); + status =encode_fsinfo (&xdr, lease_bitmap, &hdr); +encode_nops (nops, &hdr);return status; }
@@ -2114,20 +2280,22 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struc {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fhandle); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fhandle, &hdr);if (status !=0 ) goto out; - status =encode_delegreturn (&xdr, args->stateid); + status =encode_delegreturn (&xdr, args->stateid, &hdr);if (status !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }
@@ -2138,19 +2306,20 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;int replen;int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->dir_fh)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out; -if ((status =encode_lookup (&xdr, args->name)) !=0 ) +if ((status =encode_lookup (&xdr, args->name, &hdr)) !=0 ) goto out; -if ((status =encode_fs_locations (&xdr, args->bitmask)) !=0 ) +if ((status =encode_fs_locations (&xdr, args->bitmask, &hdr)) !=0 ) goto out;/* set up reply * toplevel_status + OP_PUTFH + status
@@ -2160,6 +2329,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfsxdr_inline_pages (&req->rq_rcv_buf, replen, &args->page,0 ,PAGE_SIZE ); out: +encode_nops (nops, &hdr);return status; }
@@ -4036,20 +4206,22 @@ out:static int nfs4_xdr_enc_setacl (struct rpc_rqst *req,__be32 *p,struct nfs_setaclargs *args) { -struct xdr_stream xdr; -struct compound_hdr hdr = { - .nops =2 , - }; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr = { + .nops =0 , + }; +int status; +__be32 *nops; -xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); -if (status) - goto out; - status =encode_setacl (&xdr, args); +xdr_init_encode (&xdr, &req->rq_snd_buf, p); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr); +if (status) + goto out; + status =encode_setacl (&xdr, args, &hdr); out: -return status; +encode_nops (nops, &hdr); +return status; }/* * Decode SETACL response
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 04/85] FIXME: NFS: Increment operation number in each encode_* routine
Quoted 11 lines · Benny Halevy
From: Andy Adamson <[email protected]>
FIXME: bhalevy: is this a good opportunity for a cleanup-only patch to fix whitespacing?
Pass in the
compound_hdrand bump the number of operations in each encode_* subroutine so as to allow us to more easily construct new compound statements.Fix tabs, do not fix 'do not use assignment in if condition' warnings.
Signed-off-by Andy Adamson<[email protected]>Signed-off-by Benny Halevy <[email protected]>
review 11-14: andy will submit:
* whitespace clenaup
* status removal
* move nops ptr into compound_hdr
Quoted 1,525 lines
--- fs/nfs/nfs4xdr.c | 630 ++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 401 insertions(+), 229 deletions(-)fs/nfs/nfs4xdr.c +401
-229@@ -578,9 +578,10 @@ static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *xdr_encode_opaque (p, str, len); } -static int encode_compound_hdr (struct xdr_stream *xdr,struct compound_hdr *hdr) +static __u32 * +encode_compound_hdr (struct xdr_stream *xdr,struct compound_hdr *hdr) { -__be32 *p; +__be32 *p, *nops;dprintk ("encode_compound: tag=%.*s\n" , (int )hdr->taglen, hdr->tag);BUG_ON (hdr->taglen >NFS4_MAXTAGLEN );@@ -588,8 +589,14 @@ static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)WRITE32 (hdr->taglen);WRITEMEM (hdr->tag, hdr->taglen);WRITE32 (NFS4_MINOR_VERSION ); + nops = p;WRITE32 (hdr->nops); -return 0 ; +return nops; +} + +static inline void encode_nops (__be32 *nops,struct compound_hdr *hdr) +{ + *nops =htonl (hdr->nops); }static void encode_nfs4_verifier (struct xdr_stream *xdr,const nfs4_verifier *verf)@@ -728,18 +735,22 @@ static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const sreturn status; } -static int encode_access (struct xdr_stream *xdr,u32 access) +static int +encode_access (struct xdr_stream *xdr,u32 access,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (8 );WRITE32 (OP_ACCESS );WRITE32 (access); - + hdr->nops++; +return 0 ; } -static int encode_close (struct xdr_stream *xdr,const struct nfs_closeargs *arg) +static int +encode_close (struct xdr_stream *xdr,const struct nfs_closeargs *arg, +struct compound_hdr *hdr) {__be32 *p;@@ -747,23 +758,29 @@ static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg)WRITE32 (OP_CLOSE );WRITE32 (arg->seqid->sequence->counter);WRITEMEM (arg->stateid->data,NFS4_STATEID_SIZE ); + hdr->nops++;return 0 ; } -static int encode_commit (struct xdr_stream *xdr,const struct nfs_writeargs *args) +static int +encode_commit (struct xdr_stream *xdr,const struct nfs_writeargs *args, +struct compound_hdr *hdr) {__be32 *p; -RESERVE_SPACE (16 ); -WRITE32 (OP_COMMIT ); -WRITE64 (args->offset); -WRITE32 (args->count); +RESERVE_SPACE (16 ); +WRITE32 (OP_COMMIT ); +WRITE64 (args->offset); +WRITE32 (args->count); + hdr->nops++; -return 0 ; +return 0 ; } -static int encode_create (struct xdr_stream *xdr,const struct nfs4_create_arg *create) +static int +encode_create (struct xdr_stream *xdr,const struct nfs4_create_arg *create, +struct compound_hdr *hdr) {__be32 *p;@@ -791,11 +808,14 @@ static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *cRESERVE_SPACE (4 + create->name->len);WRITE32 (create->name->len);WRITEMEM (create->name->name, create->name->len); + hdr->nops++;return encode_attrs (xdr, create->attrs, create->server); } -static int encode_getattr_one (struct xdr_stream *xdr,uint32_t bitmap) +static int +encode_getattr_one (struct xdr_stream *xdr,uint32_t bitmap, +struct compound_hdr *hdr) {__be32 *p;@@ -803,10 +823,13 @@ static int encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap)WRITE32 (OP_GETATTR );WRITE32 (1 );WRITE32 (bitmap); + hdr->nops++;return 0 ; } -static int encode_getattr_two (struct xdr_stream *xdr,uint32_t bm0,uint32_t bm1) +static int +encode_getattr_two (struct xdr_stream *xdr,uint32_t bm0,uint32_t bm1, +struct compound_hdr *hdr) {__be32 *p;@@ -815,40 +838,51 @@ static int encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1WRITE32 (2 );WRITE32 (bm0);WRITE32 (bm1); + hdr->nops++;return 0 ; } -static int encode_getfattr (struct xdr_stream *xdr,const u32 * bitmask) +static int +encode_getfattr (struct xdr_stream *xdr,const u32 *bitmask, +struct compound_hdr *hdr) {return encode_getattr_two (xdr, bitmask[0 ] & nfs4_fattr_bitmap[0 ], - bitmask[1 ] & nfs4_fattr_bitmap[1 ]); + bitmask[1 ] & nfs4_fattr_bitmap[1 ], hdr); } -static int encode_fsinfo (struct xdr_stream *xdr,const u32 * bitmask) +static int +encode_fsinfo (struct xdr_stream *xdr,const u32 *bitmask, +struct compound_hdr *hdr) {return encode_getattr_two (xdr, bitmask[0 ] & nfs4_fsinfo_bitmap[0 ], - bitmask[1 ] & nfs4_fsinfo_bitmap[1 ]); + bitmask[1 ] & nfs4_fsinfo_bitmap[1 ], hdr); } -static int encode_fs_locations (struct xdr_stream *xdr,const u32 * bitmask) +static int +encode_fs_locations (struct xdr_stream *xdr,const u32 *bitmask, +struct compound_hdr *hdr) {return encode_getattr_two (xdr, bitmask[0 ] & nfs4_fs_locations_bitmap[0 ], - bitmask[1 ] & nfs4_fs_locations_bitmap[1 ]); + bitmask[1 ] & nfs4_fs_locations_bitmap[1 ], + hdr); } -static int encode_getfh (struct xdr_stream *xdr) +static int encode_getfh (struct xdr_stream *xdr,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (4 );WRITE32 (OP_GETFH ); + hdr->nops++;return 0 ; } -static int encode_link (struct xdr_stream *xdr,const struct qstr *name) +static int +encode_link (struct xdr_stream *xdr,const struct qstr *name, +struct compound_hdr *hdr) {__be32 *p;@@ -856,6 +890,7 @@ static int encode_link(struct xdr_stream *xdr, const struct qstr *name)WRITE32 (OP_LINK );WRITE32 (name->len);WRITEMEM (name->name, name->len); + hdr->nops++;return 0 ; }@@ -878,7 +913,9 @@ static inline uint64_t nfs4_lock_length(struct file_lock *fl)* opcode,type,reclaim,offset,length,new_lock_owner = 32 * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40 */ -static int encode_lock (struct xdr_stream *xdr,const struct nfs_lock_args *args) +static int +encode_lock (struct xdr_stream *xdr,const struct nfs_lock_args *args, +struct compound_hdr *hdr) {__be32 *p;@@ -904,11 +941,14 @@ static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args)WRITEMEM (args->lock_stateid->data,NFS4_STATEID_SIZE );WRITE32 (args->lock_seqid->sequence->counter); } + hdr->nops++;return 0 ; } -static int encode_lockt (struct xdr_stream *xdr,const struct nfs_lockt_args *args) +static int +encode_lockt (struct xdr_stream *xdr,const struct nfs_lockt_args *args, +struct compound_hdr *hdr) {__be32 *p;@@ -921,11 +961,14 @@ static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *argWRITE32 (16 );WRITEMEM ("lock id:" ,8 );WRITE64 (args->lock_owner.id); + hdr->nops++;return 0 ; } -static int encode_locku (struct xdr_stream *xdr,const struct nfs_locku_args *args) +static int +encode_locku (struct xdr_stream *xdr,const struct nfs_locku_args *args, +struct compound_hdr *hdr) {__be32 *p;@@ -936,11 +979,14 @@ static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *argWRITEMEM (args->stateid->data,NFS4_STATEID_SIZE );WRITE64 (args->fl->fl_start);WRITE64 (nfs4_lock_length (args->fl)); + hdr->nops++;return 0 ; } -static int encode_lookup (struct xdr_stream *xdr,const struct qstr *name) +static int +encode_lookup (struct xdr_stream *xdr,const struct qstr *name, +struct compound_hdr *hdr) {int len = name->len;__be32 *p;@@ -949,6 +995,7 @@ static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name)WRITE32 (OP_LOOKUP );WRITE32 (len);WRITEMEM (name->name, len); + hdr->nops++;return 0 ; }@@ -1072,7 +1119,9 @@ static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const strucencode_string (xdr, name->len, name->name); } -static int encode_open (struct xdr_stream *xdr,const struct nfs_openargs *arg) +static int +encode_open (struct xdr_stream *xdr,const struct nfs_openargs *arg, +struct compound_hdr *hdr) {encode_openhdr (xdr, arg);encode_opentype (xdr, arg);@@ -1089,10 +1138,14 @@ static int encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg)default :BUG (); } + hdr->nops++;return 0 ; } -static int encode_open_confirm (struct xdr_stream *xdr,const struct nfs_open_confirmargs *arg) +static int +encode_open_confirm (struct xdr_stream *xdr, +const struct nfs_open_confirmargs *arg, +struct compound_hdr *hdr) {__be32 *p;@@ -1100,11 +1153,14 @@ static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_conWRITE32 (OP_OPEN_CONFIRM );WRITEMEM (arg->stateid->data,NFS4_STATEID_SIZE );WRITE32 (arg->seqid->sequence->counter); + hdr->nops++;return 0 ; } -static int encode_open_downgrade (struct xdr_stream *xdr,const struct nfs_closeargs *arg) +static int +encode_open_downgrade (struct xdr_stream *xdr,const struct nfs_closeargs *arg, +struct compound_hdr *hdr) {__be32 *p;@@ -1113,11 +1169,13 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeaWRITEMEM (arg->stateid->data,NFS4_STATEID_SIZE );WRITE32 (arg->seqid->sequence->counter);encode_share_access (xdr, arg->open_flags); + hdr->nops++;return 0 ; }static int -encode_putfh (struct xdr_stream *xdr,const struct nfs_fh *fh) +encode_putfh (struct xdr_stream *xdr,const struct nfs_fh *fh, +struct compound_hdr *hdr) {int len = fh->size;__be32 *p;@@ -1126,21 +1184,24 @@ encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh)WRITE32 (OP_PUTFH );WRITE32 (len);WRITEMEM (fh->data, len); + hdr->nops++;return 0 ; } -static int encode_putrootfh (struct xdr_stream *xdr) +static int encode_putrootfh (struct xdr_stream *xdr,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (4 );WRITE32 (OP_PUTROOTFH ); + hdr->nops++;return 0 ; } -static void encode_stateid (struct xdr_stream *xdr,const struct nfs_open_context *ctx) +static void +encode_stateid (struct xdr_stream *xdr,const struct nfs_open_context *ctx) {nfs4_stateid stateid;__be32 *p;@@ -1153,7 +1214,9 @@ static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_contextWRITEMEM (zero_stateid.data,NFS4_STATEID_SIZE ); } -static int encode_read (struct xdr_stream *xdr,const struct nfs_readargs *args) +static int +encode_read (struct xdr_stream *xdr,const struct nfs_readargs *args, +struct compound_hdr *hdr) {__be32 *p;@@ -1165,11 +1228,14 @@ static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args)RESERVE_SPACE (12 );WRITE64 (args->offset);WRITE32 (args->count); + hdr->nops++;return 0 ; } -static int encode_readdir (struct xdr_stream *xdr,const struct nfs4_readdir_arg *readdir,struct rpc_rqst *req) +static int +encode_readdir (struct xdr_stream *xdr,const struct nfs4_readdir_arg *readdir, +struct rpc_rqst *req,struct compound_hdr *hdr) {uint32_t attrs[2 ] = {FATTR4_WORD0_RDATTR_ERROR |FATTR4_WORD0_FILEID ,@@ -1191,6 +1257,7 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg attrs[1 ] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID ;WRITE32 (attrs[0 ] & readdir->bitmask[0 ]);WRITE32 (attrs[1 ] & readdir->bitmask[1 ]); + hdr->nops++; dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n", __func__, (unsigned long long)readdir->cookie,@@ -1202,17 +1269,22 @@ static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_argreturn 0 ; } -static int encode_readlink (struct xdr_stream *xdr,const struct nfs4_readlink *readlink,struct rpc_rqst *req) +static int +encode_readlink (struct xdr_stream *xdr,const struct nfs4_readlink *readlink, +struct rpc_rqst *req,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (4 );WRITE32 (OP_READLINK ); + hdr->nops++;return 0 ; } -static int encode_remove (struct xdr_stream *xdr,const struct qstr *name) +static int +encode_remove (struct xdr_stream *xdr,const struct qstr *name, +struct compound_hdr *hdr) {__be32 *p;@@ -1220,11 +1292,14 @@ static int encode_remove(struct xdr_stream *xdr, const struct qstr *name)WRITE32 (OP_REMOVE );WRITE32 (name->len);WRITEMEM (name->name, name->len); + hdr->nops++;return 0 ; } -static int encode_rename (struct xdr_stream *xdr,const struct qstr *oldname,const struct qstr *newname) +static int +encode_rename (struct xdr_stream *xdr,const struct qstr *oldname, +const struct qstr *newname,struct compound_hdr *hdr) {__be32 *p;@@ -1236,34 +1311,40 @@ static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, conRESERVE_SPACE (4 + newname->len);WRITE32 (newname->len);WRITEMEM (newname->name, newname->len); + hdr->nops++;return 0 ; } -static int encode_renew (struct xdr_stream *xdr,const struct nfs_client *client_stateid) +static int +encode_renew (struct xdr_stream *xdr,const struct nfs_client *client_stateid, +struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (12 );WRITE32 (OP_RENEW );WRITE64 (client_stateid->cl_clientid); + hdr->nops++;return 0 ; }static int -encode_restorefh (struct xdr_stream *xdr) +encode_restorefh (struct xdr_stream *xdr,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (4 );WRITE32 (OP_RESTOREFH ); + hdr->nops++;return 0 ; }static int -encode_setacl (struct xdr_stream *xdr,struct nfs_setaclargs *arg) +encode_setacl (struct xdr_stream *xdr,struct nfs_setaclargs *arg, +struct compound_hdr *hdr) {__be32 *p;@@ -1278,21 +1359,25 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)RESERVE_SPACE (4 );WRITE32 (arg->acl_len);xdr_write_pages (xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); + hdr->nops++;return 0 ; }static int -encode_savefh (struct xdr_stream *xdr) +encode_savefh (struct xdr_stream *xdr,struct compound_hdr *hdr) {__be32 *p;RESERVE_SPACE (4 );WRITE32 (OP_SAVEFH ); + hdr->nops++;return 0 ; } -static int encode_setattr (struct xdr_stream *xdr,const struct nfs_setattrargs *arg,const struct nfs_server *server) +static int +encode_setattr (struct xdr_stream *xdr,const struct nfs_setattrargs *arg, +const struct nfs_server *server,struct compound_hdr *hdr) {int status;__be32 *p;@@ -1300,6 +1385,7 @@ static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *RESERVE_SPACE (4 +NFS4_STATEID_SIZE );WRITE32 (OP_SETATTR );WRITEMEM (arg->stateid.data,NFS4_STATEID_SIZE ); + hdr->nops++;if ((status =encode_attrs (xdr, arg->iap, server)))return status;@@ -1307,7 +1393,10 @@ static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *return 0 ; } -static int encode_setclientid (struct xdr_stream *xdr,const struct nfs4_setclientid *setclientid) +static int +encode_setclientid (struct xdr_stream *xdr, +const struct nfs4_setclientid *setclientid, +struct compound_hdr *hdr) {__be32 *p;@@ -1322,11 +1411,15 @@ static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclienencode_string (xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr);RESERVE_SPACE (4 );WRITE32 (setclientid->sc_cb_ident); + hdr->nops++;return 0 ; } -static int encode_setclientid_confirm (struct xdr_stream *xdr,const struct nfs_client *client_state) +static int +encode_setclientid_confirm (struct xdr_stream *xdr, +const struct nfs_client *client_state, +struct compound_hdr *hdr) {__be32 *p;@@ -1334,11 +1427,14 @@ static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_cWRITE32 (OP_SETCLIENTID_CONFIRM );WRITE64 (client_state->cl_clientid);WRITEMEM (client_state->cl_confirm.data,NFS4_VERIFIER_SIZE ); + hdr->nops++;return 0 ; } -static int encode_write (struct xdr_stream *xdr,const struct nfs_writeargs *args) +static int +encode_write (struct xdr_stream *xdr,const struct nfs_writeargs *args, +struct compound_hdr *hdr) {__be32 *p;@@ -1353,11 +1449,14 @@ static int encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *argsWRITE32 (args->count);xdr_write_pages (xdr, args->pages, args->pgbase, args->count); + hdr->nops++;return 0 ; } -static int encode_delegreturn (struct xdr_stream *xdr,const nfs4_stateid *stateid) +static int +encode_delegreturn (struct xdr_stream *xdr,const nfs4_stateid *stateid, +struct compound_hdr *hdr) {__be32 *p;@@ -1365,6 +1464,7 @@ static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateiWRITE32 (OP_DELEGRETURN );WRITEMEM (stateid->data,NFS4_STATEID_SIZE ); + hdr->nops++;return 0 ; }@@ -1379,20 +1479,22 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status !=0 ) goto out; - status =encode_access (&xdr, args->access); + status =encode_access (&xdr, args->access, &hdr);if (status !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1403,20 +1505,22 @@ static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =4 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->dir_fh)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out; -if ((status =encode_lookup (&xdr, args->name)) !=0 ) +if ((status =encode_lookup (&xdr, args->name, &hdr)) !=0 ) goto out; -if ((status =encode_getfh (&xdr)) !=0 ) +if ((status =encode_getfh (&xdr, &hdr)) !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1427,17 +1531,19 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struc {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putrootfh (&xdr)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putrootfh (&xdr, &hdr)) !=0 ) goto out; -if ((status =encode_getfh (&xdr)) ==0 ) - status =encode_getfattr (&xdr, args->bitmask); +if ((status =encode_getfh (&xdr, &hdr)) ==0 ) + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1448,18 +1554,20 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->fh)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->fh, &hdr)) !=0 ) goto out; -if ((status =encode_remove (&xdr, &args->name)) !=0 ) +if ((status =encode_remove (&xdr, &args->name, &hdr)) !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1470,26 +1578,29 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =7 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->old_dir)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->old_dir, &hdr)) !=0 ) goto out; -if ((status =encode_savefh (&xdr)) !=0 ) +if ((status =encode_savefh (&xdr, &hdr)) !=0 ) goto out; -if ((status =encode_putfh (&xdr, args->new_dir)) !=0 ) +if ((status =encode_putfh (&xdr, args->new_dir, &hdr)) !=0 ) goto out; -if ((status =encode_rename (&xdr, args->old_name, args->new_name)) !=0 ) +if ((status =encode_rename (&xdr, args->old_name, args->new_name, + &hdr)) !=0 ) goto out; -if ((status =encode_getfattr (&xdr, args->bitmask)) !=0 ) +if ((status =encode_getfattr (&xdr, args->bitmask, &hdr)) !=0 ) goto out; -if ((status =encode_restorefh (&xdr)) !=0 ) +if ((status =encode_restorefh (&xdr, &hdr)) !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1500,26 +1611,28 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_ {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =7 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->fh)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->fh, &hdr)) !=0 ) goto out; -if ((status =encode_savefh (&xdr)) !=0 ) +if ((status =encode_savefh (&xdr, &hdr)) !=0 ) goto out; -if ((status =encode_putfh (&xdr, args->dir_fh)) !=0 ) +if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out; -if ((status =encode_link (&xdr, args->name)) !=0 ) +if ((status =encode_link (&xdr, args->name, &hdr)) !=0 ) goto out; -if ((status =encode_getfattr (&xdr, args->bitmask)) !=0 ) +if ((status =encode_getfattr (&xdr, args->bitmask, &hdr)) !=0 ) goto out; -if ((status =encode_restorefh (&xdr)) !=0 ) +if ((status =encode_restorefh (&xdr, &hdr)) !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1530,26 +1643,28 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =7 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->dir_fh)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out; -if ((status =encode_savefh (&xdr)) !=0 ) +if ((status =encode_savefh (&xdr, &hdr)) !=0 ) goto out; -if ((status =encode_create (&xdr, args)) !=0 ) +if ((status =encode_create (&xdr, args, &hdr)) !=0 ) goto out; -if ((status =encode_getfh (&xdr)) !=0 ) +if ((status =encode_getfh (&xdr, &hdr)) !=0 ) goto out; -if ((status =encode_getfattr (&xdr, args->bitmask)) !=0 ) +if ((status =encode_getfattr (&xdr, args->bitmask, &hdr)) !=0 ) goto out; -if ((status =encode_restorefh (&xdr)) !=0 ) +if ((status =encode_restorefh (&xdr, &hdr)) !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1568,14 +1683,16 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->fh)) ==0 ) - status =encode_getfattr (&xdr, args->bitmask); + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->fh, &hdr)) ==0 ) + status =encode_getfattr (&xdr, args->bitmask, &hdr); +encode_nops (nops, &hdr);return status; }@@ -1586,20 +1703,22 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closea {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_close (&xdr, args); + status =encode_close (&xdr, args, &hdr);if (status !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1610,32 +1729,34 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openarg {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =7 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_savefh (&xdr); + status =encode_savefh (&xdr, &hdr);if (status) goto out; - status =encode_open (&xdr, args); + status =encode_open (&xdr, args, &hdr);if (status) goto out; - status =encode_getfh (&xdr); + status =encode_getfh (&xdr, &hdr);if (status) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr);if (status) goto out; - status =encode_restorefh (&xdr); + status =encode_restorefh (&xdr, &hdr);if (status) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1646,17 +1767,19 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_open_confirm (&xdr, args); + status =encode_open_confirm (&xdr, args, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1667,20 +1790,22 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_ {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_open (&xdr, args); + status =encode_open (&xdr, args, &hdr);if (status) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1691,20 +1816,22 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct n {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_open_downgrade (&xdr, args); + status =encode_open_downgrade (&xdr, args, &hdr);if (status !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1715,17 +1842,19 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_ar {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_lock (&xdr, args); + status =encode_lock (&xdr, args, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1736,17 +1865,19 @@ static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_ {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_lockt (&xdr, args); + status =encode_lockt (&xdr, args, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1757,17 +1888,19 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_ {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_locku (&xdr, args); + status =encode_locku (&xdr, args, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1778,18 +1911,19 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;unsigned int replen;int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_readlink (&xdr, args, req); + status =encode_readlink (&xdr, args, req, &hdr);/* set up reply kvec * toplevel_status + taglen + rescount + OP_PUTFH + status @@ -1800,6 +1934,7 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n args->pgbase, args->pglen); out: +encode_nops (nops, &hdr);return status; }@@ -1810,18 +1945,19 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;int replen;int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_readdir (&xdr, args, req); + status =encode_readdir (&xdr, args, req, &hdr);/* set up reply kvec * toplevel_status + taglen + rescount + OP_PUTFH + status @@ -1835,6 +1971,7 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf args->pgbase, args->count); out: +encode_nops (nops, &hdr);return status; }@@ -1846,16 +1983,17 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargstruct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int replen, status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_read (&xdr, args); + status =encode_read (&xdr, args, &hdr);if (status) goto out;@@ -1868,6 +2006,7 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readarg args->pages, args->pgbase, args->count); req->rq_rcv_buf.flags |=XDRBUF_READ ; out: +encode_nops (nops, &hdr);return status; }@@ -1877,23 +2016,25 @@ out:static int nfs4_xdr_enc_setattr (struct rpc_rqst *req,__be32 *p,struct nfs_setattrargs *args) { -struct xdr_stream xdr; -struct compound_hdr hdr = { - .nops =3 , - }; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr = { + .nops =0 , + }; +int status; +__be32 *nops; -xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); -if (status) - goto out; - status =encode_setattr (&xdr, args, args->server); -if (status) - goto out; - status =encode_getfattr (&xdr, args->bitmask); +xdr_init_encode (&xdr, &req->rq_snd_buf, p); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr); +if (status) + goto out; + status =encode_setattr (&xdr, args, args->server, &hdr); +if (status) + goto out; + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: -return status; +encode_nops (nops, &hdr); +return status; }/* @@ -1906,21 +2047,23 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,struct xdr_stream xdr;struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int replen, status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_getattr_two (&xdr,FATTR4_WORD0_ACL ,0 ); + status =encode_getattr_two (&xdr,FATTR4_WORD0_ACL ,0 , &hdr);/* set up reply buffer: */ replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) <<2 ;xdr_inline_pages (&req->rq_rcv_buf, replen, args->acl_pages, args->acl_pgbase, args->acl_len); out: +encode_nops (nops, &hdr);return status; }@@ -1931,21 +2074,23 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writea {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_write (&xdr, args); + status =encode_write (&xdr, args, &hdr);if (status) goto out; req->rq_snd_buf.flags |=XDRBUF_WRITE ; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1956,20 +2101,22 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_write {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; - status =encode_commit (&xdr, args); + status =encode_commit (&xdr, args, &hdr);if (status) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -1980,15 +2127,17 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsin {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (!status) - status =encode_fsinfo (&xdr, args->bitmask); + status =encode_fsinfo (&xdr, args->bitmask, &hdr); +encode_nops (nops, &hdr);return status; }@@ -1999,16 +2148,19 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct n {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (!status) status =encode_getattr_one (&xdr, - args->bitmask[0 ] & nfs4_pathconf_bitmap[0 ]); + args->bitmask[0 ] & nfs4_pathconf_bitmap[0 ], + &hdr); +encode_nops (nops, &hdr);return status; }@@ -2019,17 +2171,19 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr);if (status ==0 ) status =encode_getattr_two (&xdr, args->bitmask[0 ] & nfs4_statfs_bitmap[0 ], - args->bitmask[1 ] & nfs4_statfs_bitmap[1 ]); + args->bitmask[1 ] & nfs4_statfs_bitmap[1 ], &hdr); +encode_nops (nops, &hdr);return status; }@@ -2040,18 +2194,20 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, const struc {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =2 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, fhandle); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, fhandle, &hdr);if (status ==0 ) status =encode_getattr_one (&xdr,FATTR4_WORD0_SUPPORTED_ATTRS |FATTR4_WORD0_LINK_SUPPORT |FATTR4_WORD0_SYMLINK_SUPPORT | -FATTR4_WORD0_ACLSUPPORT ); +FATTR4_WORD0_ACLSUPPORT , &hdr); +encode_nops (nops, &hdr);return status; }@@ -2062,12 +2218,16 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =1 , + .nops =0 , }; +int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -return encode_renew (&xdr, clp); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_renew (&xdr, clp, &hdr); +encode_nops (nops, &hdr); +return status; }/* @@ -2077,12 +2237,16 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4 {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =1 , + .nops =0 , }; +int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -return encode_setclientid (&xdr, sc); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_setclientid (&xdr, sc, &hdr); +encode_nops (nops, &hdr); +return status; }/* @@ -2092,18 +2256,20 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };const u32 lease_bitmap[2 ] = {FATTR4_WORD0_LEASE_TIME ,0 };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_setclientid_confirm (&xdr, clp); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_setclientid_confirm (&xdr, clp, &hdr);if (!status) - status =encode_putrootfh (&xdr); + status =encode_putrootfh (&xdr, &hdr);if (!status) - status =encode_fsinfo (&xdr, lease_bitmap); + status =encode_fsinfo (&xdr, lease_bitmap, &hdr); +encode_nops (nops, &hdr);return status; }@@ -2114,20 +2280,22 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struc {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fhandle); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fhandle, &hdr);if (status !=0 ) goto out; - status =encode_delegreturn (&xdr, args->stateid); + status =encode_delegreturn (&xdr, args->stateid, &hdr);if (status !=0 ) goto out; - status =encode_getfattr (&xdr, args->bitmask); + status =encode_getfattr (&xdr, args->bitmask, &hdr); out: +encode_nops (nops, &hdr);return status; }@@ -2138,19 +2306,20 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =3 , + .nops =0 , };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;int replen;int status; +__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); -if ((status =encode_putfh (&xdr, args->dir_fh)) !=0 ) + nops =encode_compound_hdr (&xdr, &hdr); +if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out; -if ((status =encode_lookup (&xdr, args->name)) !=0 ) +if ((status =encode_lookup (&xdr, args->name, &hdr)) !=0 ) goto out; -if ((status =encode_fs_locations (&xdr, args->bitmask)) !=0 ) +if ((status =encode_fs_locations (&xdr, args->bitmask, &hdr)) !=0 ) goto out;/* set up reply * toplevel_status + OP_PUTFH + status @@ -2160,6 +2329,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfsxdr_inline_pages (&req->rq_rcv_buf, replen, &args->page,0 ,PAGE_SIZE ); out: +encode_nops (nops, &hdr);return status; }@@ -4036,20 +4206,22 @@ out:static int nfs4_xdr_enc_setacl (struct rpc_rqst *req,__be32 *p,struct nfs_setaclargs *args) { -struct xdr_stream xdr; -struct compound_hdr hdr = { - .nops =2 , - }; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr = { + .nops =0 , + }; +int status; +__be32 *nops; -xdr_init_encode (&xdr, &req->rq_snd_buf, p); -encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, args->fh); -if (status) - goto out; - status =encode_setacl (&xdr, args); +xdr_init_encode (&xdr, &req->rq_snd_buf, p); + nops =encode_compound_hdr (&xdr, &hdr); + status =encode_putfh (&xdr, args->fh, &hdr); +if (status) + goto out; + status =encode_setacl (&xdr, args, &hdr); out: -return status; +encode_nops (nops, &hdr); +return status; }/* * Decode SETACL response Signature · 1 line
1.6.0.1
RFC 5/85 nfs41: Add Kconfig symbols for NFSv4.1
In reply to Benny HalevyFrom: Ricardo Labiaga <[email protected]>
Added CONFIG_NFS_V4_1 and made it depend upon CONFIG_NFS_V4 and EXPERIMENTAL.
--- fs/Kconfig | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)
fs/Kconfig +9 -0
@@ -1216,6 +1216,15 @@ config NFS_V4 If unsure, say N. +config NFS_V4_1 + bool "NFS client support for NFSv4.1 (EXPERIMENTAL)" + depends on NFS_V4 && EXPERIMENTAL + help + This option enables support for minor version 1 of the NFSv4 protocol + (draft-ietf-nfsv4-minorversion1) in the kernel's NFS client. + + If unsure, say N. + config ROOT_NFS bool "Root file system on NFS" depends on NFS_FS=y && IP_PNP
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 05/85] nfs41: Add Kconfig symbols for NFSv4.1
Quoted 14 lines · Benny Halevy
From: Ricardo Labiaga <[email protected]>
Added
CONFIG_NFS_V4_1and made it depend uponCONFIG_NFS_V4and EXPERIMENTAL.Signed-off-by Benny Halevy <[email protected]>--- fs/Kconfig | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)fs/Kconfig +0
-0
fs/Kconfig config NFS_V4 · line 1220
Quoted 5 lines
fs/Kconfig +2
-0@@ -1216,6 +1216,15 @@ config NFS_V4 If unsure, say N. +config NFS_V4_1 + bool "NFS client support for NFSv4.1 (EXPERIMENTAL)"
review 11-14: s/EXPERIMENTAL/DEVELOPER ONLY/
fs/Kconfig config NFS_V4 · line 1225
Quoted 5 lines
fs/Kconfig +5
-0+ depends on NFS_V4 && EXPERIMENTAL + help + This option enables support for minor version 1 of the NFSv4 protocol + (draft-ietf-nfsv4-minorversion1) in the kernel's NFS client. +
Unless you're an NFS developer, say N.
Quoted 5 lines
fs/Kconfig +2
-0+ If unsure, say N. + config ROOT_NFS bool "Root file system on NFS" depends on NFS_FS=y && IP_PNP
RFC 6/85 nfs41: common protocol definitions
In reply to Benny Halevynfs41: define all NFSv4.1 operation and error code constants.
Note that some of the definitions are used by both the nfs41 client and the server code (hence enclosed in defined(CONFIG_NFSD_V4_1) || defined(CONFIG_NFS_V4_1)).
--- include/linux/nfs.h | 19 ++++++++- include/linux/nfs4.h | 112 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 3 deletions(-)
include/linux/nfs.h +18 -1
@@ -109,7 +109,24 @@NFSERR_FILE_OPEN =10046 ,/* v4 */ NFSERR_ADMIN_REVOKED =10047 ,/* v4 */ NFSERR_CB_PATH_DOWN =10048 ,/* v4 */ - NFSERR_REPLAY_ME = 10049 /* v4 */ +NFSERR_BADIOMODE =10049 ,/* v4.1 */ +NFSERR_BADLAYOUT =10050 ,/* v4.1 */ +NFSERR_BAD_SESSION_DIGEST =10051 ,/* v4.1 */ +NFSERR_BADSESSION =10052 ,/* v4.1 */ +NFSERR_BADSLOT =10053 ,/* v4.1 */ +NFSERR_COMPLETE_ALREADY =10054 ,/* v4.1 */ +NFSERR_CONN_NOT_BOUND_TO_SESSION =10055 ,/* v4.1 */ +NFSERR_DELEG_ALREADY_WANTED =10056 ,/* v4.1 */ +NFSERR_DIRDELEG_UNAVAIL =10057 ,/* v4.1 */ +NFSERR_LAYOUTTRYLATER =10058 ,/* v4.1 */ +NFSERR_LAYOUTUNAVAILABLE =10059 ,/* v4.1 */ +NFSERR_NOMATCHING_LAYOUT =10060 ,/* v4.1 */ +NFSERR_RECALLCONFLICT =10061 ,/* v4.1 */ +NFSERR_UNKNOWN_LAYOUTTYPE =10062 ,/* v4.1 */ +NFSERR_SEQ_MISORDERED =10063 ,/* v4.1 */ +NFSERR_SEQUENCE_POS =10064 ,/* v4.1 */ + + NFSERR_REPLAY_ME = 11001, /* linux internal */ };/* NFSv2 file types - beware, these are not the same in NFSv3 */
include/linux/nfs4.h +110 -2
161 lines not on this page · raw message
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 06/85] nfs41: common protocol definitions
Quoted 29 lines · Benny Halevy
nfs41: define all NFSv4.1 operation and error code constants.
Note that some of the definitions are used by both the nfs41 client and the server code (hence enclosed in
defined(CONFIG_NFSD_V4_1)||defined(CONFIG_NFS_V4_1)).Signed-off-by Andy Adamson<[email protected]>Signed-off-by Benny Halevy <[email protected]>include/linux/nfs.h | 19 ++++++++- include/linux/nfs4.h | 112 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 3 deletions(-)include/linux/nfs.h +8
-1@@ -109,7 +109,24 @@NFSERR_FILE_OPEN =10046 ,/* v4 */ NFSERR_ADMIN_REVOKED =10047 ,/* v4 */ NFSERR_CB_PATH_DOWN =10048 ,/* v4 */ -NFSERR_REPLAY_ME =10049 /* v4 */ +NFSERR_BADIOMODE =10049 ,/* v4.1 */ +NFSERR_BADLAYOUT =10050 ,/* v4.1 */ +NFSERR_BAD_SESSION_DIGEST =10051 ,/* v4.1 */ +NFSERR_BADSESSION =10052 ,/* v4.1 */ +NFSERR_BADSLOT =10053 ,/* v4.1 */ +NFSERR_COMPLETE_ALREADY =10054 ,/* v4.1 */ +NFSERR_CONN_NOT_BOUND_TO_SESSION =10055 ,/* v4.1 */ + NFSERR_DELEG_ALREADY_WANTED = 10056, /* v4.1 */
include/linux/nfs.h line 129
Quoted 10 lines
include/linux/nfs.h +10
-0+NFSERR_DIRDELEG_UNAVAIL =10057 ,/* v4.1 */ +NFSERR_LAYOUTTRYLATER =10058 ,/* v4.1 */ +NFSERR_LAYOUTUNAVAILABLE =10059 ,/* v4.1 */ +NFSERR_NOMATCHING_LAYOUT =10060 ,/* v4.1 */ +NFSERR_RECALLCONFLICT =10061 ,/* v4.1 */ +NFSERR_UNKNOWN_LAYOUTTYPE =10062 ,/* v4.1 */ +NFSERR_SEQ_MISORDERED =10063 ,/* v4.1 */ +NFSERR_SEQUENCE_POS =10064 ,/* v4.1 */ + + NFSERR_REPLAY_ME = 11001, /* linux internal */
review 11-14: Trond wants to get rid of the NFSERR_ consts and use NFS4ERR (enum nfs_stat) this will also clean up linux/nfs.h so that nfs4 defs will be in nfs4.h
Quoted 16 lines
include/linux/nfs.h +0
-0};/* NFSv2 file types - beware, these are not the same in NFSv3 */ include/linux/nfs4.h +1
-0@@ -21,6 +21,7 @@#define NFS4_FHSIZE 128#define NFS4_MAXPATHLEN PATH_MAX#define NFS4_MAXNAMLEN NAME_MAX +#define NFS4_MAX_SESSIONID_LEN 16#define NFS4_ACCESS_READ 0x0001#define NFS4_ACCESS_LOOKUP 0x0002
include/linux/nfs4.h line 42
Quoted 4 lines
include/linux/nfs4.h +1
-0@@ -38,6 +39,7 @@#define NFS4_OPEN_RESULT_CONFIRM 0x0002#define NFS4_OPEN_RESULT_LOCKTYPE_POSIX 0x0004 +#define NFS4_SHARE_DENY_MASK 0x000F
review 11-14: NFS4_SHARE_ACCESS_MASK
include/linux/nfs4.h line 50
Quoted 8 lines
include/linux/nfs4.h +1
-0#define NFS4_SHARE_ACCESS_READ 0x0001#define NFS4_SHARE_ACCESS_WRITE 0x0002#define NFS4_SHARE_ACCESS_BOTH 0x0003@@ -45,6 +47,20 @@#define NFS4_SHARE_DENY_WRITE 0x0002#define NFS4_SHARE_DENY_BOTH 0x0003 +#if defined(CONFIG_NFSD_V4_1 ) || defined(CONFIG_NFS_V4_1 )
review 11-14: get rid of #ifdef in the definition
Quoted 18 lines
include/linux/nfs4.h +13
-0+#define NFS4_SHARE_WANT_MASK 0xFF00 +#define NFS4_SHARE_WANT_NO_PREFERENCE 0x0000 +#define NFS4_SHARE_WANT_READ_DELEG 0x0100 +#define NFS4_SHARE_WANT_WRITE_DELEG 0x0200 +#define NFS4_SHARE_WANT_ANY_DELEG 0x0300 +#define NFS4_SHARE_WANT_NO_DELEG 0x0400 +#define NFS4_SHARE_WANT_CANCEL 0x0500 + +#define NFS4_SHARE_WHEN_MASK 0xF0000 +#define NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL 0x10000 +#define NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED 0x20000 +#endif /* CONFIG_NFSD_V4_1 || CONFIG_NFS_V4_1 */ +#define NFS4_SET_TO_SERVER_TIME 0#define NFS4_SET_TO_CLIENT_TIME 1@@ -88,6 +104,15 @@#define NFS4_ACE_GENERIC_EXECUTE 0x001200A0
include/linux/nfs4.h line 114
Quoted 10 lines
include/linux/nfs4.h +8
-0#define NFS4_ACE_MASK_ALL 0x001F01FF +#define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001 +#define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002 +#define EXCHGID4_FLAG_USE_NON_PNFS 0x00010000 +#define EXCHGID4_FLAG_USE_PNFS_MDS 0x00020000 +#define EXCHGID4_FLAG_USE_PNFS_DS 0x00040000 +#define EXCHGID4_INVAL_FLAG_MASK 0x77707774 + +#define NFS4_LENGTH_EOF (~(u64)0)
review 11-14: s/NFS4_LENGTH_EOF/NFS4_MAX_UINT64/
include/linux/nfs4.h enum nfs_opnum4 { · line 180
Quoted 9 lines
include/linux/nfs4.h +2
-0+enum nfs4_acl_whotype {NFS4_ACL_WHO_NAMED =0 ,NFS4_ACL_WHO_OWNER ,@@ -152,6 +177,27 @@ enum nfs_opnum4 {OP_VERIFY =37 ,OP_WRITE =38 ,OP_RELEASE_LOCKOWNER =39 , +#if defined(CONFIG_NFSD_V4_1) || defined(CONFIG_NFS_V4_1)
review 11-14: get rid of #ifdef
Quoted 24 lines
include/linux/nfs4.h +20
-0+OP_BACKCHANNEL_CTL =40 , +OP_BIND_CONN_TO_SESSION =41 , +OP_EXCHANGE_ID =42 , +OP_CREATE_SESSION =43 , +OP_DESTROY_SESSION =44 , +OP_FREE_STATEID =45 , +OP_GET_DIR_DELEGATION =46 , +OP_GETDEVICEINFO =47 , +OP_GETDEVICELIST =48 , +OP_LAYOUTCOMMIT =49 , +OP_LAYOUTGET =50 , +OP_LAYOUTRETURN =51 , +OP_SECINFO_NO_NAME =52 , +OP_SEQUENCE =53 , +OP_SET_SSV =54 , +OP_TEST_STATEID =55 , +OP_WANT_DELEGATION =56 , +OP_DESTROY_CLIENTID =57 , +OP_RECLAIM_COMPLETE =58 , +#endif /* defined(CONFIG_NFSD_V4_1) || defined(CONFIG_NFS_V4_1) */ OP_ILLEGAL = 10044, };
include/linux/nfs4.h enum nfsstat4 { · line 278
Quoted 6 lines
include/linux/nfs4.h +2
-1@@ -228,7 +274,47 @@ enum nfsstat4 {NFS4ERR_DEADLOCK =10045 ,NFS4ERR_FILE_OPEN =10046 ,NFS4ERR_ADMIN_REVOKED =10047 , -NFS4ERR_CB_PATH_DOWN =10048 +NFS4ERR_CB_PATH_DOWN =10048 , +#if defined(CONFIG_NFS_V4_1)
review 11-14: ditto
Quoted 43 lines
include/linux/nfs4.h +39
-0+NFS4ERR_BADIOMODE =10049 , +NFS4ERR_BADLAYOUT =10050 , +NFS4ERR_BAD_SESSION_DIGEST =10051 , +NFS4ERR_BADSESSION =10052 , +NFS4ERR_BADSLOT =10053 , +NFS4ERR_COMPLETE_ALREADY =10054 , +NFS4ERR_CONN_NOT_BOUND_TO_SESSION =10055 , +NFS4ERR_DELEG_ALREADY_WANTED =10056 , +NFS4ERR_BACK_CHAN_BUSY =10057 ,/* backchan reqs outstanding */ +NFS4ERR_LAYOUTTRYLATER =10058 , +NFS4ERR_LAYOUTUNAVAILABLE =10059 , +NFS4ERR_NOMATCHING_LAYOUT =10060 , +NFS4ERR_RECALLCONFLICT =10061 , +NFS4ERR_UNKNOWN_LAYOUTTYPE =10062 , +NFS4ERR_SEQ_MISORDERED =10063 ,/* unexpected seq.id in req */ +NFS4ERR_SEQUENCE_POS =10064 ,/* [CB_]SEQ. op not 1st op */ +NFS4ERR_REQ_TOO_BIG =10065 ,/* request too big */ +NFS4ERR_REP_TOO_BIG =10066 ,/* reply too big */ +NFS4ERR_REP_TOO_BIG_TO_CACHE =10067 ,/* rep. not all cached */ +NFS4ERR_RETRY_UNCACHED_REP =10068 ,/* retry & rep. uncached */ +NFS4ERR_UNSAFE_COMPOUND =10069 ,/* retry/recovery too hard */ +NFS4ERR_TOO_MANY_OPS =10070 ,/* too many ops in [CB_]COMP */ +NFS4ERR_OP_NOT_IN_SESSION =10071 ,/* op needs [CB_]SEQ. op */ +NFS4ERR_HASH_ALG_UNSUPP =10072 ,/* hash alg. not supp. */ +NFS4ERR_CONN_BINDING_NOT_ENFORCED =10073 ,/* SET_SSV not allowed */ +NFS4ERR_CLIENTID_BUSY =10074 ,/* clientid has state */ +NFS4ERR_PNFS_IO_HOLE =10075 ,/* IO to _SPARSE file hole */ +NFS4ERR_SEQ_FALSE_RETRY =10076 ,/* retry not origional */ +NFS4ERR_BAD_HIGH_SLOT =10077 ,/* sequence arg bad */ +NFS4ERR_DEADSESSION =10078 ,/* persistent session dead */ +NFS4ERR_ENCR_ALG_UNSUPP =10079 ,/* SSV alg mismatch */ +NFS4ERR_PNFS_NO_LAYOUT =10080 ,/* direct I/O with no layout */ +NFS4ERR_NOT_ONLY_OP =10081 ,/* bad compound */ +NFS4ERR_WRONG_CRED =10082 ,/* permissions:state change */ +NFS4ERR_WRONG_TYPE =10083 ,/* current operation mismatch */ +NFS4ERR_DIRDELEG_UNAVAIL =10084 ,/* no directory delegation */ +NFS4ERR_REJECT_DELEG =10085 ,/* on callback */ + NFS4ERR_RETURNCONFLICT = 10086, /* outstanding layoutreturn */ +#endif /* CONFIG_NFS_V4_1 */ };/*
include/linux/nfs4.h enum lock_type4 { · line 437
Quoted 5 lines
include/linux/nfs4.h +1
-1@@ -348,7 +434,7 @@ enum lock_type4 {#define NFSPROC4_NULL 0#define NFSPROC4_COMPOUND 1 -#define NFS4_MINOR_VERSION 0 +#define NFS4_MINOR_VERSION 1
review 11-14: get rid of this, it's unused.
include/linux/nfs4.h enum { · line 478
Quoted 8 lines
include/linux/nfs4.h +1
-0#define NFS4_DEBUG 1/* Index of predefined Linux client operations */ @@ -389,7 +475,29 @@ enum {NFSPROC4_CLNT_GETACL ,NFSPROC4_CLNT_SETACL ,NFSPROC4_CLNT_FS_LOCATIONS , +#if defined(CONFIG_NFS_V4_1)
review 11-14: get rid of #ifdef
include/linux/nfs4.h enum { · line 487
Quoted 9 lines
include/linux/nfs4.h +9
-0+NFSPROC4_CLNT_EXCHANGE_ID , +NFSPROC4_CLNT_CREATE_SESSION , +NFSPROC4_CLNT_DESTROY_SESSION , +NFSPROC4_CLNT_SEQUENCE , + NFSPROC4_CLNT_GET_LEASE_TIME, +#endif /* CONFIG_NFSD_V4_1 */ +}; + +#if defined(CONFIG_NFSD_V4_1 ) || defined(CONFIG_NFS_V4_1 )
get rid of the #ifdef
include/linux/nfs4.h enum { · line 488
Quoted 1 line
include/linux/nfs4.h +1
-0+typedef unsigned char nfs41_sessionid [16 ];
review 11-14: change to struct nfs4_sessionid { unsigned char data[16]; }; no typedef.
change server name to nfsd4_private_sessionid
Quoted 15 lines
include/linux/nfs4.h +11
-0+ +/* Create Session Flags */ +#define SESSION4_PERSIST 0x001 +#define SESSION4_BACK_CHAN 0x002 +#define SESSION4_RDMA 0x004 + +enum state_protect_how4 { +SP4_NONE =0 , +SP4_MACH_CRED =1 , +SP4_SSV =2 }; +#endif /* defined(CONFIG_NFSD_V4_1) || defined(CONFIG_NFS_V4_1) */ #endif #endif
RFC 7/85 nfs41: define NFS4_MAX_MINOR_VERSION based on CONFIG_NFS_V4_1
In reply to Benny HalevyFrom: Mike Sager <[email protected]>
If 4.1 isn't supported, NFS4_MAX_MINOR_VERSION will be 0.
--- include/linux/nfs4.h | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
include/linux/nfs4.h +7 -0
@@ -435,6 +435,13 @@ enum lock_type4 {#define NFSPROC4_NULL 0#define NFSPROC4_COMPOUND 1#define NFS4_MINOR_VERSION 1 + +#if defined(CONFIG_NFS_V4_1 ) +#define NFS4_MAX_MINOR_VERSION 1 +#else +#define NFS4_MAX_MINOR_VERSION 0 +#endif /* CONFIG_NFS_V4_1 */ +#define NFS4_DEBUG 1/* Index of predefined Linux client operations */
Signature · 1 line
1.6.0.2
RFC 8/85 nfs41: client xdr definitions
In reply to Benny HalevyDefine stubs for sequence args and res data structures and embed them in all other nfs4 and nfs41 xdr types. They are needed for sending any op in a nfs41 compound rpc.
--- include/linux/nfs_xdr.h | 118 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 118 insertions(+), 0 deletions(-)
include/linux/nfs_xdr.h +118 -0
@@ -113,6 +113,43 @@ struct nfs4_change_info { };struct nfs_seqid ; + +/* Opaque session ID */ +struct sessionid4 { +char data[NFS4_MAX_SESSIONID_LEN ]; +}; + +struct nfs41_sequence_args { +/* stub */ +}; + +#define SEQ4_STATUS_CB_PATH_DOWN 0x00000001 +#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002 +#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED 0x00000004 +#define SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED 0x00000008 +#define SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED 0x00000010 +#define SEQ4_STATUS_ADMIN_STATE_REVOKED 0x00000020 +#define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040 +#define SEQ4_STATUS_LEASE_MOVED 0x00000080 +#define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100 + +struct nfs41_sequence_res { +/* stub */ +}; + +#if defined(CONFIG_NFS_V4_1 ) + +struct nfs4_get_lease_time_args { +struct nfs41_sequence_args la_seq_args; +}; + +struct nfs4_get_lease_time_res { +struct nfs_fsinfo *lr_fsinfo; +struct nfs41_sequence_res lr_seq_res; +}; + +#endif /* CONFIG_NFS_V4_1 */ +/* * Arguments to the open call. */
@@ -132,6 +169,7 @@ struct nfs_openargs {const struct nfs_server *server;/* Needed for ID mapping */ const u32 * bitmask;__u32 claim; +struct nfs41_sequence_args seq_args; };struct nfs_openres {
@@ -148,6 +186,7 @@ struct nfs_openres {__u32 do_recall;__u64 maxsize;__u32 attrset[NFS4_BITMAP_SIZE ]; +struct nfs41_sequence_res seq_res; };/*
@@ -173,6 +212,7 @@ struct nfs_closeargs {struct nfs_seqid * seqid;int open_flags;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs_closeres {
@@ -180,6 +220,7 @@ struct nfs_closeres {struct nfs_fattr * fattr;struct nfs_seqid * seqid;const struct nfs_server *server; +struct nfs41_sequence_res seq_res; };/* * * Arguments to the lock,lockt, and locku call.
@@ -200,12 +241,14 @@ struct nfs_lock_args { unsigned char block : 1; unsigned char reclaim : 1; unsigned char new_lock_owner : 1; +struct nfs41_sequence_args seq_args; };struct nfs_lock_res {nfs4_stateid stateid;struct nfs_seqid * lock_seqid;struct nfs_seqid * open_seqid; +struct nfs41_sequence_res seq_res; };struct nfs_locku_args {
@@ -213,32 +256,38 @@ struct nfs_locku_args {struct file_lock * fl;struct nfs_seqid * seqid;nfs4_stateid * stateid; +struct nfs41_sequence_args seq_args; };struct nfs_locku_res {nfs4_stateid stateid;struct nfs_seqid * seqid; +struct nfs41_sequence_res seq_res; };struct nfs_lockt_args {struct nfs_fh * fh;struct file_lock * fl;struct nfs_lowner lock_owner; +struct nfs41_sequence_args seq_args; };struct nfs_lockt_res {struct file_lock * denied;/* LOCK, LOCKT failed */ +struct nfs41_sequence_res seq_res; };struct nfs4_delegreturnargs {const struct nfs_fh *fhandle;const nfs4_stateid *stateid;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_delegreturnres {struct nfs_fattr * fattr;const struct nfs_server *server; +struct nfs41_sequence_res seq_res; };/*
@@ -251,12 +300,14 @@ struct nfs_readargs {__u32 count;unsigned int pgbase;struct page ** pages; +struct nfs41_sequence_args seq_args; };struct nfs_readres {struct nfs_fattr * fattr;__u32 count;int eof; +struct nfs41_sequence_res seq_res; };/*
@@ -271,6 +322,7 @@ struct nfs_writeargs {unsigned int pgbase;struct page ** pages;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs_writeverf {
@@ -283,6 +335,7 @@ struct nfs_writeres {struct nfs_writeverf * verf;__u32 count;const struct nfs_server *server; +struct nfs41_sequence_res seq_res; };/*
@@ -292,12 +345,14 @@ struct nfs_removeargs {const struct nfs_fh *fh;struct qstr name;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs_removeres {const struct nfs_server *server;struct nfs4_change_info cinfo;struct nfs_fattr dir_attr; +struct nfs41_sequence_res seq_res; };/*
@@ -350,6 +405,7 @@ struct nfs_setattrargs {struct iattr * iap;const struct nfs_server * server;/* Needed for name mapping */ const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs_setaclargs {
@@ -357,6 +413,11 @@ struct nfs_setaclargs {size_t acl_len;unsigned int acl_pgbase;struct page ** acl_pages; +struct nfs41_sequence_args seq_args; +}; + +struct nfs_setaclres { +struct nfs41_sequence_res seq_res; };struct nfs_getaclargs {
@@ -364,11 +425,18 @@ struct nfs_getaclargs {size_t acl_len;unsigned int acl_pgbase;struct page ** acl_pages; +struct nfs41_sequence_args seq_args; +}; + +struct nfs_getaclres { +size_t *acl_len; +struct nfs41_sequence_res seq_res; };struct nfs_setattrres {struct nfs_fattr * fattr;const struct nfs_server * server; +struct nfs41_sequence_res seq_res; };struct nfs_linkargs {
@@ -548,6 +616,7 @@ struct nfs4_accessargs {const struct nfs_fh * fh;const u32 * bitmask;u32 access; +struct nfs41_sequence_args seq_args; };struct nfs4_accessres {
@@ -555,6 +624,7 @@ struct nfs4_accessres {struct nfs_fattr * fattr;u32 supported;u32 access; +struct nfs41_sequence_res seq_res; };struct nfs4_create_arg {
@@ -574,6 +644,7 @@ struct nfs4_create_arg {const struct iattr * attrs;const struct nfs_fh * dir_fh;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_create_res {
@@ -582,21 +653,30 @@ struct nfs4_create_res {struct nfs_fattr * fattr;struct nfs4_change_info dir_cinfo;struct nfs_fattr * dir_fattr; +struct nfs41_sequence_res seq_res; };struct nfs4_fsinfo_arg {const struct nfs_fh * fh;const u32 * bitmask; +struct nfs41_sequence_args seq_args; +}; + +struct nfs4_fsinfo_res { +struct nfs_fsinfo *fsinfo; +struct nfs41_sequence_res seq_res; };struct nfs4_getattr_arg {const struct nfs_fh * fh;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_getattr_res {const struct nfs_server * server;struct nfs_fattr * fattr; +struct nfs41_sequence_res seq_res; };struct nfs4_link_arg {
@@ -604,6 +684,7 @@ struct nfs4_link_arg {const struct nfs_fh * dir_fh;const struct qstr * name;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_link_res {
@@ -611,6 +692,7 @@ struct nfs4_link_res {struct nfs_fattr * fattr;struct nfs4_change_info cinfo;struct nfs_fattr * dir_attr; +struct nfs41_sequence_res seq_res; };
@@ -618,21 +700,30 @@ struct nfs4_lookup_arg {const struct nfs_fh * dir_fh;const struct qstr * name;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_lookup_res {const struct nfs_server * server;struct nfs_fattr * fattr;struct nfs_fh * fh; +struct nfs41_sequence_res seq_res; };struct nfs4_lookup_root_arg {const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_pathconf_arg {const struct nfs_fh * fh;const u32 * bitmask; +struct nfs41_sequence_args seq_args; +}; + +struct nfs4_pathconf_res { +struct nfs_pathconf *pathconf; +struct nfs41_sequence_res seq_res; };struct nfs4_readdir_arg {
@@ -643,11 +734,13 @@ struct nfs4_readdir_arg {struct page ** pages;/* zero-copy data */ unsigned int pgbase;/* zero-copy data */ const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_readdir_res {nfs4_verifier verifier;unsigned int pgbase; +struct nfs41_sequence_res seq_res; };struct nfs4_readlink {
@@ -655,6 +748,11 @@ struct nfs4_readlink {unsigned int pgbase;unsigned int pglen;/* zero-copy data */ struct page ** pages;/* zero-copy data */ +struct nfs41_sequence_args seq_args; +}; + +struct nfs4_readlink_res { +struct nfs41_sequence_res seq_res; };struct nfs4_rename_arg {
@@ -663,6 +761,7 @@ struct nfs4_rename_arg {const struct qstr * old_name;const struct qstr * new_name;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_rename_res {
@@ -671,6 +770,7 @@ struct nfs4_rename_res {struct nfs_fattr * old_fattr;struct nfs4_change_info new_cinfo;struct nfs_fattr * new_fattr; +struct nfs41_sequence_res seq_res; };#define NFS4_SETCLIENTID_NAMELEN (127)
@@ -689,6 +789,17 @@ struct nfs4_setclientid {struct nfs4_statfs_arg {const struct nfs_fh * fh;const u32 * bitmask; +struct nfs41_sequence_args seq_args; +}; + +struct nfs4_statfs_res { +struct nfs_fsstat *fsstat; +struct nfs41_sequence_res seq_res; +}; + +struct nfs4_server_caps_arg { +struct nfs_fh *fhandle; +struct nfs41_sequence_args seq_args; };struct nfs4_server_caps_res {
@@ -696,6 +807,7 @@ struct nfs4_server_caps_res {u32 acl_bitmask;u32 has_links;u32 has_symlinks; +struct nfs41_sequence_res seq_res; };struct nfs4_string {
@@ -730,6 +842,12 @@ struct nfs4_fs_locations_arg {const struct qstr *name;struct page *page;const u32 *bitmask; + struct nfs41_sequence_args seq_args; +}; + +struct nfs4_fs_locations_res { +struct nfs4_fs_locations *fs_locations; +struct nfs41_sequence_res seq_res; };#endif /* CONFIG_NFS_V4 */
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 08/85] nfs41: client xdr definitions
Quoted 15 lines · Benny Halevy
Define stubs for sequence args and res data structures and embed them in all other nfs4 and nfs41 xdr types. They are needed for sending any op in a nfs41 compound rpc.
Signed-off-by Andy Adamson<[email protected]>Signed-off-by Benny Halevy <[email protected]>--- include/linux/nfs_xdr.h | 118 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 118 insertions(+), 0 deletions(-)include/linux/nfs_xdr.h +0
-0
include/linux/nfs_xdr.h struct nfs4_change_info { · line 120
Quoted 8 lines
include/linux/nfs_xdr.h +5
-0@@ -113,6 +113,43 @@ struct nfs4_change_info { };struct nfs_seqid ; + +/* Opaque session ID */ +struct sessionid4 { +char data[NFS4_MAX_SESSIONID_LEN ]; +};
review 11-14: this is redundant.
Quoted 10 lines
include/linux/nfs_xdr.h +10
-0+ +struct nfs41_sequence_args { +/* stub */ +}; + +#define SEQ4_STATUS_CB_PATH_DOWN 0x00000001 +#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002 +#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED 0x00000004 +#define SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED 0x00000008 +#define SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED 0x00000010
include/linux/nfs_xdr.h struct nfs4_change_info { · line 140
Quoted 10 lines
include/linux/nfs_xdr.h +10
-0+#define SEQ4_STATUS_ADMIN_STATE_REVOKED 0x00000020 +#define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040 +#define SEQ4_STATUS_LEASE_MOVED 0x00000080 +#define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100 + +struct nfs41_sequence_res { +/* stub */ +}; + +#if defined(CONFIG_NFS_V4_1 )
review 11-14: no need for #ifdef
Quoted 16 lines
include/linux/nfs_xdr.h +12
-0+ +struct nfs4_get_lease_time_args { +struct nfs41_sequence_args la_seq_args; +}; + +struct nfs4_get_lease_time_res { +struct nfs_fsinfo *lr_fsinfo; +struct nfs41_sequence_res lr_seq_res; +}; + +#endif /* CONFIG_NFS_V4_1 */ +/* * Arguments to the open call. */
include/linux/nfs_xdr.h struct nfs_openargs { · line 172
Quoted 4 lines
include/linux/nfs_xdr.h +1
-0@@ -132,6 +169,7 @@ struct nfs_openargs {const struct nfs_server *server;/* Needed for ID mapping */ const u32 * bitmask;__u32 claim; +struct nfs41_sequence_args seq_args;
review 11-14: discussed embedding seq_args/res vs. having a wrapper structure a-la
struct nfs_rpc_args {
void *op_args;
struct nfs41_sequence_args seq_args;
};struct nfs_rpc_res {
void *op_res;
struct nfs41_sequence_res seq_res;
};Trond prefers the former (keep current).
Quoted 349 lines
include/linux/nfs_xdr.h +80
-0};struct nfs_openres {@@ -148,6 +186,7 @@ struct nfs_openres {__u32 do_recall;__u64 maxsize;__u32 attrset[NFS4_BITMAP_SIZE ]; +struct nfs41_sequence_res seq_res; };/* @@ -173,6 +212,7 @@ struct nfs_closeargs {struct nfs_seqid * seqid;int open_flags;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs_closeres {@@ -180,6 +220,7 @@ struct nfs_closeres {struct nfs_fattr * fattr;struct nfs_seqid * seqid;const struct nfs_server *server; +struct nfs41_sequence_res seq_res; };/* * * Arguments to the lock,lockt, and locku call. @@ -200,12 +241,14 @@ struct nfs_lock_args { unsigned char block : 1; unsigned char reclaim : 1; unsigned char new_lock_owner : 1; +struct nfs41_sequence_args seq_args; };struct nfs_lock_res {nfs4_stateid stateid;struct nfs_seqid * lock_seqid;struct nfs_seqid * open_seqid; +struct nfs41_sequence_res seq_res; };struct nfs_locku_args {@@ -213,32 +256,38 @@ struct nfs_locku_args {struct file_lock * fl;struct nfs_seqid * seqid;nfs4_stateid * stateid; +struct nfs41_sequence_args seq_args; };struct nfs_locku_res {nfs4_stateid stateid;struct nfs_seqid * seqid; +struct nfs41_sequence_res seq_res; };struct nfs_lockt_args {struct nfs_fh * fh;struct file_lock * fl;struct nfs_lowner lock_owner; +struct nfs41_sequence_args seq_args; };struct nfs_lockt_res {struct file_lock * denied;/* LOCK, LOCKT failed */ +struct nfs41_sequence_res seq_res; };struct nfs4_delegreturnargs {const struct nfs_fh *fhandle;const nfs4_stateid *stateid;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_delegreturnres {struct nfs_fattr * fattr;const struct nfs_server *server; +struct nfs41_sequence_res seq_res; };/* @@ -251,12 +300,14 @@ struct nfs_readargs {__u32 count;unsigned int pgbase;struct page ** pages; +struct nfs41_sequence_args seq_args; };struct nfs_readres {struct nfs_fattr * fattr;__u32 count;int eof; +struct nfs41_sequence_res seq_res; };/* @@ -271,6 +322,7 @@ struct nfs_writeargs {unsigned int pgbase;struct page ** pages;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs_writeverf {@@ -283,6 +335,7 @@ struct nfs_writeres {struct nfs_writeverf * verf;__u32 count;const struct nfs_server *server; +struct nfs41_sequence_res seq_res; };/* @@ -292,12 +345,14 @@ struct nfs_removeargs {const struct nfs_fh *fh;struct qstr name;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs_removeres {const struct nfs_server *server;struct nfs4_change_info cinfo;struct nfs_fattr dir_attr; +struct nfs41_sequence_res seq_res; };/* @@ -350,6 +405,7 @@ struct nfs_setattrargs {struct iattr * iap;const struct nfs_server * server;/* Needed for name mapping */ const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs_setaclargs {@@ -357,6 +413,11 @@ struct nfs_setaclargs {size_t acl_len;unsigned int acl_pgbase;struct page ** acl_pages; +struct nfs41_sequence_args seq_args; +}; + +struct nfs_setaclres { +struct nfs41_sequence_res seq_res; };struct nfs_getaclargs {@@ -364,11 +425,18 @@ struct nfs_getaclargs {size_t acl_len;unsigned int acl_pgbase;struct page ** acl_pages; +struct nfs41_sequence_args seq_args; +}; + +struct nfs_getaclres { +size_t *acl_len; +struct nfs41_sequence_res seq_res; };struct nfs_setattrres {struct nfs_fattr * fattr;const struct nfs_server * server; +struct nfs41_sequence_res seq_res; };struct nfs_linkargs {@@ -548,6 +616,7 @@ struct nfs4_accessargs {const struct nfs_fh * fh;const u32 * bitmask;u32 access; +struct nfs41_sequence_args seq_args; };struct nfs4_accessres {@@ -555,6 +624,7 @@ struct nfs4_accessres {struct nfs_fattr * fattr;u32 supported;u32 access; +struct nfs41_sequence_res seq_res; };struct nfs4_create_arg {@@ -574,6 +644,7 @@ struct nfs4_create_arg {const struct iattr * attrs;const struct nfs_fh * dir_fh;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_create_res {@@ -582,21 +653,30 @@ struct nfs4_create_res {struct nfs_fattr * fattr;struct nfs4_change_info dir_cinfo;struct nfs_fattr * dir_fattr; +struct nfs41_sequence_res seq_res; };struct nfs4_fsinfo_arg {const struct nfs_fh * fh;const u32 * bitmask; +struct nfs41_sequence_args seq_args; +}; + +struct nfs4_fsinfo_res { +struct nfs_fsinfo *fsinfo; +struct nfs41_sequence_res seq_res; };struct nfs4_getattr_arg {const struct nfs_fh * fh;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_getattr_res {const struct nfs_server * server;struct nfs_fattr * fattr; +struct nfs41_sequence_res seq_res; };struct nfs4_link_arg {@@ -604,6 +684,7 @@ struct nfs4_link_arg {const struct nfs_fh * dir_fh;const struct qstr * name;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_link_res {@@ -611,6 +692,7 @@ struct nfs4_link_res {struct nfs_fattr * fattr;struct nfs4_change_info cinfo;struct nfs_fattr * dir_attr; +struct nfs41_sequence_res seq_res; };@@ -618,21 +700,30 @@ struct nfs4_lookup_arg {const struct nfs_fh * dir_fh;const struct qstr * name;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_lookup_res {const struct nfs_server * server;struct nfs_fattr * fattr;struct nfs_fh * fh; +struct nfs41_sequence_res seq_res; };struct nfs4_lookup_root_arg {const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_pathconf_arg {const struct nfs_fh * fh;const u32 * bitmask; +struct nfs41_sequence_args seq_args; +}; + +struct nfs4_pathconf_res { +struct nfs_pathconf *pathconf; +struct nfs41_sequence_res seq_res; };struct nfs4_readdir_arg {@@ -643,11 +734,13 @@ struct nfs4_readdir_arg {struct page ** pages;/* zero-copy data */ unsigned int pgbase;/* zero-copy data */ const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_readdir_res {nfs4_verifier verifier;unsigned int pgbase; +struct nfs41_sequence_res seq_res; };struct nfs4_readlink {@@ -655,6 +748,11 @@ struct nfs4_readlink {unsigned int pgbase;unsigned int pglen;/* zero-copy data */ struct page ** pages;/* zero-copy data */ +struct nfs41_sequence_args seq_args; +}; + +struct nfs4_readlink_res { +struct nfs41_sequence_res seq_res; };struct nfs4_rename_arg {@@ -663,6 +761,7 @@ struct nfs4_rename_arg {const struct qstr * old_name;const struct qstr * new_name;const u32 * bitmask; +struct nfs41_sequence_args seq_args; };struct nfs4_rename_res {@@ -671,6 +770,7 @@ struct nfs4_rename_res {struct nfs_fattr * old_fattr;struct nfs4_change_info new_cinfo;struct nfs_fattr * new_fattr; +struct nfs41_sequence_res seq_res; };#define NFS4_SETCLIENTID_NAMELEN (127)@@ -689,6 +789,17 @@ struct nfs4_setclientid {struct nfs4_statfs_arg {const struct nfs_fh * fh;const u32 * bitmask; +struct nfs41_sequence_args seq_args; +}; + +struct nfs4_statfs_res { +struct nfs_fsstat *fsstat; +struct nfs41_sequence_res seq_res; +}; + +struct nfs4_server_caps_arg { +struct nfs_fh *fhandle; +struct nfs41_sequence_args seq_args; };struct nfs4_server_caps_res {@@ -696,6 +807,7 @@ struct nfs4_server_caps_res {u32 acl_bitmask;u32 has_links;u32 has_symlinks; +struct nfs41_sequence_res seq_res; };struct nfs4_string {@@ -730,6 +842,12 @@ struct nfs4_fs_locations_arg {const struct qstr *name;struct page *page;const u32 *bitmask; + struct nfs41_sequence_args seq_args; +}; + +struct nfs4_fs_locations_res { +struct nfs4_fs_locations *fs_locations; +struct nfs41_sequence_res seq_res; };#endif /* CONFIG_NFS_V4 */
RFC 9/85 nfs41: add mount command option minorvers
In reply to Benny HalevyFrom: Mike Sager <[email protected]>
mount -t nfs4 -o minorvers=[0|1] specifies whether to use 4.0 or 4.1. The default is 1.
--- fs/nfs/internal.h | 1 + fs/nfs/super.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 0 deletions(-)
fs/nfs/internal.h +1 -0
@@ -41,6 +41,7 @@ struct nfs_parsed_mount_data {unsigned int auth_flavor_len;rpc_authflavor_t auth_flavors[1 ];char *client_address; +unsigned int minorversion;struct {struct sockaddr_storage address;
fs/nfs/super.c +10 -0
@@ -87,6 +87,7 @@ enum { Opt_mountport, Opt_mountvers, Opt_nfsvers, + Opt_minorversion,/* Mount options that take string arguments */ Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
@@ -146,6 +147,7 @@ static const match_table_t nfs_mount_option_tokens = { { Opt_mountvers, "mountvers=%u" }, { Opt_nfsvers, "nfsvers=%u" }, { Opt_nfsvers, "vers=%u" }, + { Opt_minorversion, "minorversion=%u" }, { Opt_sec, "sec=%s" }, { Opt_proto, "proto=%s" },
@@ -1160,6 +1162,13 @@ static int nfs_parse_mount_options(char *raw,nfs_parse_invalid_value ("nfsvers" ); }break ; +case Opt_minorversion: +if (match_int (args, &option)) +return 0 ; +if (option <0 || option >NFS4_MAX_MINOR_VERSION ) +return 0 ; + mnt->minorversion = option; +break ;/* * options that take text values
@@ -2208,6 +2217,7 @@ static int nfs4_validate_mount_data(void *options, args->nfs_server.port =NFS_PORT ;/* 2049 unless user set port= */ args->auth_flavors[0 ] =RPC_AUTH_UNIX ; args->auth_flavor_len =0 ; + args->minorversion =NFS4_MAX_MINOR_VERSION ;switch (data->version) {case 1 :
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 09/85] nfs41: add mount command option minorvers
review 11-13: s/minorvers/minorversion/ in patch description add to commit message reasoning - mounting a broken nfsv4.0 server that breaks when attempting a 4.1 mount
Quoted 66 lines · Benny Halevy
From: Mike Sager <[email protected]>
mount -t nfs4 -o minorvers=[0|1] specifies whether to use 4.0 or 4.1. The default is 1.
Signed-off-by Mike Sager <[email protected]>Signed-off-by Benny Halevy <[email protected]>--- fs/nfs/internal.h | 1 + fs/nfs/super.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 0 deletions(-)fs/nfs/internal.h +1
-0@@ -41,6 +41,7 @@ struct nfs_parsed_mount_data {unsigned int auth_flavor_len;rpc_authflavor_t auth_flavors[1 ];char *client_address; +unsigned int minorversion;struct {struct sockaddr_storage address;fs/nfs/super.c +10
-0@@ -87,6 +87,7 @@ enum { Opt_mountport, Opt_mountvers, Opt_nfsvers, + Opt_minorversion,/* Mount options that take string arguments */ Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,@@ -146,6 +147,7 @@ static const match_table_t nfs_mount_option_tokens = { { Opt_mountvers, "mountvers=%u" }, { Opt_nfsvers, "nfsvers=%u" }, { Opt_nfsvers, "vers=%u" }, + { Opt_minorversion, "minorversion=%u" }, { Opt_sec, "sec=%s" }, { Opt_proto, "proto=%s" },@@ -1160,6 +1162,13 @@ static int nfs_parse_mount_options(char *raw,nfs_parse_invalid_value ("nfsvers" ); }break ; +case Opt_minorversion: +if (match_int (args, &option)) +return 0 ; +if (option <0 || option >NFS4_MAX_MINOR_VERSION ) +return 0 ; + mnt->minorversion = option; +break ;/* * options that take text values @@ -2208,6 +2217,7 @@ static int nfs4_validate_mount_data(void *options, args->nfs_server.port =NFS_PORT ;/* 2049 unless user set port= */ args->auth_flavors[0 ] =RPC_AUTH_UNIX ; args->auth_flavor_len =0 ; + args->minorversion =NFS4_MAX_MINOR_VERSION ;switch (data->version) {case 1 :
RFC 10/85 nfs41: struct nfs_server minorversion
In reply to Benny HalevyFrom: Mike Sager <[email protected]>
Set nfs_server minorversion from mount option (or default). During client initialization, use this minorversion.
--- fs/nfs/client.c | 2 ++ include/linux/nfs_fs_sb.h | 1 + 2 files changed, 3 insertions(+), 0 deletions(-)
fs/nfs/client.c +2 -0
@@ -1112,6 +1112,8 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,if (!server)return ERR_PTR (-ENOMEM ); + server->minorversion = data->minorversion; +/* set up the general RPC client */ error =nfs4_init_server (server, data);if (error <0 )
include/linux/nfs_fs_sb.h +1 -0
@@ -115,6 +115,7 @@ struct nfs_server {u32 acl_bitmask;/* V4 bitmask representing the ACEs that are supported on this filesystem */ +u32 minorversion;#endif void (*destroy)(struct nfs_server *);
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 10/85] nfs41: struct nfs_server minorversion
Quoted 7 lines · Benny Halevy
From: Mike Sager <[email protected]>
Set
nfs_serverminorversion from mount option (or default). During client initialization, use this minorversion.Signed-off-by Mike Sager <[email protected]>Signed-off-by Benny Halevy <[email protected]>
review 11-14: see if wse can only keep one copy of the minorversion in the nfs_client.
Quoted 30 lines
--- fs/nfs/client.c | 2 ++ include/linux/nfs_fs_sb.h | 1 + 2 files changed, 3 insertions(+), 0 deletions(-)fs/nfs/client.c +2
-0@@ -1112,6 +1112,8 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,if (!server)return ERR_PTR (-ENOMEM ); + server->minorversion = data->minorversion; +/* set up the general RPC client */ error =nfs4_init_server (server, data);if (error <0 )include/linux/nfs_fs_sb.h +1
-0@@ -115,6 +115,7 @@ struct nfs_server {u32 acl_bitmask;/* V4 bitmask representing the ACEs that are supported on this filesystem */ +u32 minorversion;#endif void (*destroy)(struct nfs_server *);
Signature · 9 lines
Benny Halevy Software Architect Tel/Fax: +972-3-647-8340 Mobile: +972-54-802-8340 [email protected] Panasas, Inc. The Leader in Parallel Storage www.panasas.com
RFC 11/85 nfs41: nfs_client.cl_minorversion
In reply to Benny HalevyThis field is set to the nfsv4 minor version for this mount.
--- fs/nfs/client.c | 1 + include/linux/nfs_fs_sb.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletions(-)
fs/nfs/client.c +1 -0
@@ -1030,6 +1030,7 @@ static int nfs4_set_client(struct nfs_server *server, error =PTR_ERR (clp); goto error; } + clp->cl_minorversion = server->minorversion; error =nfs4_init_client (clp, timeparms, ip_addr, authflavour);if (error <0 ) goto error_put;
include/linux/nfs_fs_sb.h +2 -1
@@ -69,7 +69,8 @@ struct nfs_client {*/ char cl_ipaddr[48 ];unsigned char cl_id_uniquifier; -#endif +u32 cl_minorversion; +#endif /* CONFIG_NFS_V4 */ };/*
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 11/85] nfs41: nfs_client.cl_minorversion
Quoted 3 lines · Benny Halevy
This field is set to the nfsv4 minor version for this mount.
Signed-off-by Benny Halevy <[email protected]>
review 11-14: directly set cl_minorversion to data->minorversion in callers of nfs4_set_client.
we want to differentiate between autodetect minorersion (-1) and one that's explictly set by the mount option. and remember that for referrals. keep that as a flag in nfs_client.cl_res_state
On autodetect reclaimer should try with the highest minorversion and possibly fallback if needed, otherwise try only given minorversion. On clone (referral) follow the same algorithm using the master copy's minorversion configuration.
Quoted 31 lines
--- fs/nfs/client.c | 1 + include/linux/nfs_fs_sb.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletions(-)fs/nfs/client.c +1
-0@@ -1030,6 +1030,7 @@ static int nfs4_set_client(struct nfs_server *server, error =PTR_ERR (clp); goto error; } + clp->cl_minorversion = server->minorversion; error =nfs4_init_client (clp, timeparms, ip_addr, authflavour);if (error <0 ) goto error_put;include/linux/nfs_fs_sb.h +2
-1@@ -69,7 +69,8 @@ struct nfs_client {*/ char cl_ipaddr[48 ];unsigned char cl_id_uniquifier; -#endif +u32 cl_minorversion; +#endif /* CONFIG_NFS_V4 */ };/*
RFC 12/85 nfs41: set nfs_client rpc_ops based on minorversion
In reply to Benny Halevy--- fs/nfs/client.c | 6 ++-- fs/nfs/nfs4proc.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++- include/linux/nfs_xdr.h | 3 ++ 3 files changed, 54 insertions(+), 4 deletions(-)
fs/nfs/client.c +3 -3
@@ -359,7 +359,8 @@ static struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_inint error;dprintk ("--> nfs_get_client(%s,v%u)\n" , - cl_init->hostname ?:"" , cl_init->rpc_ops->version); + cl_init->hostname ?:"" , + cl_init->rpc_ops ? cl_init->rpc_ops->version :0 );/* see if the client already exists */ do {
@@ -976,7 +977,7 @@ static int nfs4_init_client(struct nfs_client *clp, }/* Check NFS protocol revision and initialize RPC op vector */ - clp->rpc_ops = &nfs_v4_clientops; + clp->rpc_ops = nfsv4_minorversion_clientops[clp->cl_minorversion]; error =nfs_create_rpc_client (clp, timeparms, authflavour,RPC_CLNT_CREATE_DISCRTRY );
@@ -1016,7 +1017,6 @@ static int nfs4_set_client(struct nfs_server *server, .hostname = hostname, .addr = addr, .addrlen = addrlen, - .rpc_ops = &nfs_v4_clientops, .proto = proto, };struct nfs_client *clp;
fs/nfs/nfs4proc.c +48 -1
61 lines not on this page · raw message
include/linux/nfs_xdr.h +3 -0
@@ -966,6 +966,9 @@ struct nfs_rpc_ops {extern const struct nfs_rpc_ops nfs_v2_clientops;extern const struct nfs_rpc_ops nfs_v3_clientops;extern const struct nfs_rpc_ops nfs_v4_clientops; +extern const struct nfs_rpc_ops nfs_v40_clientops; +extern const struct nfs_rpc_ops nfs_v41_clientops; +extern const struct nfs_rpc_ops *nfsv4_minorversion_clientops[];extern struct rpc_version nfs_version2;extern struct rpc_version nfs_version3;extern struct rpc_version nfs_version4;
Signature · 1 line
1.6.0.2
RFC 13/85 nfs41: use ptr to rpc procedures via struct nfs_client
In reply to Benny HalevyTo support heterogenuous mount minor version, use the ptr to the effective rpc procedures table via nfs_client->cl_rpcclient->cl_procinfo rather than a global one.
nfs4_proc() is a static inline helper to get the rpc procedure given a struct nfs_client * and the procedure index.
--- fs/nfs/internal.h | 5 --- fs/nfs/nfs4_fs.h | 1 - fs/nfs/nfs4proc.c | 88 ++++++++++++++++++++++++++------------------- fs/nfs/nfs4xdr.c | 22 +++++++++-- include/linux/nfs_fs_sb.h | 9 +++++ include/linux/nfs_xdr.h | 3 ++ 6 files changed, 81 insertions(+), 47 deletions(-)
fs/nfs/internal.h +0 -5
@@ -134,11 +134,6 @@ extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int);extern __be32 *nfs4_decode_dirent (__be32 *p,struct nfs_entry *entry,int plus);#endif -/* nfs4proc.c */ -#ifdef CONFIG_NFS_V4 -extern struct rpc_procinfo nfs4_procedures[]; -#endif -/* dir.c */ extern int nfs_access_cache_shrinker (int nr_to_scan,gfp_t gfp_mask);
fs/nfs/nfs4_fs.h +0 -1
@@ -226,7 +226,6 @@ extern const nfs4_stateid zero_stateid;/* nfs4xdr.c */ extern __be32 *nfs4_decode_dirent (__be32 *p,struct nfs_entry *entry,int plus); -extern struct rpc_procinfo nfs4_procedures[];struct nfs4_mount_data ;
fs/nfs/nfs4proc.c +51 -37
320 lines not on this page · raw message
fs/nfs/nfs4xdr.c +18 -4
@@ -4922,11 +4922,25 @@ struct rpc_procinfo nfs4_procedures[] = { PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), }; -struct rpc_version nfs_version4 = { - .number =4 , - .nrprocs =ARRAY_SIZE (nfs4_procedures), - .procs = nfs4_procedures +#if defined(CONFIG_NFS_V4_1 ) +struct rpc_procinfo nfs41_procedures[] = { }; +#endif /* CONFIG_NFS_V4_1 */ + +struct rpc_version nfs_version4 = { + .number =4 , + .nrprocs =ARRAY_SIZE (nfs4_procedures), + .procs = nfs4_procedures +}; + +#ifdef CONFIG_NFS_V4_1 +struct rpc_version nfs_version41 = { + .number =4 , + .nrprocs =ARRAY_SIZE (nfs41_procedures), + .procs = nfs41_procedures +}; + +#endif /* CONFIG_NFS_V4_1 */ /* * Local variables:
include/linux/nfs_fs_sb.h +9 -0
@@ -73,6 +73,15 @@ struct nfs_client {#endif /* CONFIG_NFS_V4 */ }; +#ifdef CONFIG_NFS_V4 +static inline struct rpc_procinfo * +nfs4_proc (struct nfs_client *clp,int idx) +{ +struct rpc_procinfo *procs = clp->cl_rpcclient->cl_procinfo; +return &procs[idx]; +} +#endif /* CONFIG_NFS_V4 */ +/* * NFS client parameters stored in the superblock. */
include/linux/nfs_xdr.h +3 -0
@@ -969,6 +969,9 @@ extern const struct nfs_rpc_ops nfs_v4_clientops;extern const struct nfs_rpc_ops nfs_v40_clientops;extern const struct nfs_rpc_ops nfs_v41_clientops;extern const struct nfs_rpc_ops *nfsv4_minorversion_clientops[]; +extern struct rpc_version *nfs4_minorversions[]; +extern struct rpc_procinfo *nfs4_minorversion_procedures[]; +extern struct rpc_version nfs_version2;extern struct rpc_version nfs_version3;extern struct rpc_version nfs_version4;
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 13/85] nfs41: use ptr to rpc procedures via struct nfs_client
Quoted 8 lines · Benny Halevy
To support heterogenuous mount minor version, use the ptr to the effective rpc procedures table via
nfs_client->cl_rpcclient->cl_procinforather than a global one.
nfs4_proc()is a static inline helper to get the rpc procedure given a structnfs_client* and the procedure index.Signed-off-by Benny Halevy <[email protected]>
review 11-14: this patch should be dropped since there's no nfs41_prcedures and no need for nfs_version41 (when we take the minorversion field out of struct rpc_version)
Quoted 467 lines
--- fs/nfs/internal.h | 5 --- fs/nfs/nfs4_fs.h | 1 - fs/nfs/nfs4proc.c | 88 ++++++++++++++++++++++++++------------------- fs/nfs/nfs4xdr.c | 22 +++++++++-- include/linux/nfs_fs_sb.h | 9 +++++ include/linux/nfs_xdr.h | 3 ++ 6 files changed, 81 insertions(+), 47 deletions(-)fs/nfs/internal.h +0
-5@@ -134,11 +134,6 @@ extern __be32 *nfs3_decode_dirent(__be32 *, struct nfs_entry *, int);extern __be32 *nfs4_decode_dirent (__be32 *p,struct nfs_entry *entry,int plus);#endif -/* nfs4proc.c */ -#ifdef CONFIG_NFS_V4 -extern struct rpc_procinfo nfs4_procedures[]; -#endif -/* dir.c */ extern int nfs_access_cache_shrinker (int nr_to_scan,gfp_t gfp_mask);fs/nfs/nfs4_fs.h +0
-1@@ -226,7 +226,6 @@ extern const nfs4_stateid zero_stateid;/* nfs4xdr.c */ extern __be32 *nfs4_decode_dirent (__be32 *p,struct nfs_entry *entry,int plus); -extern struct rpc_procinfo nfs4_procedures[];struct nfs4_mount_data ;fs/nfs/nfs4proc.c +51
-37@@ -762,7 +762,8 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)struct nfs_server *server =NFS_SERVER (data->dir->d_inode);struct rpc_task *task;struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_CONFIRM ], + .rpc_proc =nfs4_proc (server->nfs_client, +NFSPROC4_CLNT_OPEN_CONFIRM ), .rpc_argp = &data->c_arg, .rpc_resp = &data->c_res, .rpc_cred = data->owner->so_cred,@@ -823,7 +824,8 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) data->o_arg.id = sp->so_owner_id.id; data->o_arg.clientid = sp->so_client->cl_clientid;if (data->o_arg.claim ==NFS4_OPEN_CLAIM_PREVIOUS ) { - task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR ]; + task->tk_msg.rpc_proc =nfs4_proc (sp->so_client, +NFSPROC4_CLNT_OPEN_NOATTR );nfs_copy_fh (&data->o_res.fh, data->o_arg.fh); } data->timestamp = jiffies;@@ -899,7 +901,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)struct nfs_openres *o_res = &data->o_res;struct rpc_task *task;struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_OPEN ), .rpc_argp = o_arg, .rpc_resp = o_res, .rpc_cred = data->owner->so_cred,@@ -1153,7 +1155,8 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, .server = server, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETATTR ], + .rpc_proc =nfs4_proc (server->nfs_client, +NFSPROC4_CLNT_SETATTR ), .rpc_argp = &arg, .rpc_resp = &res, .rpc_cred = cred,@@ -1271,10 +1274,12 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) }nfs_fattr_init (calldata->res.fattr);if (test_bit (NFS_O_RDONLY_STATE , &state->flags) !=0 ) { - task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE ]; + task->tk_msg.rpc_proc =nfs4_proc (state->owner->so_client, +NFSPROC4_CLNT_OPEN_DOWNGRADE ); calldata->arg.open_flags =FMODE_READ ; }else if (test_bit (NFS_O_WRONLY_STATE , &state->flags) !=0 ) { - task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE ]; + task->tk_msg.rpc_proc =nfs4_proc (state->owner->so_client, +NFSPROC4_CLNT_OPEN_DOWNGRADE ); calldata->arg.open_flags =FMODE_WRITE ; } calldata->timestamp = jiffies;@@ -1305,7 +1310,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)struct nfs4_state_owner *sp = state->owner;struct rpc_task *task;struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE ], + .rpc_proc =nfs4_proc (sp->so_client,NFSPROC4_CLNT_CLOSE ), .rpc_cred = state->owner->so_cred, };struct rpc_task_setup task_setup_data = {@@ -1472,7 +1477,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f {struct nfs4_server_caps_res res = {};struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SERVER_CAPS ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_SERVER_CAPS ), .rpc_argp = fhandle, .rpc_resp = &res, };@@ -1516,7 +1521,7 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, .fh = fhandle, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP_ROOT ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_LOOKUP_ROOT ), .rpc_argp = &args, .rpc_resp = &res, };@@ -1605,7 +1610,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, .server = server, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETATTR ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_GETATTR ), .rpc_argp = &args, .rpc_resp = &res, };@@ -1687,7 +1692,7 @@ static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *d .fh = fhandle, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUP ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_LOOKUP ), .rpc_argp = &args, .rpc_resp = &res, };@@ -1756,7 +1761,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry .fattr = &fattr, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_ACCESS ), .rpc_argp = &args, .rpc_resp = &res, .rpc_cred = entry->cred,@@ -1834,6 +1839,7 @@ static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)static int _nfs4_proc_readlink (struct inode *inode,struct page *page,unsigned int pgbase,unsigned int pglen) { +struct nfs_server *server =NFS_SERVER (inode);struct nfs4_readlink args = { .fh =NFS_FH (inode), .pgbase = pgbase,@@ -1841,7 +1847,7 @@ static int _nfs4_proc_readlink(struct inode *inode, struct page *page, .pages = &page, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READLINK ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_READLINK ), .rpc_argp = &args, .rpc_resp =NULL , };@@ -1932,7 +1938,7 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name) .server = server, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_REMOVE ), .rpc_argp = &args, .rpc_resp = &res, };@@ -1967,7 +1973,7 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir) args->bitmask = server->attr_bitmask; res->server = server; - msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE ]; + msg->rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_REMOVE ); }static int nfs4_proc_unlink_done (struct rpc_task *task,struct inode *dir)@@ -1999,7 +2005,7 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name, .new_fattr = &new_fattr, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_RENAME ), .rpc_argp = &arg, .rpc_resp = &res, };@@ -2048,7 +2054,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr * .dir_attr = &dir_attr, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_LINK ), .rpc_argp = &arg, .rpc_resp = &res, };@@ -2096,7 +2102,8 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,if (data !=NULL ) {struct nfs_server *server =NFS_SERVER (dir); - data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE ]; + data->msg.rpc_proc =nfs4_proc (server->nfs_client, +NFSPROC4_CLNT_CREATE ); data->msg.rpc_argp = &data->arg; data->msg.rpc_resp = &data->res; data->arg.dir_fh =NFS_FH (dir);@@ -2145,7 +2152,8 @@ static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,if (data ==NULL ) goto out; - data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK ]; + data->msg.rpc_proc =nfs4_proc (NFS_SERVER (dir)->nfs_client, +NFSPROC4_CLNT_SYMLINK ); data->arg.u.symlink.pages = &page; data->arg.u.symlink.len = len;@@ -2204,6 +2212,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, u64 cookie, struct page *page, unsigned int count, int plus) { struct inode *dir = dentry->d_inode; +struct nfs_server *server =NFS_SERVER (dir); struct nfs4_readdir_arg args = { .fh = NFS_FH(dir), .pages = &page,@@ -2213,7 +2222,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, };struct nfs4_readdir_res res;struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READDIR ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_READDIR ), .rpc_argp = &args, .rpc_resp = &res, .rpc_cred = cred,@@ -2305,7 +2314,7 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, .bitmask = server->attr_bitmask, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_STATFS ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_STATFS ), .rpc_argp = &args, .rpc_resp = fsstat, };@@ -2334,7 +2343,7 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, .bitmask = server->attr_bitmask, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSINFO ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_FSINFO ), .rpc_argp = &args, .rpc_resp = fsinfo, };@@ -2369,7 +2378,7 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle .bitmask = server->attr_bitmask, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PATHCONF ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_PATHCONF ), .rpc_argp = &args, .rpc_resp = pathconf, };@@ -2415,8 +2424,10 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)static void nfs4_proc_read_setup (struct nfs_read_data *data,struct rpc_message *msg) { +struct nfs_server *server =NFS_SERVER (data->inode); + data->timestamp = jiffies; - msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ ]; + msg->rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_READ ); }static int nfs4_write_done (struct rpc_task *task,struct nfs_write_data *data)@@ -2442,7 +2453,7 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag data->res.server = server; data->timestamp = jiffies; - msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE ]; + msg->rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_WRITE ); }static int nfs4_commit_done (struct rpc_task *task,struct nfs_write_data *data)@@ -2463,7 +2474,7 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa data->args.bitmask = server->attr_bitmask; data->res.server = server; - msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT ]; + msg->rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_COMMIT ); }/* @@ -2497,7 +2508,7 @@ static const struct rpc_call_ops nfs4_renew_ops = {int nfs4_proc_async_renew (struct nfs_client *clp,struct rpc_cred *cred) {struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW ], + .rpc_proc =nfs4_proc (clp,NFSPROC4_CLNT_RENEW ), .rpc_argp = clp, .rpc_cred = cred, };@@ -2509,7 +2520,7 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)int nfs4_proc_renew (struct nfs_client *clp,struct rpc_cred *cred) {struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENEW ], + .rpc_proc =nfs4_proc (clp,NFSPROC4_CLNT_RENEW ), .rpc_argp = clp, .rpc_cred = cred, };@@ -2629,8 +2640,9 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu };size_t resp_len = buflen;void *resp_buf; +struct nfs_server *server =NFS_SERVER (inode);struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_GETACL ), .rpc_argp = &args, .rpc_resp = &resp_len, };@@ -2713,7 +2725,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl .acl_len = buflen, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETACL ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_SETACL ), .rpc_argp = &arg, .rpc_resp =NULL , };@@ -2853,7 +2865,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po .sc_prog = program, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID ], + .rpc_proc =nfs4_proc (clp,NFSPROC4_CLNT_SETCLIENTID ), .rpc_argp = &setclientid, .rpc_resp = clp, .rpc_cred = cred,@@ -2902,7 +2914,7 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cre {struct nfs_fsinfo fsinfo;struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM ], + .rpc_proc =nfs4_proc (clp,NFSPROC4_CLNT_SETCLIENTID_CONFIRM ), .rpc_argp = clp, .rpc_resp = &fsinfo, .rpc_cred = cred,@@ -2974,7 +2986,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, costruct nfs_server *server =NFS_SERVER (inode);struct rpc_task *task;struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DELEGRETURN ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_DELEGRETURN ), .rpc_cred = cred, };struct rpc_task_setup task_setup_data = {@@ -3066,7 +3078,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock .denied = request, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKT ], + .rpc_proc =nfs4_proc (clp,NFSPROC4_CLNT_LOCKT ), .rpc_argp = &arg, .rpc_resp = &res, .rpc_cred = state->owner->so_cred,@@ -3218,7 +3230,8 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl, {struct nfs4_unlockdata *data;struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU ], + .rpc_proc =nfs4_proc (NFS_SERVER (lsp->ls_state->inode)->nfs_client, +NFSPROC4_CLNT_LOCKU ), .rpc_cred = ctx->cred, };struct rpc_task_setup task_setup_data = {@@ -3405,7 +3418,8 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fstruct nfs4_lockdata *data;struct rpc_task *task;struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCK ], + .rpc_proc =nfs4_proc (NFS_SERVER (state->inode)->nfs_client, +NFSPROC4_CLNT_LOCK ), .rpc_cred = state->owner->so_cred, };struct rpc_task_setup task_setup_data = {@@ -3648,7 +3662,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, .bitmask = bitmask, };struct rpc_message msg = { - .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS ], + .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_FS_LOCATIONS ), .rpc_argp = &args, .rpc_resp = fs_locations, };fs/nfs/nfs4xdr.c +18
-4@@ -4922,11 +4922,25 @@ struct rpc_procinfo nfs4_procedures[] = { PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), }; -struct rpc_version nfs_version4 = { - .number =4 , - .nrprocs =ARRAY_SIZE (nfs4_procedures), - .procs = nfs4_procedures +#if defined(CONFIG_NFS_V4_1 ) +struct rpc_procinfo nfs41_procedures[] = { }; +#endif /* CONFIG_NFS_V4_1 */ + +struct rpc_version nfs_version4 = { + .number =4 , + .nrprocs =ARRAY_SIZE (nfs4_procedures), + .procs = nfs4_procedures +}; + +#ifdef CONFIG_NFS_V4_1 +struct rpc_version nfs_version41 = { + .number =4 , + .nrprocs =ARRAY_SIZE (nfs41_procedures), + .procs = nfs41_procedures +}; + +#endif /* CONFIG_NFS_V4_1 */ /* * Local variables: include/linux/nfs_fs_sb.h +9
-0@@ -73,6 +73,15 @@ struct nfs_client {#endif /* CONFIG_NFS_V4 */ }; +#ifdef CONFIG_NFS_V4 +static inline struct rpc_procinfo * +nfs4_proc (struct nfs_client *clp,int idx) +{ +struct rpc_procinfo *procs = clp->cl_rpcclient->cl_procinfo; +return &procs[idx]; +} +#endif /* CONFIG_NFS_V4 */ +/* * NFS client parameters stored in the superblock. */ include/linux/nfs_xdr.h +3
-0@@ -969,6 +969,9 @@ extern const struct nfs_rpc_ops nfs_v4_clientops;extern const struct nfs_rpc_ops nfs_v40_clientops;extern const struct nfs_rpc_ops nfs_v41_clientops;extern const struct nfs_rpc_ops *nfsv4_minorversion_clientops[]; +extern struct rpc_version *nfs4_minorversions[]; +extern struct rpc_procinfo *nfs4_minorversion_procedures[]; +extern struct rpc_version nfs_version2;extern struct rpc_version nfs_version3;extern struct rpc_version nfs_version4;
RFC 14/85 nfs41: sunrpc: support minorversion for rpc_clnt version table.
In reply to Benny HalevyValidate minorversion only if not zero as legacy code declares nrminorvers==0 and that should work just fine with minorversion==0 argument.
Pass minorversion down to rpc_create in nfs_create_rpc_client
--- fs/nfs/client.c | 17 ++++++++++++++--- include/linux/nfs_xdr.h | 3 +++ include/linux/sunrpc/clnt.h | 10 +++++++++- net/sunrpc/clnt.c | 13 ++++++++----- 4 files changed, 34 insertions(+), 9 deletions(-)
fs/nfs/client.c +14 -3
@@ -56,7 +56,10 @@ static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);/* * RPC cruft for NFS */ -static struct rpc_version *nfs_version[5 ] = { +#define NFS_MAXVERSION 4 + +static struct rpc_version *nfs_version[(NFS_MAXVERSION +1 ) * + (NFS4_MAX_MINOR_VERSION +1 )] = { [2 ] = &nfs_version2, #ifdef CONFIG_NFS_V3 [3] = &nfs_version3,
@@ -64,12 +67,16 @@ static struct rpc_version *nfs_version[5] = { #ifdef CONFIG_NFS_V4 [4] = &nfs_version4, #endif +#ifdef CONFIG_NFS_V4_1 + [(NFS_MAXVERSION + 1) + 4] = &nfs_version41, +#endif /* CONFIG_NFS_V4_1 */ }; struct rpc_program nfs_program = { .name = "nfs", .number = NFS_PROGRAM, - .nrvers =ARRAY_SIZE (nfs_version), + .nrvers = NFS_MAXVERSION + 1, + .nrminorvers = NFS4_MAX_MINOR_VERSION + 1, .version = nfs_version, .stats = &nfs_rpcstat, .pipe_dir_name = "/nfs",
@@ -482,6 +489,9 @@ static int nfs_create_rpc_client(struct nfs_client *clp, .servername = clp->cl_hostname, .program = &nfs_program, .version = clp->rpc_ops->version, +#ifdef CONFIG_NFS_V4 + .minorversion = clp->cl_minorversion, +#endif /* CONFIG_NFS_V4 */ .authflavor = flavor, .flags = flags, };
@@ -550,7 +560,7 @@ static void nfs_init_server_aclclient(struct nfs_server *server)if (server->flags &NFS_MOUNT_NOACL ) goto out_noacl; - server->client_acl =rpc_bind_new_program (server->client, &nfsacl_program,3 ); + server->client_acl =rpc_bind_new_program (server->client, &nfsacl_program,3 ,0 );if (IS_ERR (server->client_acl)) goto out_noacl;
@@ -970,6 +980,7 @@ static int nfs4_init_client(struct nfs_client *clp, {int error; +dprintk ("--> nfs4_init_client minorversion %u\n" , clp->cl_minorversion);if (clp->cl_cons_state ==NFS_CS_READY ) {/* the client is initialised already */ dprintk ("<-- nfs4_init_client() = 0 [already %p]\n" , clp);
include/linux/nfs_xdr.h +3 -0
@@ -975,6 +975,9 @@ extern struct rpc_procinfo *nfs4_minorversion_procedures[];extern struct rpc_version nfs_version2;extern struct rpc_version nfs_version3;extern struct rpc_version nfs_version4; +#if defined(CONFIG_NFS_V4_1 ) +extern struct rpc_version nfs_version41; +#endif /* CONFIG_NFS_V4_1 */ extern struct rpc_version nfsacl_version3;extern struct rpc_program nfsacl_program;
include/linux/sunrpc/clnt.h +9 -1
@@ -68,11 +68,18 @@ struct rpc_program {char * name;/* protocol name */ u32 number;/* program number */ unsigned int nrvers;/* number of versions */ +unsigned int nrminorvers;/* number of minor versions */ struct rpc_version ** version;/* version array */ struct rpc_stat * stats;/* statistics */ char * pipe_dir_name;/* path to rpc_pipefs dir */ }; +static inline struct rpc_version * +get_rpc_version (struct rpc_program *prog,u32 vers,int minorvers) +{ +return prog->version[minorvers * prog->nrvers + vers]; +} +struct rpc_version {u32 number;/* version number */ unsigned int nrprocs;/* number of procs */
@@ -106,6 +113,7 @@ struct rpc_create_args {struct rpc_program *program;u32 prognumber;/* overrides program->number */ u32 version; +unsigned char minorversion;rpc_authflavor_t authflavor;unsigned long flags; };
@@ -120,7 +128,7 @@ struct rpc_create_args {struct rpc_clnt *rpc_create (struct rpc_create_args *args);struct rpc_clnt *rpc_bind_new_program (struct rpc_clnt *, -struct rpc_program *,u32 ); +struct rpc_program *,u32 ,int minorversion);struct rpc_clnt *rpc_clone_client (struct rpc_clnt *);void rpc_shutdown_client (struct rpc_clnt *);void rpc_release_client (struct rpc_clnt *);
net/sunrpc/clnt.c +8 -5
@@ -148,9 +148,10 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struif (!xprt) goto out_no_xprt; -if (args->version >= program->nrvers) +if (args->version >= program->nrvers || + (args->minorversion && args->minorversion >= program->nrminorvers)) goto out_err; - version = program->version[args->version]; + version =get_rpc_version (program, args->version, args->minorversion);if (version ==NULL ) goto out_err;
@@ -472,14 +473,16 @@ rpc_release_client(struct rpc_clnt *clnt)*/ struct rpc_clnt *rpc_bind_new_program (struct rpc_clnt *old,struct rpc_program *program, -u32 vers) +u32 vers,int minorversion) {struct rpc_clnt *clnt;struct rpc_version *version;int err; -BUG_ON (vers >= program->nrvers || !program->version[vers]); - version = program->version[vers]; +BUG_ON (vers >= program->nrvers || + (minorversion && minorversion >= program->nrminorvers) || + !get_rpc_version (program, vers, minorversion)); + version =get_rpc_version (program, vers, minorversion); clnt =rpc_clone_client (old);if (IS_ERR (clnt)) goto out;
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 14/85] nfs41: sunrpc: support minorversion for rpc_clnt version table.
Quoted 6 lines · Benny Halevy
Validate minorversion only if not zero as legacy code declares nrminorvers==0 and that should work just fine with minorversion==0 argument.
Pass minorversion down to
rpc_createinnfs_create_rpc_clientSigned-off-by Benny Halevy <[email protected]>
review 11-14: patch will be dropped.
Quoted 159 lines
--- fs/nfs/client.c | 17 ++++++++++++++--- include/linux/nfs_xdr.h | 3 +++ include/linux/sunrpc/clnt.h | 10 +++++++++- net/sunrpc/clnt.c | 13 ++++++++----- 4 files changed, 34 insertions(+), 9 deletions(-)fs/nfs/client.c +14
-3@@ -56,7 +56,10 @@ static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);/* * RPC cruft for NFS */ -static struct rpc_version *nfs_version[5 ] = { +#define NFS_MAXVERSION 4 + +static struct rpc_version *nfs_version[(NFS_MAXVERSION +1 ) * + (NFS4_MAX_MINOR_VERSION +1 )] = { [2 ] = &nfs_version2, #ifdef CONFIG_NFS_V3 [3] = &nfs_version3,@@ -64,12 +67,16 @@ static struct rpc_version *nfs_version[5] = { #ifdef CONFIG_NFS_V4 [4] = &nfs_version4, #endif +#ifdef CONFIG_NFS_V4_1 + [(NFS_MAXVERSION + 1) + 4] = &nfs_version41, +#endif /* CONFIG_NFS_V4_1 */ }; struct rpc_program nfs_program = { .name = "nfs", .number = NFS_PROGRAM, - .nrvers =ARRAY_SIZE (nfs_version), + .nrvers = NFS_MAXVERSION + 1, + .nrminorvers = NFS4_MAX_MINOR_VERSION + 1, .version = nfs_version, .stats = &nfs_rpcstat, .pipe_dir_name = "/nfs",@@ -482,6 +489,9 @@ static int nfs_create_rpc_client(struct nfs_client *clp, .servername = clp->cl_hostname, .program = &nfs_program, .version = clp->rpc_ops->version, +#ifdef CONFIG_NFS_V4 + .minorversion = clp->cl_minorversion, +#endif /* CONFIG_NFS_V4 */ .authflavor = flavor, .flags = flags, };@@ -550,7 +560,7 @@ static void nfs_init_server_aclclient(struct nfs_server *server)if (server->flags &NFS_MOUNT_NOACL ) goto out_noacl; - server->client_acl =rpc_bind_new_program (server->client, &nfsacl_program,3 ); + server->client_acl =rpc_bind_new_program (server->client, &nfsacl_program,3 ,0 );if (IS_ERR (server->client_acl)) goto out_noacl;@@ -970,6 +980,7 @@ static int nfs4_init_client(struct nfs_client *clp, {int error; +dprintk ("--> nfs4_init_client minorversion %u\n" , clp->cl_minorversion);if (clp->cl_cons_state ==NFS_CS_READY ) {/* the client is initialised already */ dprintk ("<-- nfs4_init_client() = 0 [already %p]\n" , clp);include/linux/nfs_xdr.h +3
-0@@ -975,6 +975,9 @@ extern struct rpc_procinfo *nfs4_minorversion_procedures[];extern struct rpc_version nfs_version2;extern struct rpc_version nfs_version3;extern struct rpc_version nfs_version4; +#if defined(CONFIG_NFS_V4_1 ) +extern struct rpc_version nfs_version41; +#endif /* CONFIG_NFS_V4_1 */ extern struct rpc_version nfsacl_version3;extern struct rpc_program nfsacl_program;include/linux/sunrpc/clnt.h +9
-1@@ -68,11 +68,18 @@ struct rpc_program {char * name;/* protocol name */ u32 number;/* program number */ unsigned int nrvers;/* number of versions */ +unsigned int nrminorvers;/* number of minor versions */ struct rpc_version ** version;/* version array */ struct rpc_stat * stats;/* statistics */ char * pipe_dir_name;/* path to rpc_pipefs dir */ }; +static inline struct rpc_version * +get_rpc_version (struct rpc_program *prog,u32 vers,int minorvers) +{ +return prog->version[minorvers * prog->nrvers + vers]; +} +struct rpc_version {u32 number;/* version number */ unsigned int nrprocs;/* number of procs */ @@ -106,6 +113,7 @@ struct rpc_create_args {struct rpc_program *program;u32 prognumber;/* overrides program->number */ u32 version; +unsigned char minorversion;rpc_authflavor_t authflavor;unsigned long flags; };@@ -120,7 +128,7 @@ struct rpc_create_args {struct rpc_clnt *rpc_create (struct rpc_create_args *args);struct rpc_clnt *rpc_bind_new_program (struct rpc_clnt *, -struct rpc_program *,u32 ); +struct rpc_program *,u32 ,int minorversion);struct rpc_clnt *rpc_clone_client (struct rpc_clnt *);void rpc_shutdown_client (struct rpc_clnt *);void rpc_release_client (struct rpc_clnt *);net/sunrpc/clnt.c +8
-5@@ -148,9 +148,10 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struif (!xprt) goto out_no_xprt; -if (args->version >= program->nrvers) +if (args->version >= program->nrvers || + (args->minorversion && args->minorversion >= program->nrminorvers)) goto out_err; - version = program->version[args->version]; + version =get_rpc_version (program, args->version, args->minorversion);if (version ==NULL ) goto out_err;@@ -472,14 +473,16 @@ rpc_release_client(struct rpc_clnt *clnt)*/ struct rpc_clnt *rpc_bind_new_program (struct rpc_clnt *old,struct rpc_program *program, -u32 vers) +u32 vers,int minorversion) {struct rpc_clnt *clnt;struct rpc_version *version;int err; -BUG_ON (vers >= program->nrvers || !program->version[vers]); - version = program->version[vers]; +BUG_ON (vers >= program->nrvers || + (minorversion && minorversion >= program->nrminorvers) || + !get_rpc_version (program, vers, minorversion)); + version =get_rpc_version (program, vers, minorversion); clnt =rpc_clone_client (old);if (IS_ERR (clnt)) goto out;
RFC 15/85 nfs41: Proper initialization of nfs_client_initdata.rpc_ops
In reply to Benny HalevyFrom: Ricardo Labiaga <[email protected]>
The rpc_ops needs to be initialized to the proper minor version clientops so that nfs_get_client() can find an existing nfs_client structure if a mount to the same server has already occurred.
This enables the traditional sharing of nfs_client structures, as well as fixes the problem where mounts of the same filesystem on the same mountpoint were not being detected correctly.
--- fs/nfs/client.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
fs/nfs/client.c +2 -0
@@ -1028,6 +1028,8 @@ static int nfs4_set_client(struct nfs_server *server, .hostname = hostname, .addr = addr, .addrlen = addrlen, + .rpc_ops = + nfsv4_minorversion_clientops[server->minorversion], .proto = proto, };struct nfs_client *clp;
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 15/85] nfs41: Proper initialization of nfs_client_initdata.rpc_ops
Quoted 6 lines · Benny Halevy
From: Ricardo Labiaga <[email protected]>
The
rpc_opsneeds to be initialized to the proper minor version clientops so thatnfs_get_client()can find an existingnfs_clientstructure if a mount to the same server has already occurred.
Quoted 6 lines
This enables the traditional sharing of
nfs_clientstructures, as well as fixes the problem where mounts of the same filesystem on the same mountpoint were not being detected correctly.Signed-off-by Ricardo Labiaga <[email protected]>Signed-off-by Benny Halevy <[email protected]>
review 11-14: see if we can get rid of that since right now nfs_v41_clientops == nfs_v40_clientops
Quoted 17 lines
--- fs/nfs/client.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)fs/nfs/client.c +2
-0@@ -1028,6 +1028,8 @@ static int nfs4_set_client(struct nfs_server *server, .hostname = hostname, .addr = addr, .addrlen = addrlen, + .rpc_ops = + nfsv4_minorversion_clientops[server->minorversion], .proto = proto, };struct nfs_client *clp;
RFC 16/85 nfs41: pass recovery status from reclaimer kthread up to nfs4_wait_clnt_recover
In reply to Benny Halevystatus is cleared on recovery start and may be left as non-zero if recovery failed so it can be picked up by an upper layer caller (e.g. nfs4_create_server)
--- fs/nfs/nfs4proc.c | 2 ++ fs/nfs/nfs4state.c | 5 ++++- include/linux/nfs_fs_sb.h | 1 + 3 files changed, 7 insertions(+), 1 deletions(-)
fs/nfs/nfs4proc.c +2 -0
@@ -2802,6 +2802,8 @@ static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp) res =wait_on_bit (&clp->cl_state,NFS4CLNT_STATE_RECOVER , nfs4_wait_bit_killable,TASK_KILLABLE ); +if (!res) + res = clp->cl_recovery_status;rwsem_release (&clp->cl_sem.dep_map,1 , _RET_IP_);return res;
fs/nfs/nfs4state.c +4 -1
@@ -814,8 +814,10 @@ void nfs4_schedule_state_recovery(struct nfs_client *clp) {if (!clp)return ; -if (test_and_set_bit (NFS4CLNT_STATE_RECOVER , &clp->cl_state) ==0 ) +if (test_and_set_bit (NFS4CLNT_STATE_RECOVER , &clp->cl_state) ==0 ) { + clp->cl_recovery_status =0 ;nfs4_recover_state (clp); + } }static int nfs4_reclaim_locks (struct nfs4_state_recovery_ops *ops,struct nfs4_state *state)
@@ -1018,6 +1020,7 @@ out: out_error:printk (KERN_WARNING "Error: state recovery failed on NFSv4 server %s" " with error %d\n" , clp->cl_hostname, -status); + clp->cl_recovery_status = status;set_bit (NFS4CLNT_LEASE_EXPIRED , &clp->cl_state); goto out; }
include/linux/nfs_fs_sb.h +1 -0
@@ -38,6 +38,7 @@ struct nfs_client {u64 cl_clientid;/* constant */ nfs4_verifier cl_confirm;unsigned long cl_state; +int cl_recovery_status;struct rb_root cl_openowner_id;struct rb_root cl_lockowner_id;
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 16/85] nfs41: pass recovery status from reclaimer kthread up to nfs4_wait_clnt_recover
Quoted 5 lines · Benny Halevy
status is cleared on recovery start and may be left as non-zero if recovery failed so it can be picked up by an upper layer caller (e.g.
nfs4_create_server)Signed-off-by Benny Halevy <[email protected]>
review 11-14: let the reclaimer fallback to lower minorversion and drop this patch.
Quoted 55 lines
--- fs/nfs/nfs4proc.c | 2 ++ fs/nfs/nfs4state.c | 5 ++++- include/linux/nfs_fs_sb.h | 1 + 3 files changed, 7 insertions(+), 1 deletions(-)fs/nfs/nfs4proc.c +2
-0@@ -2802,6 +2802,8 @@ static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp) res =wait_on_bit (&clp->cl_state,NFS4CLNT_STATE_RECOVER , nfs4_wait_bit_killable,TASK_KILLABLE ); +if (!res) + res = clp->cl_recovery_status;rwsem_release (&clp->cl_sem.dep_map,1 , _RET_IP_);return res;fs/nfs/nfs4state.c +4
-1@@ -814,8 +814,10 @@ void nfs4_schedule_state_recovery(struct nfs_client *clp) {if (!clp)return ; -if (test_and_set_bit (NFS4CLNT_STATE_RECOVER , &clp->cl_state) ==0 ) +if (test_and_set_bit (NFS4CLNT_STATE_RECOVER , &clp->cl_state) ==0 ) { + clp->cl_recovery_status =0 ;nfs4_recover_state (clp); + } }static int nfs4_reclaim_locks (struct nfs4_state_recovery_ops *ops,struct nfs4_state *state)@@ -1018,6 +1020,7 @@ out: out_error:printk (KERN_WARNING "Error: state recovery failed on NFSv4 server %s" " with error %d\n" , clp->cl_hostname, -status); + clp->cl_recovery_status = status;set_bit (NFS4CLNT_LEASE_EXPIRED , &clp->cl_state); goto out; }include/linux/nfs_fs_sb.h +1
-0@@ -38,6 +38,7 @@ struct nfs_client {u64 cl_clientid;/* constant */ nfs4_verifier cl_confirm;unsigned long cl_state; +int cl_recovery_status;struct rb_root cl_openowner_id;struct rb_root cl_lockowner_id;
RFC 17/85 nfs41: fallback to lower minorversion if nfs4_create_server fails
In reply to Benny Halevyretry nfs4_create_server with lower minorversion on minorvers_mismatch error
--- fs/nfs/client.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-)
fs/nfs/client.c +11 -1
@@ -1118,15 +1118,17 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, {struct nfs_fattr fattr;struct nfs_server *server; +int minorvers = data->minorversion;int error;dprintk ("--> nfs4_create_server()\n" ); +retry: server =nfs_alloc_server ();if (!server)return ERR_PTR (-ENOMEM ); - server->minorversion = data->minorversion; + server->minorversion = minorvers;/* set up the general RPC client */ error =nfs4_init_server (server, data);
@@ -1168,7 +1170,15 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,return server; error: +if (server->nfs_client && server->nfs_client->cl_recovery_status) + error = server->nfs_client->cl_recovery_status;nfs_free_server (server); +if (minorvers >0 && error == -NFS4ERR_MINOR_VERS_MISMATCH ) { + minorvers--; +dprintk ("%s: error %d retrying with minorvers=%d\n" , + __func__, error, minorvers); + goto retry; + }dprintk ("<-- nfs4_create_server() = error %d\n" , error);return ERR_PTR (error); }
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 17/85] nfs41: fallback to lower minorversion if nfs4_create_server fails
Quoted 3 lines · Benny Halevy
retry
nfs4_create_serverwith lower minorversion onminorvers_mismatcherrorSigned-off-by Benny Halevy <[email protected]>
review 11-14: move logic to reclaimer();
Quoted 43 lines
--- fs/nfs/client.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-)fs/nfs/client.c +11
-1@@ -1118,15 +1118,17 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, {struct nfs_fattr fattr;struct nfs_server *server; +int minorvers = data->minorversion;int error;dprintk ("--> nfs4_create_server()\n" ); +retry: server =nfs_alloc_server ();if (!server)return ERR_PTR (-ENOMEM ); - server->minorversion = data->minorversion; + server->minorversion = minorvers;/* set up the general RPC client */ error =nfs4_init_server (server, data);@@ -1168,7 +1170,15 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,return server; error: +if (server->nfs_client && server->nfs_client->cl_recovery_status) + error = server->nfs_client->cl_recovery_status;nfs_free_server (server); +if (minorvers >0 && error == -NFS4ERR_MINOR_VERS_MISMATCH ) { + minorvers--; +dprintk ("%s: error %d retrying with minorvers=%d\n" , + __func__, error, minorvers); + goto retry; + }dprintk ("<-- nfs4_create_server() = error %d\n" , error);return ERR_PTR (error); }
RFC 18/85 nfs41: sessions client infrastructure
In reply to Benny HalevyFrom: Andy Adamson <[email protected]>
NFSv4.1 Sessions basic data types, initialization, and destruction.
The session is always associated with a struct nfs_client that holds the exchange_id results. Add an nfs_client struct backpointer to the session and refactor the session recovery routines to only require a struct nfs4_sessions parameter.
--- fs/nfs/client.c | 40 +++++++++++++++++++++++++++++++++++++ fs/nfs/internal.h | 1 + fs/nfs/nfs4_fs.h | 4 +++ fs/nfs/nfs4proc.c | 35 ++++++++++++++++++++++++++++++++ include/linux/nfs4_session.h | 45 ++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs_fs_sb.h | 5 ++++ 6 files changed, 130 insertions(+), 0 deletions(-) create mode 100644 include/linux/nfs4_session.h
fs/nfs/client.c +40 -0
@@ -37,6 +37,9 @@#include <linux/in6.h> #include <net/ipv6.h> #include <linux/nfs_xdr.h> +#if defined(CONFIG_NFS_V4_1 ) +#include <linux/nfs4_session.h> +#endif /* CONFIG_NFS_V4_1 */ #include <asm/system.h>
@@ -884,6 +887,11 @@ void nfs_free_server(struct nfs_server *server)list_del (&server->master_link);spin_unlock (&nfs_client_lock); +#ifdef CONFIG_NFS_V4_1 +if (server->nfs_client->cl_session !=NULL ) +nfs4_put_session (&server->nfs_client->cl_session); +#endif /* CONFIG_NFS_V4_1 */ +if (server->destroy !=NULL ) server->destroy (server);
@@ -1110,6 +1118,34 @@ error: }/* +* Allocate and initialize a session if required +*/ +int nfs4_init_session (struct nfs_client *clp,struct rpc_clnt *clnt) +{ +int error =0 ; + +#if defined(CONFIG_NFS_V4_1 ) +if (clp->cl_minorversion) { +struct nfs4_session *session =NULL ; +/* +* Create the session and mark it expired. +* When a SEQUENCE operation encounters the expired session +* it will do session recovery to initialize it. +*/ + session =nfs4_alloc_session (); +if (!session) + error = -ENOMEM ; +else { + session->clnt = clnt; + session->clp = clp; + } + clp->cl_session = session; + } +#endif /* CONFIG_NFS_V4_1 */ +return error; +} + +/* * Create a version 4 volume record * - keyed on server and FSID */
@@ -1139,6 +1175,10 @@ retry:BUG_ON (!server->nfs_client->rpc_ops);BUG_ON (!server->nfs_client->rpc_ops->file_inode_ops); + error =nfs4_init_session (server->nfs_client, server->client); +if (error) + goto error; +/* Probe the root fh to retrieve its FSID */ error =nfs4_path_walk (server, mntfh, data->nfs_server.export_path);if (error <0 )
fs/nfs/internal.h +1 -0
@@ -82,6 +82,7 @@ extern void nfs_free_server(struct nfs_server *server);extern struct nfs_server *nfs_clone_server (struct nfs_server *,struct nfs_fh *,struct nfs_fattr *); +extern int nfs4_init_session (struct nfs_client *clp,struct rpc_clnt *clnt);#ifdef CONFIG_PROC_FS extern int __init nfs_fs_proc_init (void );extern void nfs_fs_proc_exit (void );
fs/nfs/nfs4_fs.h +4 -0
@@ -188,6 +188,10 @@ extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops; +#if defined(CONFIG_NFS_V4_1 ) +extern void nfs4_put_session (struct nfs4_session **session); +extern struct nfs4_session *nfs4_alloc_session (void ); +#endif /* CONFIG_NFS_V4_1 */ extern const u32 nfs4_fattr_bitmap[2 ];extern const u32 nfs4_statfs_bitmap[2 ];
fs/nfs/nfs4proc.c +35 -0
@@ -53,6 +53,9 @@#include "delegation.h" #include "internal.h" #include "iostat.h" +#if defined(CONFIG_NFS_V4_1 ) +#include <linux/nfs4_session.h> +#endif /* CONFIG_NFS_V4_1 */ #define NFSDBG_FACILITY NFSDBG_PROC
@@ -3679,6 +3682,38 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,return status; } +#ifdef CONFIG_NFS_V4_1 +struct nfs4_session *nfs4_alloc_session (void ) +{ +struct nfs4_session *session; + + session =kzalloc (sizeof (struct nfs4_session ),GFP_ATOMIC ); +if (!session) +return NULL ; + +atomic_set (&session->ref_count,1 ); + +return session; +} + +static void nfs4_free_session (struct nfs4_session *session) +{ +dprintk ("%s: freeing session %p\n" , __func__, session); +kfree (session); +} + +void nfs4_put_session (struct nfs4_session **session) +{ +dprintk ("--> nfs4_put_session()\n" ); +if (atomic_dec_and_test (&((*session)->ref_count))) { +nfs4_free_session (*session); + *session =NULL ; + } +dprintk ("<-- nfs4_put_session()\n" ); +} + +#endif /* CONFIG_NFS_V4_1 */ +struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = { .recover_open = nfs4_open_reclaim, .recover_lock = nfs4_lock_reclaim,
include/linux/nfs4_session.h new file +45 -0
45 lines not on this page · raw message
include/linux/nfs_fs_sb.h +5 -0
@@ -7,6 +7,7 @@#include <asm/atomic.h> +struct nfs4_session ;struct nfs_iostats ;struct nlm_host ;
@@ -72,6 +73,10 @@ struct nfs_client {unsigned char cl_id_uniquifier;u32 cl_minorversion;#endif /* CONFIG_NFS_V4 */ + +#ifdef CONFIG_NFS_V4_1 +struct nfs4_session *cl_session;/* sharred session */ +#endif /* CONFIG_NFS_V4_1 */ };#ifdef CONFIG_NFS_V4
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 18/85] nfs41: sessions client infrastructure
Quoted 150 lines · Benny Halevy
From: Andy Adamson <[email protected]>
NFSv4.1 Sessions basic data types, initialization, and destruction.
The session is always associated with a struct
nfs_clientthat holds theexchange_idresults. Add annfs_clientstruct backpointer to the session and refactor the session recovery routines to only require a structnfs4_sessionsparameter.Signed-off-by Rahul Iyer <[email protected]>Signed-off-by Andy Adamson<[email protected]>Signed-off-by Benny Halevy <[email protected]>--- fs/nfs/client.c | 40 +++++++++++++++++++++++++++++++++++++ fs/nfs/internal.h | 1 + fs/nfs/nfs4_fs.h | 4 +++ fs/nfs/nfs4proc.c | 35 ++++++++++++++++++++++++++++++++ include/linux/nfs4_session.h | 45 ++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs_fs_sb.h | 5 ++++ 6 files changed, 130 insertions(+), 0 deletions(-) create mode 100644 include/linux/nfs4_session.hfs/nfs/client.c +40
-0@@ -37,6 +37,9 @@#include <linux/in6.h> #include <net/ipv6.h> #include <linux/nfs_xdr.h> +#if defined(CONFIG_NFS_V4_1 ) +#include <linux/nfs4_session.h> +#endif /* CONFIG_NFS_V4_1 */ #include <asm/system.h> @@ -884,6 +887,11 @@ void nfs_free_server(struct nfs_server *server)list_del (&server->master_link);spin_unlock (&nfs_client_lock); +#ifdef CONFIG_NFS_V4_1 +if (server->nfs_client->cl_session !=NULL ) +nfs4_put_session (&server->nfs_client->cl_session); +#endif /* CONFIG_NFS_V4_1 */ +if (server->destroy !=NULL ) server->destroy (server);@@ -1110,6 +1118,34 @@ error: }/* +* Allocate and initialize a session if required +*/ +int nfs4_init_session (struct nfs_client *clp,struct rpc_clnt *clnt) +{ +int error =0 ; + +#if defined(CONFIG_NFS_V4_1 ) +if (clp->cl_minorversion) { +struct nfs4_session *session =NULL ; +/* +* Create the session and mark it expired. +* When a SEQUENCE operation encounters the expired session +* it will do session recovery to initialize it. +*/ + session =nfs4_alloc_session (); +if (!session) + error = -ENOMEM ; +else { + session->clnt = clnt; + session->clp = clp; + } + clp->cl_session = session; + } +#endif /* CONFIG_NFS_V4_1 */ +return error; +} + +/* * Create a version 4 volume record * - keyed on server and FSID */ @@ -1139,6 +1175,10 @@ retry:BUG_ON (!server->nfs_client->rpc_ops);BUG_ON (!server->nfs_client->rpc_ops->file_inode_ops); + error =nfs4_init_session (server->nfs_client, server->client); +if (error) + goto error; +/* Probe the root fh to retrieve its FSID */ error =nfs4_path_walk (server, mntfh, data->nfs_server.export_path);if (error <0 )fs/nfs/internal.h +1
-0@@ -82,6 +82,7 @@ extern void nfs_free_server(struct nfs_server *server);extern struct nfs_server *nfs_clone_server (struct nfs_server *,struct nfs_fh *,struct nfs_fattr *); +extern int nfs4_init_session (struct nfs_client *clp,struct rpc_clnt *clnt);#ifdef CONFIG_PROC_FS extern int __init nfs_fs_proc_init (void );extern void nfs_fs_proc_exit (void );fs/nfs/nfs4_fs.h +4
-0@@ -188,6 +188,10 @@ extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops; +#if defined(CONFIG_NFS_V4_1 ) +extern void nfs4_put_session (struct nfs4_session **session); +extern struct nfs4_session *nfs4_alloc_session (void ); +#endif /* CONFIG_NFS_V4_1 */ extern const u32 nfs4_fattr_bitmap[2 ];extern const u32 nfs4_statfs_bitmap[2 ];fs/nfs/nfs4proc.c +14
-0@@ -53,6 +53,9 @@#include "delegation.h" #include "internal.h" #include "iostat.h" +#if defined(CONFIG_NFS_V4_1 ) +#include <linux/nfs4_session.h> +#endif /* CONFIG_NFS_V4_1 */ #define NFSDBG_FACILITY NFSDBG_PROC@@ -3679,6 +3682,38 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,return status; } +#ifdef CONFIG_NFS_V4_1 +struct nfs4_session *nfs4_alloc_session (void ) +{ +struct nfs4_session *session; + + session =kzalloc (sizeof (struct nfs4_session ),GFP_ATOMIC ); +if (!session) +return NULL ; + +atomic_set (&session->ref_count,1 ); +
fs/nfs/nfs4proc.c int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, · line 3705
Quoted 10 lines
fs/nfs/nfs4proc.c +10
-0+return session; +} + +static void nfs4_free_session (struct nfs4_session *session) +{ +dprintk ("%s: freeing session %p\n" , __func__, session); +kfree (session); +} + +void nfs4_put_session (struct nfs4_session **session)
review 11-14: pass a struct nfs4_session* (not **) do not set *session to NULL
include/linux/nfs4_session.h
Quoted 19 lines
fs/nfs/nfs4proc.c +11
-0+{ +dprintk ("--> nfs4_put_session()\n" ); +if (atomic_dec_and_test (&((*session)->ref_count))) { +nfs4_free_session (*session); + *session =NULL ; + } +dprintk ("<-- nfs4_put_session()\n" ); +} + +#endif /* CONFIG_NFS_V4_1 */ +struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = { .recover_open = nfs4_open_reclaim, .recover_lock = nfs4_lock_reclaim,include/linux/nfs4_session.h new file +0
-0
review 11-14: move to fs/nfs/nfs4_fs.h
Quoted 8 lines
include/linux/nfs4_session.h new file +7
-0@@ -0,0 +1,45 @@ +#ifndef _NFS4_SESSIONS_H +#define _NFS4_SESSIONS_H + +#if defined(CONFIG_NFS_V4_1 ) + +#include <linux/nfs4.h> +#include <linux/smp_lock.h>
include/linux/nfs4_session.h line 17
Quoted 10 lines
include/linux/nfs4_session.h new file +10
-0+#include <linux/sunrpc/sched.h> + +struct nfs4_channel_attrs { +u32 headerpadsz; +u32 max_rqst_sz; +u32 max_resp_sz; +u32 max_resp_sz_cached; +u32 max_ops; +u32 max_reqs; +u32 rdma_attrs;
review 11-14: weed out unused fields
include/linux/nfs4_session.h line 22
Quoted 5 lines
include/linux/nfs4_session.h new file +5
-0+}; + +struct nfs4_channel { +struct nfs4_channel_attrs chan_attrs; +struct rpc_clnt *rpc_client;
review 11-14: unused, no need for this struct
include/linux/nfs4_session.h line 30
Quoted 8 lines
include/linux/nfs4_session.h new file +8
-0+}; + +/* +* Session related parameters +*/ +struct nfs4_session { +nfs41_sessionid sess_id; +u32 flags;
review 11-14: remove until used
include/linux/nfs4_session.h line 33
Quoted 3 lines
include/linux/nfs4_session.h new file +3
-0+unsigned long session_state; +u32 hash_alg; +u32 ssv_len;
review 11-14: take these out for now.
include/linux/nfs4_session.h line 36
Quoted 3 lines
include/linux/nfs4_session.h new file +3
-0+ +/* The fore and back channel */ +struct nfs4_channel fore_channel;
review 11-14: s/nfs4_channel/nfs4_channel_attrs/
include/linux/nfs4_session.h line 40
Quoted 4 lines
include/linux/nfs4_session.h new file +4
-0+struct nfs4_channel back_channel; + +atomic_t ref_count; +struct rpc_clnt *clnt;
review 11-14: use clp->cl_rpcclient instead
Quoted 28 lines
include/linux/nfs4_session.h new file +5
-0+struct nfs_client *clp; +}; + +#endif /* CONFIG_NFS_V4_1 */ +#endif include/linux/nfs_fs_sb.h +5
-0@@ -7,6 +7,7 @@#include <asm/atomic.h> +struct nfs4_session ;struct nfs_iostats ;struct nlm_host ;@@ -72,6 +73,10 @@ struct nfs_client {unsigned char cl_id_uniquifier;u32 cl_minorversion;#endif /* CONFIG_NFS_V4 */ + +#ifdef CONFIG_NFS_V4_1 +struct nfs4_session *cl_session;/* sharred session */ +#endif /* CONFIG_NFS_V4_1 */ };#ifdef CONFIG_NFS_V4
RFC 19/85 nfs41: share client sessions across mounts
In reply to Benny HalevyFrom: Andy Adamson <[email protected]>
Do not create a new session for each new mount (FSID).
Call nfs4_get_session to bump the reference count for each cloned nfs4 server which now share the struct nfs_client session.
nfs41: check minorversion on nfs41_get_session
--- fs/nfs/client.c | 4 ++++ fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4proc.c | 5 +++++ 3 files changed, 10 insertions(+), 0 deletions(-)
fs/nfs/client.c +4 -0
@@ -1336,6 +1336,10 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,if (!IS_ERR (source->client_acl))nfs_init_server_aclclient (server); +#ifdef CONFIG_NFS_V4_1 +nfs4_get_session (server->nfs_client); +#endif /* CONFIG_NFS_V4_1 */ +/* probe the filesystem info for this server filesystem */ error =nfs_probe_fsinfo (server, fh, &fattr_fsinfo);if (error <0 )
fs/nfs/nfs4_fs.h +1 -0
@@ -190,6 +190,7 @@ extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;#if defined(CONFIG_NFS_V4_1 )extern void nfs4_put_session (struct nfs4_session **session); +extern void nfs4_get_session (struct nfs_client *clp);extern struct nfs4_session *nfs4_alloc_session (void );#endif /* CONFIG_NFS_V4_1 */
fs/nfs/nfs4proc.c +5 -0
@@ -3712,6 +3712,11 @@ void nfs4_put_session(struct nfs4_session **session)dprintk ("<-- nfs4_put_session()\n" ); } +void nfs4_get_session (struct nfs_client *clp) +{ +if (clp->cl_minorversion ==1 ) +atomic_inc (&clp->cl_session->ref_count); +}#endif /* CONFIG_NFS_V4_1 */ struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 19/85] nfs41: share client sessions across mounts
Quoted 22 lines · Benny Halevy
From: Andy Adamson <[email protected]>
Do not create a new session for each new mount (FSID).
Call
nfs4_get_sessionto bump the reference count for each cloned nfs4 server which now share the structnfs_clientsession.nfs41: check minorversion on
nfs41_get_sessionSigned-off-by Andy Adamson<[email protected]>Signed-off-by Benny Halevy <[email protected]>--- fs/nfs/client.c | 4 ++++ fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4proc.c | 5 +++++ 3 files changed, 10 insertions(+), 0 deletions(-)fs/nfs/client.c +0
-0
fs/nfs/client.c struct nfs_server *nfs_clone_server(struct nfs_server *source, · line 1339
Quoted 4 lines
fs/nfs/client.c +1
-0@@ -1336,6 +1336,10 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,if (!IS_ERR (source->client_acl))nfs_init_server_aclclient (server); +#ifdef CONFIG_NFS_V4_1
review 11-14: check for clp->cl_session != NULL
Quoted 23 lines
fs/nfs/client.c +3
-0+nfs4_get_session (server->nfs_client); +#endif /* CONFIG_NFS_V4_1 */ +/* probe the filesystem info for this server filesystem */ error =nfs_probe_fsinfo (server, fh, &fattr_fsinfo);if (error <0 )fs/nfs/nfs4_fs.h +1
-0@@ -190,6 +190,7 @@ extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;#if defined(CONFIG_NFS_V4_1 )extern void nfs4_put_session (struct nfs4_session **session); +extern void nfs4_get_session (struct nfs_client *clp);extern struct nfs4_session *nfs4_alloc_session (void );#endif /* CONFIG_NFS_V4_1 */ fs/nfs/nfs4proc.c +0
-0
fs/nfs/nfs4proc.c void nfs4_put_session(struct nfs4_session **session) · line 3715
Quoted 4 lines
fs/nfs/nfs4proc.c +1
-0@@ -3712,6 +3712,11 @@ void nfs4_put_session(struct nfs4_session **session)dprintk ("<-- nfs4_put_session()\n" ); } +void nfs4_get_session (struct nfs_client *clp)
review 11-14: just pass a session*
Quoted 7 lines
fs/nfs/nfs4proc.c +4
-0+{ +if (clp->cl_minorversion ==1 ) +atomic_inc (&clp->cl_session->ref_count); +}#endif /* CONFIG_NFS_V4_1 */ struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
RFC 20/85 nfs41: slot table init and destroy
In reply to Benny HalevyCode to initialize and destroy the slot table.
Uses bitmap-based allocation.
--- fs/nfs/nfs4proc.c | 88 ++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs4_session.h | 17 ++++++++ 2 files changed, 105 insertions(+), 0 deletions(-)
fs/nfs/nfs4proc.c +88 -0
@@ -3683,6 +3683,92 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, }#ifdef CONFIG_NFS_V4_1 +/* +* Initialize slot table +* +* Note: the "used" bitmap points to _used_slots id max_slots <= BITS_PER_LONG. +* Otherwise, we dynamically allocate enough ulongs to hold max_slots bits. +*/ +static int nfs4_init_slot_table (struct nfs4_channel *channel) +{ +struct nfs4_slot_table *tbl = &channel->slot_table; +int i, max_slots = channel->chan_attrs.max_reqs; +struct nfs4_slot *slot; +unsigned long *used; +int ret = -ENOMEM ; + +dprintk ("--> %s: max_reqs=%u\n" , __func__, + channel->chan_attrs.max_reqs); + slot =kzalloc (max_slots *sizeof (struct nfs4_slot ),GFP_ATOMIC ); +if (!slot) + goto out; +for (i =0 ; i < max_slots; ++i) + slot[i].seq_nr =1 ; + +if (max_slots <=BITS_PER_LONG ) + used = &tbl->_used_slots;/* use word in tbl */ +else { +/* allocate enough unsigned longs for max_slots bits */ + used =kzalloc (sizeof (unsigned long ) * +DIV_ROUND_UP (max_slots,BITS_PER_LONG ), +GFP_ATOMIC ); +if (!used) + goto out_free; + } + ret =0 ; + +spin_lock (&tbl->slot_tbl_lock); +if (tbl->slots !=NULL ) { +spin_unlock (&tbl->slot_tbl_lock); +dprintk ("%s: slot table already initialized. tbl=%p slots=%p\n" , + __func__, tbl, tbl->slots); +WARN_ON (1 ); + goto out_free; + } + tbl->max_slots = max_slots; + tbl->slots = slot; + tbl->used_slots = used; + tbl->lowest_free_slotid =0 ;/* first slot is free */ + tbl->highest_used_slotid =-1 ;/* no slot is currently used */ +spin_unlock (&tbl->slot_tbl_lock); +dprintk ("%s: tbl=%p slots=%p max_slots=%d\n" , __func__, + tbl, tbl->slots, tbl->max_slots); +out: +dprintk ("<-- %s: return %d\n" , __func__, ret); +return ret; +out_free: +kfree (slot); +if (used != &tbl->_used_slots) +kfree (used); + goto out; +} + +/* Destroy the slot table */ +static void nfs4_destroy_slot_table (struct nfs4_channel *channel) +{ +if (channel->slot_table.slots ==NULL ) +return ; +kfree (channel->slot_table.slots); + channel->slot_table.slots =NULL ; +/* Was the "used" bitmap dynamically allocated? */ +if (channel->slot_table.used_slots != &channel->slot_table._used_slots) +kfree (channel->slot_table.used_slots); + +return ; +} + +static int nfs4_init_channel (struct nfs4_channel *channel) +{ +struct nfs4_slot_table *tbl; + + tbl = &channel->slot_table; + +spin_lock_init (&tbl->slot_tbl_lock); +rpc_init_wait_queue (&tbl->slot_tbl_waitq,"Slot table" ); + +return 0 ; +} +struct nfs4_session *nfs4_alloc_session (void ) {struct nfs4_session *session;
@@ -3693,6 +3779,7 @@ struct nfs4_session *nfs4_alloc_session(void)atomic_set (&session->ref_count,1 ); +nfs4_init_channel (&session->fore_channel);return session; }
@@ -3706,6 +3793,7 @@ void nfs4_put_session(struct nfs4_session **session) {dprintk ("--> nfs4_put_session()\n" );if (atomic_dec_and_test (&((*session)->ref_count))) { +nfs4_destroy_slot_table (&((*session)->fore_channel));nfs4_free_session (*session); *session =NULL ; }
include/linux/nfs4_session.h +17 -0
@@ -17,9 +17,26 @@ struct nfs4_channel_attrs {u32 rdma_attrs; }; +struct nfs4_slot { +u32 seq_nr; +}; + +struct nfs4_slot_table { +struct nfs4_slot *slots;/* seqid per slot */ +unsigned long *used_slots;/* used/unused bitmap */ +unsigned long _used_slots;/* used when max_slots fits */ +spinlock_t slot_tbl_lock; +struct rpc_wait_queue slot_tbl_waitq;/* allocators may wait here */ +int max_slots;/* # slots in table */ +int lowest_free_slotid;/* lower bound hint */ +int highest_used_slotid;/* sent to server on each SEQ. +* op for dynamic resizing */ +}; +struct nfs4_channel {struct nfs4_channel_attrs chan_attrs;struct rpc_clnt *rpc_client; +struct nfs4_slot_table slot_table; };/*
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 20/85] nfs41: slot table init and destroy
Quoted 129 lines · Benny Halevy
Code to initialize and destroy the slot table.
Uses bitmap-based allocation.Signed-off-by Andy Adamson<[email protected]>Signed-off-by Benny Halevy <[email protected]>--- fs/nfs/nfs4proc.c | 88 ++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs4_session.h | 17 ++++++++ 2 files changed, 105 insertions(+), 0 deletions(-)fs/nfs/nfs4proc.c +88
-0@@ -3683,6 +3683,92 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, }#ifdef CONFIG_NFS_V4_1 +/* +* Initialize slot table +* +* Note: the "used" bitmap points to _used_slots id max_slots <= BITS_PER_LONG. +* Otherwise, we dynamically allocate enough ulongs to hold max_slots bits. +*/ +static int nfs4_init_slot_table (struct nfs4_channel *channel) +{ +struct nfs4_slot_table *tbl = &channel->slot_table; +int i, max_slots = channel->chan_attrs.max_reqs; +struct nfs4_slot *slot; +unsigned long *used; +int ret = -ENOMEM ; + +dprintk ("--> %s: max_reqs=%u\n" , __func__, + channel->chan_attrs.max_reqs); + slot =kzalloc (max_slots *sizeof (struct nfs4_slot ),GFP_ATOMIC ); +if (!slot) + goto out; +for (i =0 ; i < max_slots; ++i) + slot[i].seq_nr =1 ; + +if (max_slots <=BITS_PER_LONG ) + used = &tbl->_used_slots;/* use word in tbl */ +else { +/* allocate enough unsigned longs for max_slots bits */ + used =kzalloc (sizeof (unsigned long ) * +DIV_ROUND_UP (max_slots,BITS_PER_LONG ), +GFP_ATOMIC ); +if (!used) + goto out_free; + } + ret =0 ; + +spin_lock (&tbl->slot_tbl_lock); +if (tbl->slots !=NULL ) { +spin_unlock (&tbl->slot_tbl_lock); +dprintk ("%s: slot table already initialized. tbl=%p slots=%p\n" , + __func__, tbl, tbl->slots); +WARN_ON (1 ); + goto out_free; + } + tbl->max_slots = max_slots; + tbl->slots = slot; + tbl->used_slots = used; + tbl->lowest_free_slotid =0 ;/* first slot is free */ + tbl->highest_used_slotid =-1 ;/* no slot is currently used */ +spin_unlock (&tbl->slot_tbl_lock); +dprintk ("%s: tbl=%p slots=%p max_slots=%d\n" , __func__, + tbl, tbl->slots, tbl->max_slots); +out: +dprintk ("<-- %s: return %d\n" , __func__, ret); +return ret; +out_free: +kfree (slot); +if (used != &tbl->_used_slots) +kfree (used); + goto out; +} + +/* Destroy the slot table */ +static void nfs4_destroy_slot_table (struct nfs4_channel *channel) +{ +if (channel->slot_table.slots ==NULL ) +return ; +kfree (channel->slot_table.slots); + channel->slot_table.slots =NULL ; +/* Was the "used" bitmap dynamically allocated? */ +if (channel->slot_table.used_slots != &channel->slot_table._used_slots) +kfree (channel->slot_table.used_slots); + +return ; +} + +static int nfs4_init_channel (struct nfs4_channel *channel) +{ +struct nfs4_slot_table *tbl; + + tbl = &channel->slot_table; + +spin_lock_init (&tbl->slot_tbl_lock); +rpc_init_wait_queue (&tbl->slot_tbl_waitq,"Slot table" ); + +return 0 ; +} +struct nfs4_session *nfs4_alloc_session (void ) {struct nfs4_session *session;@@ -3693,6 +3779,7 @@ struct nfs4_session *nfs4_alloc_session(void)atomic_set (&session->ref_count,1 ); +nfs4_init_channel (&session->fore_channel);return session; }@@ -3706,6 +3793,7 @@ void nfs4_put_session(struct nfs4_session **session) {dprintk ("--> nfs4_put_session()\n" );if (atomic_dec_and_test (&((*session)->ref_count))) { +nfs4_destroy_slot_table (&((*session)->fore_channel));nfs4_free_session (*session); *session =NULL ; }include/linux/nfs4_session.h +0
-0@@ -17,9 +17,26 @@ struct nfs4_channel_attrs {u32 rdma_attrs;
include/linux/nfs4_session.h struct nfs4_channel_attrs { · line 27
Quoted 10 lines
include/linux/nfs4_session.h +8
-0}; +struct nfs4_slot { +u32 seq_nr; +}; + +struct nfs4_slot_table { +struct nfs4_slot *slots;/* seqid per slot */ +unsigned long *used_slots;/* used/unused bitmap */ +unsigned long _used_slots;/* used when max_slots fits */
review 11-14: just limit to 128 bits, no dynamic allocation
Quoted 15 lines
include/linux/nfs4_session.h +9
-0+spinlock_t slot_tbl_lock; +struct rpc_wait_queue slot_tbl_waitq;/* allocators may wait here */ +int max_slots;/* # slots in table */ +int lowest_free_slotid;/* lower bound hint */ +int highest_used_slotid;/* sent to server on each SEQ. +* op for dynamic resizing */ +}; +struct nfs4_channel {struct nfs4_channel_attrs chan_attrs;struct rpc_clnt *rpc_client; +struct nfs4_slot_table slot_table; };/*
RFC 21/85 nfs41: find slot
In reply to Benny HalevyFind a free slot using bitmap-based allocation. Use the optimized ffz function to find a zero bit in the bitmap that indicates a free slot, starting the search from the 'lowest_free_slotid' position.
If found, mark the slot as used in the bitmap, get the slot's slotid and seqid, and update max_slotid to be used by the SEQUENCE operation.
Also, update lowest_free_slotid for next search.
If no free slot was found the caller has to wait for a free slot (outside the scope of this function)
--- fs/nfs/nfs4proc.c | 88 ++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs4_session.h | 5 ++ 2 files changed, 93 insertions(+), 0 deletions(-)
fs/nfs/nfs4proc.c +88 -0
@@ -207,6 +207,94 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestampspin_unlock (&clp->cl_lock); } +#if defined(CONFIG_NFS_V4_1 ) + +/* +* idx2bmp - return pointer to bitmap word holding index "idx". +* +* inputs: +* @base points to bitmap. +* @idx slot index. +* +* output: +* @bit optional, *bit set to bit index of "idx" in the returned +* bitmap word. +*/ +static inline unsigned long *idx2bmp (unsigned long *base,int idx,int *bit) +{ + base += idx /BITS_PER_LONG ; +if (bit) + *bit = idx & (BITS_PER_LONG -1 ); +return base; +} + +/* +* bmp2idx - return absolute index of bmp:bit in bitmap. +* +* inputs: +* @base points to bitmap. +* @bmp points to bitmap word. +* @bit bit index in bitmap word. +*/ +static inline int bmp2idx (unsigned long *base,unsigned long *bmp, +int bit) +{ +return ((bmp - base) *BITS_PER_LONG ) + bit; +} + +/* +* nfs4_find_slot - efficiently look for a free slot +* +* nfs4_find_slot uses the ffz cpu-optimized function to look for an unset +* bit in each word in the bitmap. +* Scan starts at lowest_free_slotid, which is a hint for the free slot, +* as all lower-numbered slots are known to be used. +* If found, we mark the slot as used, update the highest_used_slotid, +* and respectively set up the sequence operation args. +* The lowest_free_slotid is always set to the successive slotid. +* A pointer to the slot's seqid is returned if found, or NULL otherwise. +*/ +static struct nfs4_slot * +nfs4_find_slot (struct nfs4_slot_table *tbl,struct rpc_task *task) +{ +int bit, slotid; +struct nfs4_slot *slot =NULL ; +unsigned long *used, u; + +spin_lock (&tbl->slot_tbl_lock); + slotid = tbl->lowest_free_slotid; +while (slotid < tbl->max_slots) { + used =idx2bmp (tbl->used_slots, slotid,NULL ); + u = *used; +if (u == ~0UL ) { +/* all slots marked used in this word */ + slotid +=BITS_PER_LONG ; +continue ; + } +/* find first slot marked free in word */ + bit =ffz (u); + slotid =bmp2idx (tbl->used_slots, used, bit); +/* mark slot used. note that we don't do that if +* slotid >= tbl->max_slots so not to confuse +* highest_used_slotid algorithm */ +if (slotid < tbl->max_slots) { + *used |= (1 << bit); +if (slotid > tbl->highest_used_slotid) + tbl->highest_used_slotid = slotid; + slot = tbl->slots + slotid; + slotid++;/* for updating lowest_free_slot */ + } +break ; + } + tbl->lowest_free_slotid = slotid; +spin_unlock (&tbl->slot_tbl_lock); +dprintk ("<-- %s slot %p slotid %d\n" , __func__, + slot, slot ?slot_idx (tbl, slot) :-1 ); +return slot; +} + +#endif /* CONFIG_NFS_V4_1 */ +static void update_changeattr (struct inode *dir,struct nfs4_change_info *cinfo) {struct nfs_inode *nfsi =NFS_I (dir);
include/linux/nfs4_session.h +5 -0
@@ -33,6 +33,11 @@ struct nfs4_slot_table {* op for dynamic resizing */ }; +static inline int slot_idx (struct nfs4_slot_table *tbl,struct nfs4_slot *sp) +{ +return sp - tbl->slots; +} +struct nfs4_channel {struct nfs4_channel_attrs chan_attrs;struct rpc_clnt *rpc_client;
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 21/85] nfs41: find slot
Quoted 84 lines · Benny Halevy
Find a free slot using bitmap-based allocation. Use the optimized ffz function to find a zero bit in the bitmap that indicates a free slot, starting the search from the '
lowest_free_slotid' position.If found, mark the slot as used in the bitmap, get the slot's slotid and seqid, and update
max_slotidto be used by the SEQUENCE operation.Also, update
lowest_free_slotidfor next search.If no free slot was found the caller has to wait for a free slot (outside the scope of this function)
Signed-off-by Benny Halevy <[email protected]>--- fs/nfs/nfs4proc.c | 88 ++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs4_session.h | 5 ++ 2 files changed, 93 insertions(+), 0 deletions(-)fs/nfs/nfs4proc.c +56
-0@@ -207,6 +207,94 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestampspin_unlock (&clp->cl_lock); } +#if defined(CONFIG_NFS_V4_1 ) + +/* +* idx2bmp - return pointer to bitmap word holding index "idx". +* +* inputs: +* @base points to bitmap. +* @idx slot index. +* +* output: +* @bit optional, *bit set to bit index of "idx" in the returned +* bitmap word. +*/ +static inline unsigned long *idx2bmp (unsigned long *base,int idx,int *bit) +{ + base += idx /BITS_PER_LONG ; +if (bit) + *bit = idx & (BITS_PER_LONG -1 ); +return base; +} + +/* +* bmp2idx - return absolute index of bmp:bit in bitmap. +* +* inputs: +* @base points to bitmap. +* @bmp points to bitmap word. +* @bit bit index in bitmap word. +*/ +static inline int bmp2idx (unsigned long *base,unsigned long *bmp, +int bit) +{ +return ((bmp - base) *BITS_PER_LONG ) + bit; +} + +/* +* nfs4_find_slot - efficiently look for a free slot +* +* nfs4_find_slot uses the ffz cpu-optimized function to look for an unset +* bit in each word in the bitmap. +* Scan starts at lowest_free_slotid, which is a hint for the free slot, +* as all lower-numbered slots are known to be used. +* If found, we mark the slot as used, update the highest_used_slotid, +* and respectively set up the sequence operation args. +* The lowest_free_slotid is always set to the successive slotid. +* A pointer to the slot's seqid is returned if found, or NULL otherwise. +*/ +static struct nfs4_slot * +nfs4_find_slot (struct nfs4_slot_table *tbl,struct rpc_task *task) +{ +int bit, slotid; +struct nfs4_slot *slot =NULL ; +unsigned long *used, u; + +spin_lock (&tbl->slot_tbl_lock); + slotid = tbl->lowest_free_slotid;
fs/nfs/nfs4proc.c static void renew_lease(const struct nfs_server *server, unsigned long timestamp · line 275
Quoted 10 lines
fs/nfs/nfs4proc.c +10
-0+while (slotid < tbl->max_slots) { + used =idx2bmp (tbl->used_slots, slotid,NULL ); + u = *used; +if (u == ~0UL ) { +/* all slots marked used in this word */ + slotid +=BITS_PER_LONG ; +continue ; + } +/* find first slot marked free in word */ + bit =ffz (u);
review 11-14: look into using a bitmap_find_free_region function
Quoted 41 lines
fs/nfs/nfs4proc.c +22
-0+ slotid =bmp2idx (tbl->used_slots, used, bit); +/* mark slot used. note that we don't do that if +* slotid >= tbl->max_slots so not to confuse +* highest_used_slotid algorithm */ +if (slotid < tbl->max_slots) { + *used |= (1 << bit); +if (slotid > tbl->highest_used_slotid) + tbl->highest_used_slotid = slotid; + slot = tbl->slots + slotid; + slotid++;/* for updating lowest_free_slot */ + } + break; + } + tbl->lowest_free_slotid = slotid; +spin_unlock (&tbl->slot_tbl_lock); +dprintk ("<-- %s slot %p slotid %d\n" , __func__, + slot, slot ?slot_idx (tbl, slot) :-1 ); +return slot; +} + +#endif /* CONFIG_NFS_V4_1 */ +static void update_changeattr (struct inode *dir,struct nfs4_change_info *cinfo) {struct nfs_inode *nfsi =NFS_I (dir);include/linux/nfs4_session.h +5
-0@@ -33,6 +33,11 @@ struct nfs4_slot_table {* op for dynamic resizing */ }; +static inline int slot_idx (struct nfs4_slot_table *tbl,struct nfs4_slot *sp) +{ +return sp - tbl->slots; +} +struct nfs4_channel {struct nfs4_channel_attrs chan_attrs;struct rpc_clnt *rpc_client;
RFC 22/85 nfs41: free slot
In reply to Benny HalevyFree a slot in the slot table.
Mark the slot as free in the bitmap-based allocation table by clearing a bit corresponding to the slotid.
Update lowest_free_slotid if freed slotid is lower than that. Update highest_used_slotid. In the case the freed slotid equals the highest_used_slotid, scan downwards for the next highest used slotid using the optimized fls* functions.
Finally, wake up thread waiting on slot_tbl_waitq for a free slot to become available.
--- fs/nfs/nfs4proc.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 54 insertions(+), 0 deletions(-)
fs/nfs/nfs4proc.c +54 -0
@@ -243,6 +243,60 @@ static inline int bmp2idx(unsigned long *base, unsigned long *bmp, }/* +* nfs4_find_slot - free a slot and efficiently update slot table. +* +* freeing a slot is trivially done by clearing its respective bit +* in the bitmap. +* The lowest_free_slotid is updated if the freed slotid is lower than that. +* If the freed slotid equals highest_used_slotid we want to update it +* so that the server would be able to size down the slot table if needed, +* otherwise we know that the highest_used_slotid is still in use. +* When updating highest_used_slotid there may be "holes" in the bitmap +* so we need to scan down from highest_used_slotid to 0 looking for the now +* highest slotid in use. +* We use the fls cpu-optimized function to look for the last set bit in each +* word in the bitmap. +* If none found, highest_used_slotid is set to -1. +*/ +static void +nfs41_free_slot (struct nfs4_slot_table *tbl,struct nfs4_slot *slot) +{ +int slotid =slot_idx (tbl, slot); +unsigned long *used, u; +int bit; + +spin_lock (&tbl->slot_tbl_lock); +/* clear used bit in bitmap */ + used =idx2bmp (tbl->used_slots, slotid, &bit); + *used &= ~(1 << bit); + +if (slotid < tbl->lowest_free_slotid) + tbl->lowest_free_slotid = slotid; + +/* update highest_used_slotid when it is freed */ +if (slotid == tbl->highest_used_slotid) { + tbl->highest_used_slotid =-1 ; + slotid--; +/* scan down for the highest used slotid */ +while (slotid >=0 ) { + used =idx2bmp (tbl->used_slots, slotid,NULL ); + u = *used; +if (!u) { +/* all slots marked free in this word */ + slotid -=BITS_PER_LONG ; +continue ; + } + bit =__fls (u); + tbl->highest_used_slotid =bmp2idx (tbl->used_slots, + used, bit); +break ; + } + } +spin_unlock (&tbl->slot_tbl_lock); +rpc_wake_up_next (&tbl->slot_tbl_waitq); +} + +/* * nfs4_find_slot - efficiently look for a free slot * * nfs4_find_slot uses the ffz cpu-optimized function to look for an unset
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 22/85] nfs41: free slot
Quoted 53 lines · Benny Halevy
Free a slot in the slot table.
Mark the slot as free in the bitmap-based allocation table by clearing a bit corresponding to the slotid.
Update
lowest_free_slotidif freed slotid is lower than that. Updatehighest_used_slotid. In the case the freed slotid equals thehighest_used_slotid, scan downwards for the next highest used slotid using the optimized fls* functions.Finally, wake up thread waiting on
slot_tbl_waitqfor a free slot to become available.Signed-off-by Benny Halevy <[email protected]>--- fs/nfs/nfs4proc.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 54 insertions(+), 0 deletions(-)fs/nfs/nfs4proc.c +27
-0@@ -243,6 +243,60 @@ static inline int bmp2idx(unsigned long *base, unsigned long *bmp, }/* +* nfs4_find_slot - free a slot and efficiently update slot table. +* +* freeing a slot is trivially done by clearing its respective bit +* in the bitmap. +* The lowest_free_slotid is updated if the freed slotid is lower than that. +* If the freed slotid equals highest_used_slotid we want to update it +* so that the server would be able to size down the slot table if needed, +* otherwise we know that the highest_used_slotid is still in use. +* When updating highest_used_slotid there may be "holes" in the bitmap +* so we need to scan down from highest_used_slotid to 0 looking for the now +* highest slotid in use. +* We use the fls cpu-optimized function to look for the last set bit in each +* word in the bitmap. +* If none found, highest_used_slotid is set to -1. +*/ +static void +nfs41_free_slot (struct nfs4_slot_table *tbl,struct nfs4_slot *slot) +{ +int slotid =slot_idx (tbl, slot); +unsigned long *used, u; +int bit; + +spin_lock (&tbl->slot_tbl_lock); +/* clear used bit in bitmap */ + used =idx2bmp (tbl->used_slots, slotid, &bit); + *used &= ~(1 << bit); +
fs/nfs/nfs4proc.c static inline int bmp2idx(unsigned long *base, unsigned long *bmp, · line 282
Quoted 10 lines
fs/nfs/nfs4proc.c +10
-0+if (slotid < tbl->lowest_free_slotid) + tbl->lowest_free_slotid = slotid; + +/* update highest_used_slotid when it is freed */ +if (slotid == tbl->highest_used_slotid) { + tbl->highest_used_slotid =-1 ; + slotid--; +/* scan down for the highest used slotid */ +while (slotid >=0 ) { + used =idx2bmp (tbl->used_slots, slotid,NULL );
review 11-14: look into using a bitmap_ function, add one if needed
Quoted 20 lines
fs/nfs/nfs4proc.c +17
-0+ u = *used; +if (!u) { +/* all slots marked free in this word */ + slotid -=BITS_PER_LONG ; +continue ; + } + bit =__fls (u); + tbl->highest_used_slotid =bmp2idx (tbl->used_slots, + used, bit); +break ; + } + } +spin_unlock (&tbl->slot_tbl_lock); +rpc_wake_up_next (&tbl->slot_tbl_waitq); +} + +/* * nfs4_find_slot - efficiently look for a free slot * * nfs4_find_slot uses the ffz cpu-optimized function to look for an unset
RFC 23/85 nfs41: minorversion support for xdr
In reply to Benny HalevyFrom: Andy Adamson <[email protected]>
Add the minorversion to struct rpc_version and struct rpc_clnt, and struct compound_hdr. Switch on the minorversion to perfom NFSv4.0 vrs NFSv4.1 encoding,
Add the nfsv41 encode and decode sizes. Add encode_sequence to all nfs4_enc_* routines and decode_sequence to all nfs4_dec_* routines as required by v41.
--- fs/nfs/nfs4xdr.c | 641 +++++++++++++++++++++++++++++++------------ include/linux/sunrpc/clnt.h | 2 + net/sunrpc/clnt.c | 2 + 3 files changed, 471 insertions(+), 174 deletions(-)
fs/nfs/nfs4xdr.c +467 -174
@@ -240,43 +240,63 @@ static int nfs4_stat_to_errno(int); (encode_getattr_maxsz)#define decode_fs_locations_maxsz \ (0) + +#if defined(CONFIG_NFS_V4_1 ) +#define encode_sequence_maxsz 0/* stub */ +#define decode_sequence_maxsz 0/* stub */ +#else /* CONFIG_NFS_V4_1 */ +#define encode_sequence_maxsz 0 +#define decode_sequence_maxsz 0 +#endif /* CONFIG_NFS_V4_1 */ +#define NFS4_enc_compound_sz (1024)/* XXX: large enough? */ #define NFS4_dec_compound_sz (1024)/* XXX: large enough? */ #define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_read_maxsz)#define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_read_maxsz)#define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_readlink_maxsz)#define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_readlink_maxsz)#define NFS4_enc_readdir_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_readdir_maxsz)#define NFS4_dec_readdir_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_readdir_maxsz)#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_write_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_write_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_commit_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_commit_maxsz + \ decode_getattr_maxsz) -#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ +#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_savefh_maxsz + \ encode_open_maxsz + \
@@ -284,7 +304,8 @@ static int nfs4_stat_to_errno(int); encode_getattr_maxsz + \ encode_restorefh_maxsz + \ encode_getattr_maxsz) -#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ +#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_savefh_maxsz + \ decode_open_maxsz + \
@@ -301,43 +322,53 @@ static int nfs4_stat_to_errno(int); decode_putfh_maxsz + \ decode_open_confirm_maxsz)#define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_open_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_open_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_open_downgrade_sz \ (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_open_downgrade_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_open_downgrade_sz \ (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_open_downgrade_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_close_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_close_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_setattr_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_setattr_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_fsinfo_maxsz)#define NFS4_dec_fsinfo_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_fsinfo_maxsz)#define NFS4_enc_renew_sz (compound_encode_hdr_maxsz + \
@@ -359,64 +390,81 @@ static int nfs4_stat_to_errno(int); decode_putrootfh_maxsz + \ decode_fsinfo_maxsz)#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_lock_maxsz)#define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_lock_maxsz)#define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_lockt_maxsz)#define NFS4_dec_lockt_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_lockt_maxsz)#define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_locku_maxsz)#define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_locku_maxsz)#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_access_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_access_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_lookup_maxsz + \ encode_getattr_maxsz + \ encode_getfh_maxsz)#define NFS4_dec_lookup_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_lookup_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz)#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putrootfh_maxsz + \ encode_getattr_maxsz + \ encode_getfh_maxsz)#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putrootfh_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz)#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_remove_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 5 + \ decode_getattr_maxsz)#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_savefh_maxsz + \ encode_putfh_maxsz + \
@@ -425,6 +473,7 @@ static int nfs4_stat_to_errno(int); encode_restorefh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_savefh_maxsz + \ decode_putfh_maxsz + \
@@ -433,6 +482,7 @@ static int nfs4_stat_to_errno(int); decode_restorefh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_savefh_maxsz + \ encode_putfh_maxsz + \
@@ -441,6 +491,7 @@ static int nfs4_stat_to_errno(int); encode_restorefh_maxsz + \ decode_getattr_maxsz)#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_savefh_maxsz + \ decode_putfh_maxsz + \
@@ -449,16 +500,19 @@ static int nfs4_stat_to_errno(int); decode_restorefh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_symlink_maxsz + \ encode_getattr_maxsz + \ encode_getfh_maxsz)#define NFS4_dec_symlink_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_symlink_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz)#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_savefh_maxsz + \ encode_create_maxsz + \
@@ -467,6 +521,7 @@ static int nfs4_stat_to_errno(int); encode_restorefh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_savefh_maxsz + \ decode_create_maxsz + \
@@ -475,49 +530,63 @@ static int nfs4_stat_to_errno(int); decode_restorefh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_pathconf_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_statfs_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_statfs_maxsz)#define NFS4_dec_statfs_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_statfs_maxsz)#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_delegreturn_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_delegreturn_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_getacl_maxsz)#define NFS4_dec_getacl_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_getacl_maxsz)#define NFS4_enc_setacl_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_setacl_maxsz)#define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_setacl_maxsz)#define NFS4_enc_fs_locations_sz \ (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_lookup_maxsz + \ encode_fs_locations_maxsz)#define NFS4_dec_fs_locations_sz \ (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_lookup_maxsz + \ decode_fs_locations_maxsz)
@@ -543,6 +612,7 @@ struct compound_hdr {uint32_t nops;uint32_t taglen;char * tag; +u32 minorversion; };/*
@@ -578,7 +648,7 @@ static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *xdr_encode_opaque (p, str, len); } -static __u32 * +static __be32 *encode_compound_hdr (struct xdr_stream *xdr,struct compound_hdr *hdr) {__be32 *p, *nops;
@@ -588,7 +658,7 @@ encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)RESERVE_SPACE (12 +(XDR_QUADLEN (hdr->taglen)<<2 ));WRITE32 (hdr->taglen);WRITEMEM (hdr->tag, hdr->taglen); -WRITE32 (NFS4_MINOR_VERSION ); +WRITE32 (hdr->minorversion); nops = p;WRITE32 (hdr->nops);return nops;
@@ -1377,7 +1447,8 @@ encode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr)static int encode_setattr (struct xdr_stream *xdr,const struct nfs_setattrargs *arg, -const struct nfs_server *server,struct compound_hdr *hdr) +const struct nfs_server *server, +struct compound_hdr *hdr) {int status;__be32 *p;
@@ -1468,6 +1539,30 @@ encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid,return 0 ; } + +#if defined(CONFIG_NFS_V4_1 ) +/* NFSv4.1 operations */ +static int encode_sequence (struct xdr_stream *xdr, +const struct nfs41_sequence_args *args, +struct compound_hdr *hdr) +{ +if (hdr->minorversion ==0 ) +return 0 ; + +/* stub */ + hdr->nops++; + +return 0 ; +} +#else /* CONFIG_NFS_V4_1 */ +static inline int encode_sequence (struct xdr_stream *xdr, +const struct nfs41_sequence_args *args, +struct compound_hdr *hdr) +{ +return 0 ; +} +#endif /* CONFIG_NFS_V4_1 */ +/* * END OF "GENERIC" ENCODE ROUTINES. */
@@ -1475,17 +1570,19 @@ encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid,/* * Encode an ACCESS request */ -static int nfs4_xdr_enc_access (struct rpc_rqst *req,__be32 *p,const struct nfs4_accessargs *args) +static int nfs4_xdr_enc_access (struct rpc_rqst *req,__be32 *p, +const struct nfs4_accessargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status !=0 ) goto out;
@@ -1501,17 +1598,19 @@ out:/* * Encode LOOKUP request */ -static int nfs4_xdr_enc_lookup (struct rpc_rqst *req,__be32 *p,const struct nfs4_lookup_arg *args) +static int nfs4_xdr_enc_lookup (struct rpc_rqst *req,__be32 *p, +const struct nfs4_lookup_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out;if ((status =encode_lookup (&xdr, args->name, &hdr)) !=0 )
@@ -1527,17 +1626,19 @@ out:/* * Encode LOOKUP_ROOT request */ -static int nfs4_xdr_enc_lookup_root (struct rpc_rqst *req,__be32 *p,const struct nfs4_lookup_root_arg *args) +static int nfs4_xdr_enc_lookup_root (struct rpc_rqst *req,__be32 *p, +const struct nfs4_lookup_root_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putrootfh (&xdr, &hdr)) !=0 ) goto out;if ((status =encode_getfh (&xdr, &hdr)) ==0 )
@@ -1550,17 +1651,19 @@ out:/* * Encode REMOVE request */ -static int nfs4_xdr_enc_remove (struct rpc_rqst *req,__be32 *p,const struct nfs_removeargs *args) +static int nfs4_xdr_enc_remove (struct rpc_rqst *req,__be32 *p, +const struct nfs_removeargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->fh, &hdr)) !=0 ) goto out;if ((status =encode_remove (&xdr, &args->name, &hdr)) !=0 )
@@ -1574,17 +1677,19 @@ out:/* * Encode RENAME request */ -static int nfs4_xdr_enc_rename (struct rpc_rqst *req,__be32 *p,const struct nfs4_rename_arg *args) +static int nfs4_xdr_enc_rename (struct rpc_rqst *req,__be32 *p, +const struct nfs4_rename_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->old_dir, &hdr)) !=0 ) goto out;if ((status =encode_savefh (&xdr, &hdr)) !=0 )
@@ -1607,17 +1712,19 @@ out:/* * Encode LINK request */ -static int nfs4_xdr_enc_link (struct rpc_rqst *req,__be32 *p,const struct nfs4_link_arg *args) +static int nfs4_xdr_enc_link (struct rpc_rqst *req,__be32 *p, +const struct nfs4_link_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->fh, &hdr)) !=0 ) goto out;if ((status =encode_savefh (&xdr, &hdr)) !=0 )
@@ -1639,17 +1746,19 @@ out:/* * Encode CREATE request */ -static int nfs4_xdr_enc_create (struct rpc_rqst *req,__be32 *p,const struct nfs4_create_arg *args) +static int nfs4_xdr_enc_create (struct rpc_rqst *req,__be32 *p, +const struct nfs4_create_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out;if ((status =encode_savefh (&xdr, &hdr)) !=0 )
@@ -1679,17 +1788,19 @@ static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, __be32 *p, const struct nf/* * Encode GETATTR request */ -static int nfs4_xdr_enc_getattr (struct rpc_rqst *req,__be32 *p,const struct nfs4_getattr_arg *args) +static int nfs4_xdr_enc_getattr (struct rpc_rqst *req,__be32 *p, +const struct nfs4_getattr_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->fh, &hdr)) ==0 ) status =encode_getfattr (&xdr, args->bitmask, &hdr);encode_nops (nops, &hdr);
@@ -1699,17 +1810,19 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf/* * Encode a CLOSE request */ -static int nfs4_xdr_enc_close (struct rpc_rqst *req,__be32 *p,struct nfs_closeargs *args) +static int nfs4_xdr_enc_close (struct rpc_rqst *req,__be32 *p, +struct nfs_closeargs *args) { -struct xdr_stream xdr; -struct compound_hdr hdr = { - .nops =0 , - }; +struct xdr_stream xdr; +struct compound_hdr hdr = { + .minorversion = req->rq_task->tk_client->cl_mvers, + };int status;__be32 *nops; -xdr_init_encode (&xdr, &req->rq_snd_buf, p); +xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -1725,17 +1838,19 @@ out:/* * Encode an OPEN request */ -static int nfs4_xdr_enc_open (struct rpc_rqst *req,__be32 *p,struct nfs_openargs *args) +static int nfs4_xdr_enc_open (struct rpc_rqst *req,__be32 *p, +struct nfs_openargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -1767,7 +1882,7 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;
@@ -1786,17 +1901,19 @@ out:/* * Encode an OPEN request with no attributes. */ -static int nfs4_xdr_enc_open_noattr (struct rpc_rqst *req,__be32 *p,struct nfs_openargs *args) +static int nfs4_xdr_enc_open_noattr (struct rpc_rqst *req,__be32 *p, +struct nfs_openargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -1812,17 +1929,19 @@ out:/* * Encode an OPEN_DOWNGRADE request */ -static int nfs4_xdr_enc_open_downgrade (struct rpc_rqst *req,__be32 *p,struct nfs_closeargs *args) +static int nfs4_xdr_enc_open_downgrade (struct rpc_rqst *req,__be32 *p, +struct nfs_closeargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -1838,17 +1957,19 @@ out:/* * Encode a LOCK request */ -static int nfs4_xdr_enc_lock (struct rpc_rqst *req,__be32 *p,struct nfs_lock_args *args) +static int nfs4_xdr_enc_lock (struct rpc_rqst *req,__be32 *p, +struct nfs_lock_args *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -1861,17 +1982,19 @@ out:/* * Encode a LOCKT request */ -static int nfs4_xdr_enc_lockt (struct rpc_rqst *req,__be32 *p,struct nfs_lockt_args *args) +static int nfs4_xdr_enc_lockt (struct rpc_rqst *req,__be32 *p, +struct nfs_lockt_args *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -1884,17 +2007,19 @@ out:/* * Encode a LOCKU request */ -static int nfs4_xdr_enc_locku (struct rpc_rqst *req,__be32 *p,struct nfs_locku_args *args) +static int nfs4_xdr_enc_locku (struct rpc_rqst *req,__be32 *p, +struct nfs_locku_args *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -1907,11 +2032,12 @@ out:/* * Encode a READLINK request */ -static int nfs4_xdr_enc_readlink (struct rpc_rqst *req,__be32 *p,const struct nfs4_readlink *args) +static int nfs4_xdr_enc_readlink (struct rpc_rqst *req,__be32 *p, +const struct nfs4_readlink *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;unsigned int replen;
@@ -1920,6 +2046,7 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct nxdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -1941,11 +2068,12 @@ out:/* * Encode a READDIR request */ -static int nfs4_xdr_enc_readdir (struct rpc_rqst *req,__be32 *p,const struct nfs4_readdir_arg *args) +static int nfs4_xdr_enc_readdir (struct rpc_rqst *req,__be32 *p, +const struct nfs4_readdir_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;int replen;
@@ -1954,6 +2082,7 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nfxdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -1978,18 +2107,20 @@ out:/* * Encode a READ request */ -static int nfs4_xdr_enc_read (struct rpc_rqst *req,__be32 *p,struct nfs_readargs *args) +static int nfs4_xdr_enc_read (struct rpc_rqst *req,__be32 *p, +struct nfs_readargs *args) {struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int replen, status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -2013,18 +2144,20 @@ out:/* * Encode an SETATTR request */ -static int nfs4_xdr_enc_setattr (struct rpc_rqst *req,__be32 *p,struct nfs_setattrargs *args) +static int nfs4_xdr_enc_setattr (struct rpc_rqst *req,__be32 *p, +struct nfs_setattrargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -2042,18 +2175,19 @@ out:*/ static int nfs4_xdr_enc_getacl (struct rpc_rqst *req,__be32 *p, -struct nfs_getaclargs *args) +struct nfs_getaclargs *args) {struct xdr_stream xdr;struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int replen, status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -2070,24 +2204,25 @@ out:/* * Encode a WRITE request */ -static int nfs4_xdr_enc_write (struct rpc_rqst *req,__be32 *p,struct nfs_writeargs *args) +static int nfs4_xdr_enc_write (struct rpc_rqst *req,__be32 *p, +struct nfs_writeargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; status =encode_write (&xdr, args, &hdr);if (status) goto out; - req->rq_snd_buf.flags |=XDRBUF_WRITE ; status =encode_getfattr (&xdr, args->bitmask, &hdr); out:encode_nops (nops, &hdr);
@@ -2097,17 +2232,19 @@ out:/* * a COMMIT request */ -static int nfs4_xdr_enc_commit (struct rpc_rqst *req,__be32 *p,struct nfs_writeargs *args) +static int nfs4_xdr_enc_commit (struct rpc_rqst *req,__be32 *p, +struct nfs_writeargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;
@@ -2123,17 +2260,19 @@ out:/* * FSINFO request */ -static int nfs4_xdr_enc_fsinfo (struct rpc_rqst *req,__be32 *p,struct nfs4_fsinfo_arg *args) +static int nfs4_xdr_enc_fsinfo (struct rpc_rqst *req,__be32 *p, +struct nfs4_fsinfo_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (!status) status =encode_fsinfo (&xdr, args->bitmask, &hdr);
@@ -2144,17 +2283,19 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsin/* * a PATHCONF request */ -static int nfs4_xdr_enc_pathconf (struct rpc_rqst *req,__be32 *p,const struct nfs4_pathconf_arg *args) +static int nfs4_xdr_enc_pathconf (struct rpc_rqst *req,__be32 *p, +const struct nfs4_pathconf_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (!status) status = encode_getattr_one(&xdr,
@@ -2167,22 +2308,25 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct n/* * a STATFS request */ -static int nfs4_xdr_enc_statfs (struct rpc_rqst *req,__be32 *p,const struct nfs4_statfs_arg *args) +static int nfs4_xdr_enc_statfs (struct rpc_rqst *req,__be32 *p, +const struct nfs4_statfs_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status ==0 ) status =encode_getattr_two (&xdr, args->bitmask[0 ] & nfs4_statfs_bitmap[0 ], - args->bitmask[1 ] & nfs4_statfs_bitmap[1 ], &hdr); + args->bitmask[1 ] & nfs4_statfs_bitmap[1 ], + &hdr);encode_nops (nops, &hdr);return status; }
@@ -2190,18 +2334,20 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs/* * GETATTR_BITMAP request */ -static int nfs4_xdr_enc_server_caps (struct rpc_rqst *req,__be32 *p,const struct nfs_fh *fhandle) +static int nfs4_xdr_enc_server_caps (struct rpc_rqst *req,__be32 *p, +struct nfs4_server_caps_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, fhandle, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); + status =encode_putfh (&xdr, args->fhandle, &hdr);if (status ==0 ) status = encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS| FATTR4_WORD0_LINK_SUPPORT|
@@ -2218,7 +2364,7 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;
@@ -2226,6 +2372,7 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_clientxdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); status =encode_renew (&xdr, clp, &hdr); +encode_nops (nops, &hdr);return status; }
@@ -2237,7 +2384,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4 {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;
@@ -2245,6 +2392,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); status =encode_setclientid (&xdr, sc, &hdr); +encode_nops (nops, &hdr);return status; }
@@ -2256,7 +2404,7 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };const u32 lease_bitmap[2 ] = {FATTR4_WORD0_LEASE_TIME ,0 };int status;
@@ -2276,17 +2424,19 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str/* * DELEGRETURN request */ -static int nfs4_xdr_enc_delegreturn (struct rpc_rqst *req,__be32 *p,const struct nfs4_delegreturnargs *args) +static int nfs4_xdr_enc_delegreturn (struct rpc_rqst *req,__be32 *p, +const struct nfs4_delegreturnargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fhandle, &hdr);if (status !=0 ) goto out;
@@ -2302,11 +2452,12 @@ out:/* * Encode FS_LOCATIONS request */ -static int nfs4_xdr_enc_fs_locations (struct rpc_rqst *req,__be32 *p,struct nfs4_fs_locations_arg *args) +static int nfs4_xdr_enc_fs_locations (struct rpc_rqst *req,__be32 *p, +struct nfs4_fs_locations_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;int replen;
@@ -2315,6 +2466,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfsxdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out;if ((status =encode_lookup (&xdr, args->name, &hdr)) !=0 )
@@ -2325,7 +2477,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs* toplevel_status + OP_PUTFH + status * + OP_LOOKUP + status + OP_GETATTR + status = 7 */ - replen = (RPC_REPHDRSIZE + auth->au_rslack +7 ) <<2 ; + replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_enc_fsinfo_sz) <<2 ;xdr_inline_pages (&req->rq_rcv_buf, replen, &args->page,0 ,PAGE_SIZE ); out:
@@ -3963,19 +4115,48 @@ static int decode_delegreturn(struct xdr_stream *xdr)return decode_op_hdr (xdr,OP_DELEGRETURN ); } +#if defined(CONFIG_NFS_V4_1 ) +static int decode_sequence (struct xdr_stream *xdr, +struct nfs41_sequence_res *res, +struct rpc_rqst *rqstp) +{ +if (rqstp->rq_task->tk_client->cl_mvers ==0 ) +return 0 ; + +/* stub */ + +return 0 ; +} +#else /* CONFIG_NFS_V4_1 */ +static inline int decode_sequence (struct xdr_stream *xdr, +struct nfs41_sequence_res *res, +struct rpc_rqst *rqstp) +{ +return 0 ; +} +#endif /* CONFIG_NFS_V4_1 */ + +/* +* END OF "GENERIC" DECODE ROUTINES. +*/ +/* * Decode OPEN_DOWNGRADE response */ -static int nfs4_xdr_dec_open_downgrade (struct rpc_rqst *rqstp,__be32 *p,struct nfs_closeres *res) +static int nfs4_xdr_dec_open_downgrade (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_closeres *res) { -struct xdr_stream xdr; -struct compound_hdr hdr; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr; +int status; -xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); - status =decode_compound_hdr (&xdr, &hdr); -if (status) - goto out; +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -3988,20 +4169,21 @@ out: }/* -* END OF "GENERIC" DECODE ROUTINES. -*/ - -/* * Decode ACCESS response */ -static int nfs4_xdr_dec_access (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_accessres *res) +static int nfs4_xdr_dec_access (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_accessres *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out; status =decode_putfh (&xdr);if (status !=0 )
@@ -4017,14 +4199,19 @@ out:/* * Decode LOOKUP response */ -static int nfs4_xdr_dec_lookup (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_lookup_res *res) +static int nfs4_xdr_dec_lookup (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_lookup_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;
@@ -4040,14 +4227,19 @@ out:/* * Decode LOOKUP_ROOT response */ -static int nfs4_xdr_dec_lookup_root (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_lookup_res *res) +static int nfs4_xdr_dec_lookup_root (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_lookup_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putrootfh (&xdr)) !=0 ) goto out;
@@ -4060,14 +4252,19 @@ out:/* * Decode REMOVE response */ -static int nfs4_xdr_dec_remove (struct rpc_rqst *rqstp,__be32 *p,struct nfs_removeres *res) +static int nfs4_xdr_dec_remove (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_removeres *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;
@@ -4081,14 +4278,19 @@ out:/* * Decode RENAME response */ -static int nfs4_xdr_dec_rename (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_rename_res *res) +static int nfs4_xdr_dec_rename (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_rename_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status; - +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;
@@ -4111,14 +4313,19 @@ out:/* * Decode LINK response */ -static int nfs4_xdr_dec_link (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_link_res *res) +static int nfs4_xdr_dec_link (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_link_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;
@@ -4144,14 +4351,19 @@ out:/* * Decode CREATE response */ -static int nfs4_xdr_dec_create (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_create_res *res) +static int nfs4_xdr_dec_create (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_create_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status; - +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;
@@ -4181,7 +4393,8 @@ static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_c/* * Decode GETATTR response */ -static int nfs4_xdr_dec_getattr (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_getattr_res *res) +static int nfs4_xdr_dec_getattr (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_getattr_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4191,56 +4404,65 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out; status =decode_getfattr (&xdr, res->fattr, res->server); out:return status; - }/* * Encode an SETACL request */ static int -nfs4_xdr_enc_setacl (struct rpc_rqst *req,__be32 *p,struct nfs_setaclargs *args) +nfs4_xdr_enc_setacl (struct rpc_rqst *req,__be32 *p, +struct nfs_setaclargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; status =encode_setacl (&xdr, args, &hdr); out: -encode_nops (nops, &hdr);return status; } +/* * Decode SETACL response */ static int -nfs4_xdr_dec_setacl (struct rpc_rqst *rqstp,__be32 *p,void *res) +nfs4_xdr_dec_setacl (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_setaclres *res) {struct xdr_stream xdr;struct compound_hdr hdr; +struct nfs_setattrres *sattrp =NULL ;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out; - status =decode_setattr (&xdr, res); + status =decode_setattr (&xdr, sattrp); out:return status; }
@@ -4249,7 +4471,8 @@ out:* Decode GETACL response */ static int -nfs4_xdr_dec_getacl (struct rpc_rqst *rqstp,__be32 *p,size_t *acl_len) +nfs4_xdr_dec_getacl (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_getaclres *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4259,10 +4482,13 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len) status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out; - status =decode_getacl (&xdr, rqstp, acl_len); + status =decode_getacl (&xdr, rqstp, res->acl_len); out:return status;
@@ -4271,16 +4497,20 @@ out:/* * Decode CLOSE response */ -static int nfs4_xdr_dec_close (struct rpc_rqst *rqstp,__be32 *p,struct nfs_closeres *res) +static int nfs4_xdr_dec_close (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_closeres *res) { -struct xdr_stream xdr; -struct compound_hdr hdr; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr; +int status; -xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); - status =decode_compound_hdr (&xdr, &hdr); -if (status) - goto out; +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4301,16 +4531,20 @@ out:/* * Decode OPEN response */ -static int nfs4_xdr_dec_open (struct rpc_rqst *rqstp,__be32 *p,struct nfs_openres *res) +static int nfs4_xdr_dec_open (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_openres *res) { -struct xdr_stream xdr; -struct compound_hdr hdr; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr; +int status; -xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); - status =decode_compound_hdr (&xdr, &hdr); -if (status) - goto out; +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4355,16 +4589,20 @@ out:/* * Decode OPEN response */ -static int nfs4_xdr_dec_open_noattr (struct rpc_rqst *rqstp,__be32 *p,struct nfs_openres *res) +static int nfs4_xdr_dec_open_noattr (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_openres *res) { -struct xdr_stream xdr; -struct compound_hdr hdr; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr; +int status; -xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); - status =decode_compound_hdr (&xdr, &hdr); -if (status) - goto out; +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4379,16 +4617,20 @@ out:/* * Decode SETATTR response */ -static int nfs4_xdr_dec_setattr (struct rpc_rqst *rqstp,__be32 *p,struct nfs_setattrres *res) +static int nfs4_xdr_dec_setattr (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_setattrres *res) { -struct xdr_stream xdr; -struct compound_hdr hdr; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr; +int status; -xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); - status =decode_compound_hdr (&xdr, &hdr); -if (status) - goto out; +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4405,7 +4647,8 @@ out:/* * Decode LOCK response */ -static int nfs4_xdr_dec_lock (struct rpc_rqst *rqstp,__be32 *p,struct nfs_lock_res *res) +static int nfs4_xdr_dec_lock (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_lock_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4415,6 +4658,9 @@ static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_ status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4426,7 +4672,8 @@ out:/* * Decode LOCKT response */ -static int nfs4_xdr_dec_lockt (struct rpc_rqst *rqstp,__be32 *p,struct nfs_lockt_res *res) +static int nfs4_xdr_dec_lockt (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_lockt_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4436,6 +4683,9 @@ static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4447,7 +4697,8 @@ out:/* * Decode LOCKU response */ -static int nfs4_xdr_dec_locku (struct rpc_rqst *rqstp,__be32 *p,struct nfs_locku_res *res) +static int nfs4_xdr_dec_locku (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_locku_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4457,6 +4708,9 @@ static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4468,7 +4722,8 @@ out:/* * Decode READLINK response */ -static int nfs4_xdr_dec_readlink (struct rpc_rqst *rqstp,__be32 *p,void *res) +static int nfs4_xdr_dec_readlink (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_readlink_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4478,6 +4733,9 @@ static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res) status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4489,7 +4747,8 @@ out:/* * Decode READDIR response */ -static int nfs4_xdr_dec_readdir (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_readdir_res *res) +static int nfs4_xdr_dec_readdir (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_readdir_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4499,6 +4758,9 @@ static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_r status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4510,7 +4772,8 @@ out:/* * Decode Read response */ -static int nfs4_xdr_dec_read (struct rpc_rqst *rqstp,__be32 *p,struct nfs_readres *res) +static int nfs4_xdr_dec_read (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_readres *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4520,6 +4783,9 @@ static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readr status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4533,7 +4799,8 @@ out:/* * Decode WRITE response */ -static int nfs4_xdr_dec_write (struct rpc_rqst *rqstp,__be32 *p,struct nfs_writeres *res) +static int nfs4_xdr_dec_write (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_writeres *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4543,6 +4810,9 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writ status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4559,7 +4829,8 @@ out:/* * Decode COMMIT response */ -static int nfs4_xdr_dec_commit (struct rpc_rqst *rqstp,__be32 *p,struct nfs_writeres *res) +static int nfs4_xdr_dec_commit (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_writeres *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4569,6 +4840,9 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_wri status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;
@@ -4583,7 +4857,8 @@ out:/* * FSINFO request */ -static int nfs4_xdr_dec_fsinfo (struct rpc_rqst *req,__be32 *p,struct nfs_fsinfo *fsinfo) +static int nfs4_xdr_dec_fsinfo (struct rpc_rqst *req,__be32 *p, +struct nfs4_fsinfo_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4592,16 +4867,19 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfxdr_init_decode (&xdr, &req->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr);if (!status) + status =decode_sequence (&xdr, &res->seq_res, req); +if (!status) status =decode_putfh (&xdr);if (!status) - status =decode_fsinfo (&xdr, fsinfo); + status =decode_fsinfo (&xdr, res->fsinfo);return status; }/* * PATHCONF request */ -static int nfs4_xdr_dec_pathconf (struct rpc_rqst *req,__be32 *p,struct nfs_pathconf *pathconf) +static int nfs4_xdr_dec_pathconf (struct rpc_rqst *req,__be32 *p, +struct nfs4_pathconf_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4610,16 +4888,19 @@ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_patxdr_init_decode (&xdr, &req->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr);if (!status) + status =decode_sequence (&xdr, &res->seq_res, req); +if (!status) status =decode_putfh (&xdr);if (!status) - status =decode_pathconf (&xdr, pathconf); + status =decode_pathconf (&xdr, res->pathconf);return status; }/* * STATFS request */ -static int nfs4_xdr_dec_statfs (struct rpc_rqst *req,__be32 *p,struct nfs_fsstat *fsstat) +static int nfs4_xdr_dec_statfs (struct rpc_rqst *req,__be32 *p, +struct nfs4_statfs_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4628,23 +4909,30 @@ static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fsstaxdr_init_decode (&xdr, &req->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr);if (!status) + status =decode_sequence (&xdr, &res->seq_res, req); +if (!status) status =decode_putfh (&xdr);if (!status) - status =decode_statfs (&xdr, fsstat); + status =decode_statfs (&xdr, res->fsstat);return status; }/* * GETATTR_BITMAP request */ -static int nfs4_xdr_dec_server_caps (struct rpc_rqst *req,__be32 *p,struct nfs4_server_caps_res *res) +static int nfs4_xdr_dec_server_caps (struct rpc_rqst *req,__be32 *p, +struct nfs4_server_caps_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &req->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, req); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;
@@ -4709,7 +4997,8 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str/* * DELEGRETURN request */ -static int nfs4_xdr_dec_delegreturn (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_delegreturnres *res) +static int nfs4_xdr_dec_delegreturn (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_delegreturnres *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4717,7 +5006,10 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nfxdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr); -if (status !=0 ) +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out; status =decode_putfh (&xdr);if (status !=0 )
@@ -4731,7 +5023,8 @@ out:/* * FS_LOCATIONS request */ -static int nfs4_xdr_dec_fs_locations (struct rpc_rqst *req,__be32 *p,struct nfs4_fs_locations *res) +static int nfs4_xdr_dec_fs_locations (struct rpc_rqst *req,__be32 *p, +struct nfs4_fs_locations_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;
@@ -4739,14 +5032,18 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfsxdr_init_decode (&xdr, &req->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr); -if (status !=0 ) +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, req); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;if ((status =decode_lookup (&xdr)) !=0 ) goto out;xdr_enter_page (&xdr,PAGE_SIZE ); - status =decode_getfattr (&xdr, &res->fattr, res->server); + status =decode_getfattr (&xdr, &res->fs_locations->fattr, + res->fs_locations->server); out:return status; }
@@ -4877,10 +5174,10 @@ nfs4_stat_to_errno(int stat)#define PROC (proc, argtype, restype) \ [NFSPROC4_CLNT_##proc] = { \ .p_proc = NFSPROC4_COMPOUND, \ - .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \ - .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \ - .p_arglen = NFS4_##argtype##_sz, \ - .p_replen = NFS4_##restype##_sz, \ + .p_encode = (kxdrproc_t) nfs4##_xdr_##argtype, \ + .p_decode = (kxdrproc_t) nfs4##_xdr_##restype, \ + .p_arglen = NFS4##_##argtype##_sz, \ + .p_replen = NFS4##_##restype##_sz, \ .p_statidx = NFSPROC4_CLNT_##proc, \ .p_name = #proc, \ }
@@ -4922,11 +5219,6 @@ struct rpc_procinfo nfs4_procedures[] = { PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), }; -#if defined(CONFIG_NFS_V4_1 ) -struct rpc_procinfo nfs41_procedures[] = { -}; -#endif /* CONFIG_NFS_V4_1 */ -struct rpc_version nfs_version4 = { .number =4 , .nrprocs =ARRAY_SIZE (nfs4_procedures),
@@ -4936,8 +5228,9 @@ struct rpc_version nfs_version4 = {#ifdef CONFIG_NFS_V4_1 struct rpc_version nfs_version41 = { .number =4 , - .nrprocs =ARRAY_SIZE (nfs41_procedures), - .procs = nfs41_procedures + .minorversion =1 , + .nrprocs =ARRAY_SIZE (nfs4_procedures), + .procs = nfs4_procedures };#endif /* CONFIG_NFS_V4_1 */
include/linux/sunrpc/clnt.h +2 -0
@@ -32,6 +32,7 @@ struct rpc_clnt {struct rpc_procinfo * cl_procinfo;/* procedure info */ u32 cl_prog,/* RPC program number */ cl_vers,/* RPC version number */ + cl_mvers,/* RPC minorversion number */ cl_maxproc;/* max procedure number */ char * cl_server;/* server machine name */
@@ -82,6 +83,7 @@ get_rpc_version(struct rpc_program *prog, u32 vers, int minorvers)struct rpc_version {u32 number;/* version number */ +u32 minorversion;/* minorversion number */ unsigned int nrprocs;/* number of procs */ struct rpc_procinfo * procs;/* procedure array */ };
net/sunrpc/clnt.c +2 -0
@@ -177,6 +177,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru clnt->cl_protname = program->name; clnt->cl_prog = args->prognumber ? : program->number; clnt->cl_vers = version->number; + clnt->cl_mvers = version->minorversion; clnt->cl_stats = program->stats; clnt->cl_metrics =rpc_alloc_iostats (clnt); err = -ENOMEM ;
@@ -491,6 +492,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old, clnt->cl_protname = program->name; clnt->cl_prog = program->number; clnt->cl_vers = version->number; + clnt->cl_mvers = version->minorversion; clnt->cl_stats = program->stats; err =rpc_ping (clnt,RPC_TASK_SOFT );if (err !=0 ) {
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 23/85] nfs41: minorversion support for xdr
Quoted 1,905 lines · Benny Halevy
From: Andy Adamson <[email protected]>
Add the minorversion to struct
rpc_versionand structrpc_clnt, and structcompound_hdr. Switch on the minorversion to perfom NFSv4.0 vrs NFSv4.1 encoding,Add the nfsv41 encode and decode sizes. Add
encode_sequenceto all nfs4_enc_* routines anddecode_sequenceto all nfs4_dec_* routines as required by v41.Signed-off-by Andy Adamson<[email protected]>Signed-off-by Benny Halevy <[email protected]>--- fs/nfs/nfs4xdr.c | 641 +++++++++++++++++++++++++++++++------------ include/linux/sunrpc/clnt.h | 2 + net/sunrpc/clnt.c | 2 + 3 files changed, 471 insertions(+), 174 deletions(-)fs/nfs/nfs4xdr.c +467
-174@@ -240,43 +240,63 @@ static int nfs4_stat_to_errno(int); (encode_getattr_maxsz)#define decode_fs_locations_maxsz \ (0) + +#if defined(CONFIG_NFS_V4_1 ) +#define encode_sequence_maxsz 0/* stub */ +#define decode_sequence_maxsz 0/* stub */ +#else /* CONFIG_NFS_V4_1 */ +#define encode_sequence_maxsz 0 +#define decode_sequence_maxsz 0 +#endif /* CONFIG_NFS_V4_1 */ +#define NFS4_enc_compound_sz (1024)/* XXX: large enough? */ #define NFS4_dec_compound_sz (1024)/* XXX: large enough? */ #define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_read_maxsz)#define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_read_maxsz)#define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_readlink_maxsz)#define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_readlink_maxsz)#define NFS4_enc_readdir_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_readdir_maxsz)#define NFS4_dec_readdir_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_readdir_maxsz)#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_write_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_write_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_commit_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_commit_maxsz + \ decode_getattr_maxsz) -#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ +#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_savefh_maxsz + \ encode_open_maxsz + \@@ -284,7 +304,8 @@ static int nfs4_stat_to_errno(int); encode_getattr_maxsz + \ encode_restorefh_maxsz + \ encode_getattr_maxsz) -#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ +#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_savefh_maxsz + \ decode_open_maxsz + \@@ -301,43 +322,53 @@ static int nfs4_stat_to_errno(int); decode_putfh_maxsz + \ decode_open_confirm_maxsz)#define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_open_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_open_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_open_downgrade_sz \ (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_open_downgrade_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_open_downgrade_sz \ (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_open_downgrade_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_close_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_close_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_setattr_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_setattr_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_fsinfo_maxsz)#define NFS4_dec_fsinfo_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_fsinfo_maxsz)#define NFS4_enc_renew_sz (compound_encode_hdr_maxsz + \@@ -359,64 +390,81 @@ static int nfs4_stat_to_errno(int); decode_putrootfh_maxsz + \ decode_fsinfo_maxsz)#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_lock_maxsz)#define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_lock_maxsz)#define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_lockt_maxsz)#define NFS4_dec_lockt_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_lockt_maxsz)#define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_locku_maxsz)#define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_locku_maxsz)#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_access_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_access_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_lookup_maxsz + \ encode_getattr_maxsz + \ encode_getfh_maxsz)#define NFS4_dec_lookup_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_lookup_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz)#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putrootfh_maxsz + \ encode_getattr_maxsz + \ encode_getfh_maxsz)#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putrootfh_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz)#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_remove_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ op_decode_hdr_maxsz + 5 + \ decode_getattr_maxsz)#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_savefh_maxsz + \ encode_putfh_maxsz + \@@ -425,6 +473,7 @@ static int nfs4_stat_to_errno(int); encode_restorefh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_savefh_maxsz + \ decode_putfh_maxsz + \@@ -433,6 +482,7 @@ static int nfs4_stat_to_errno(int); decode_restorefh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_savefh_maxsz + \ encode_putfh_maxsz + \@@ -441,6 +491,7 @@ static int nfs4_stat_to_errno(int); encode_restorefh_maxsz + \ decode_getattr_maxsz)#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_savefh_maxsz + \ decode_putfh_maxsz + \@@ -449,16 +500,19 @@ static int nfs4_stat_to_errno(int); decode_restorefh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_symlink_maxsz + \ encode_getattr_maxsz + \ encode_getfh_maxsz)#define NFS4_dec_symlink_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_symlink_maxsz + \ decode_getattr_maxsz + \ decode_getfh_maxsz)#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_savefh_maxsz + \ encode_create_maxsz + \@@ -467,6 +521,7 @@ static int nfs4_stat_to_errno(int); encode_restorefh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_savefh_maxsz + \ decode_create_maxsz + \@@ -475,49 +530,63 @@ static int nfs4_stat_to_errno(int); decode_restorefh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_pathconf_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_statfs_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_statfs_maxsz)#define NFS4_dec_statfs_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_statfs_maxsz)#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_delegreturn_maxsz + \ encode_getattr_maxsz)#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_delegreturn_maxsz + \ decode_getattr_maxsz)#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_getacl_maxsz)#define NFS4_dec_getacl_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_getacl_maxsz)#define NFS4_enc_setacl_sz (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_setacl_maxsz)#define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_setacl_maxsz)#define NFS4_enc_fs_locations_sz \ (compound_encode_hdr_maxsz + \ + encode_sequence_maxsz + \ encode_putfh_maxsz + \ encode_lookup_maxsz + \ encode_fs_locations_maxsz)#define NFS4_dec_fs_locations_sz \ (compound_decode_hdr_maxsz + \ + decode_sequence_maxsz + \ decode_putfh_maxsz + \ decode_lookup_maxsz + \ decode_fs_locations_maxsz)@@ -543,6 +612,7 @@ struct compound_hdr {uint32_t nops;uint32_t taglen;char * tag; +u32 minorversion; };/* @@ -578,7 +648,7 @@ static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *xdr_encode_opaque (p, str, len); } -static __u32 * +static __be32 *encode_compound_hdr (struct xdr_stream *xdr,struct compound_hdr *hdr) {__be32 *p, *nops;@@ -588,7 +658,7 @@ encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)RESERVE_SPACE (12 +(XDR_QUADLEN (hdr->taglen)<<2 ));WRITE32 (hdr->taglen);WRITEMEM (hdr->tag, hdr->taglen); -WRITE32 (NFS4_MINOR_VERSION ); +WRITE32 (hdr->minorversion); nops = p;WRITE32 (hdr->nops);return nops;@@ -1377,7 +1447,8 @@ encode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr)static int encode_setattr (struct xdr_stream *xdr,const struct nfs_setattrargs *arg, -const struct nfs_server *server,struct compound_hdr *hdr) +const struct nfs_server *server, +struct compound_hdr *hdr) {int status;__be32 *p;@@ -1468,6 +1539,30 @@ encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid,return 0 ; } + +#if defined(CONFIG_NFS_V4_1 ) +/* NFSv4.1 operations */ +static int encode_sequence (struct xdr_stream *xdr, +const struct nfs41_sequence_args *args, +struct compound_hdr *hdr) +{ +if (hdr->minorversion ==0 ) +return 0 ; + +/* stub */ + hdr->nops++; + +return 0 ; +} +#else /* CONFIG_NFS_V4_1 */ +static inline int encode_sequence (struct xdr_stream *xdr, +const struct nfs41_sequence_args *args, +struct compound_hdr *hdr) +{ +return 0 ; +} +#endif /* CONFIG_NFS_V4_1 */ +/* * END OF "GENERIC" ENCODE ROUTINES. */ @@ -1475,17 +1570,19 @@ encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid,/* * Encode an ACCESS request */ -static int nfs4_xdr_enc_access (struct rpc_rqst *req,__be32 *p,const struct nfs4_accessargs *args) +static int nfs4_xdr_enc_access (struct rpc_rqst *req,__be32 *p, +const struct nfs4_accessargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status !=0 ) goto out;@@ -1501,17 +1598,19 @@ out:/* * Encode LOOKUP request */ -static int nfs4_xdr_enc_lookup (struct rpc_rqst *req,__be32 *p,const struct nfs4_lookup_arg *args) +static int nfs4_xdr_enc_lookup (struct rpc_rqst *req,__be32 *p, +const struct nfs4_lookup_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out;if ((status =encode_lookup (&xdr, args->name, &hdr)) !=0 )@@ -1527,17 +1626,19 @@ out:/* * Encode LOOKUP_ROOT request */ -static int nfs4_xdr_enc_lookup_root (struct rpc_rqst *req,__be32 *p,const struct nfs4_lookup_root_arg *args) +static int nfs4_xdr_enc_lookup_root (struct rpc_rqst *req,__be32 *p, +const struct nfs4_lookup_root_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putrootfh (&xdr, &hdr)) !=0 ) goto out;if ((status =encode_getfh (&xdr, &hdr)) ==0 )@@ -1550,17 +1651,19 @@ out:/* * Encode REMOVE request */ -static int nfs4_xdr_enc_remove (struct rpc_rqst *req,__be32 *p,const struct nfs_removeargs *args) +static int nfs4_xdr_enc_remove (struct rpc_rqst *req,__be32 *p, +const struct nfs_removeargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->fh, &hdr)) !=0 ) goto out;if ((status =encode_remove (&xdr, &args->name, &hdr)) !=0 )@@ -1574,17 +1677,19 @@ out:/* * Encode RENAME request */ -static int nfs4_xdr_enc_rename (struct rpc_rqst *req,__be32 *p,const struct nfs4_rename_arg *args) +static int nfs4_xdr_enc_rename (struct rpc_rqst *req,__be32 *p, +const struct nfs4_rename_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->old_dir, &hdr)) !=0 ) goto out;if ((status =encode_savefh (&xdr, &hdr)) !=0 )@@ -1607,17 +1712,19 @@ out:/* * Encode LINK request */ -static int nfs4_xdr_enc_link (struct rpc_rqst *req,__be32 *p,const struct nfs4_link_arg *args) +static int nfs4_xdr_enc_link (struct rpc_rqst *req,__be32 *p, +const struct nfs4_link_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->fh, &hdr)) !=0 ) goto out;if ((status =encode_savefh (&xdr, &hdr)) !=0 )@@ -1639,17 +1746,19 @@ out:/* * Encode CREATE request */ -static int nfs4_xdr_enc_create (struct rpc_rqst *req,__be32 *p,const struct nfs4_create_arg *args) +static int nfs4_xdr_enc_create (struct rpc_rqst *req,__be32 *p, +const struct nfs4_create_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out;if ((status =encode_savefh (&xdr, &hdr)) !=0 )@@ -1679,17 +1788,19 @@ static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, __be32 *p, const struct nf/* * Encode GETATTR request */ -static int nfs4_xdr_enc_getattr (struct rpc_rqst *req,__be32 *p,const struct nfs4_getattr_arg *args) +static int nfs4_xdr_enc_getattr (struct rpc_rqst *req,__be32 *p, +const struct nfs4_getattr_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->fh, &hdr)) ==0 ) status =encode_getfattr (&xdr, args->bitmask, &hdr);encode_nops (nops, &hdr);@@ -1699,17 +1810,19 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf/* * Encode a CLOSE request */ -static int nfs4_xdr_enc_close (struct rpc_rqst *req,__be32 *p,struct nfs_closeargs *args) +static int nfs4_xdr_enc_close (struct rpc_rqst *req,__be32 *p, +struct nfs_closeargs *args) { -struct xdr_stream xdr; -struct compound_hdr hdr = { - .nops =0 , - }; +struct xdr_stream xdr; +struct compound_hdr hdr = { + .minorversion = req->rq_task->tk_client->cl_mvers, + };int status;__be32 *nops; -xdr_init_encode (&xdr, &req->rq_snd_buf, p); +xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -1725,17 +1838,19 @@ out:/* * Encode an OPEN request */ -static int nfs4_xdr_enc_open (struct rpc_rqst *req,__be32 *p,struct nfs_openargs *args) +static int nfs4_xdr_enc_open (struct rpc_rqst *req,__be32 *p, +struct nfs_openargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -1767,7 +1882,7 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;@@ -1786,17 +1901,19 @@ out:/* * Encode an OPEN request with no attributes. */ -static int nfs4_xdr_enc_open_noattr (struct rpc_rqst *req,__be32 *p,struct nfs_openargs *args) +static int nfs4_xdr_enc_open_noattr (struct rpc_rqst *req,__be32 *p, +struct nfs_openargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -1812,17 +1929,19 @@ out:/* * Encode an OPEN_DOWNGRADE request */ -static int nfs4_xdr_enc_open_downgrade (struct rpc_rqst *req,__be32 *p,struct nfs_closeargs *args) +static int nfs4_xdr_enc_open_downgrade (struct rpc_rqst *req,__be32 *p, +struct nfs_closeargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -1838,17 +1957,19 @@ out:/* * Encode a LOCK request */ -static int nfs4_xdr_enc_lock (struct rpc_rqst *req,__be32 *p,struct nfs_lock_args *args) +static int nfs4_xdr_enc_lock (struct rpc_rqst *req,__be32 *p, +struct nfs_lock_args *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -1861,17 +1982,19 @@ out:/* * Encode a LOCKT request */ -static int nfs4_xdr_enc_lockt (struct rpc_rqst *req,__be32 *p,struct nfs_lockt_args *args) +static int nfs4_xdr_enc_lockt (struct rpc_rqst *req,__be32 *p, +struct nfs_lockt_args *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -1884,17 +2007,19 @@ out:/* * Encode a LOCKU request */ -static int nfs4_xdr_enc_locku (struct rpc_rqst *req,__be32 *p,struct nfs_locku_args *args) +static int nfs4_xdr_enc_locku (struct rpc_rqst *req,__be32 *p, +struct nfs_locku_args *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -1907,11 +2032,12 @@ out:/* * Encode a READLINK request */ -static int nfs4_xdr_enc_readlink (struct rpc_rqst *req,__be32 *p,const struct nfs4_readlink *args) +static int nfs4_xdr_enc_readlink (struct rpc_rqst *req,__be32 *p, +const struct nfs4_readlink *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;unsigned int replen;@@ -1920,6 +2046,7 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct nxdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -1941,11 +2068,12 @@ out:/* * Encode a READDIR request */ -static int nfs4_xdr_enc_readdir (struct rpc_rqst *req,__be32 *p,const struct nfs4_readdir_arg *args) +static int nfs4_xdr_enc_readdir (struct rpc_rqst *req,__be32 *p, +const struct nfs4_readdir_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;int replen;@@ -1954,6 +2082,7 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nfxdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -1978,18 +2107,20 @@ out:/* * Encode a READ request */ -static int nfs4_xdr_enc_read (struct rpc_rqst *req,__be32 *p,struct nfs_readargs *args) +static int nfs4_xdr_enc_read (struct rpc_rqst *req,__be32 *p, +struct nfs_readargs *args) {struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int replen, status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -2013,18 +2144,20 @@ out:/* * Encode an SETATTR request */ -static int nfs4_xdr_enc_setattr (struct rpc_rqst *req,__be32 *p,struct nfs_setattrargs *args) +static int nfs4_xdr_enc_setattr (struct rpc_rqst *req,__be32 *p, +struct nfs_setattrargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -2042,18 +2175,19 @@ out:*/ static int nfs4_xdr_enc_getacl (struct rpc_rqst *req,__be32 *p, -struct nfs_getaclargs *args) +struct nfs_getaclargs *args) {struct xdr_stream xdr;struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int replen, status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -2070,24 +2204,25 @@ out:/* * Encode a WRITE request */ -static int nfs4_xdr_enc_write (struct rpc_rqst *req,__be32 *p,struct nfs_writeargs *args) +static int nfs4_xdr_enc_write (struct rpc_rqst *req,__be32 *p, +struct nfs_writeargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; status =encode_write (&xdr, args, &hdr);if (status) goto out; - req->rq_snd_buf.flags |=XDRBUF_WRITE ; status =encode_getfattr (&xdr, args->bitmask, &hdr); out:encode_nops (nops, &hdr);@@ -2097,17 +2232,19 @@ out:/* * a COMMIT request */ -static int nfs4_xdr_enc_commit (struct rpc_rqst *req,__be32 *p,struct nfs_writeargs *args) +static int nfs4_xdr_enc_commit (struct rpc_rqst *req,__be32 *p, +struct nfs_writeargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out;@@ -2123,17 +2260,19 @@ out:/* * FSINFO request */ -static int nfs4_xdr_enc_fsinfo (struct rpc_rqst *req,__be32 *p,struct nfs4_fsinfo_arg *args) +static int nfs4_xdr_enc_fsinfo (struct rpc_rqst *req,__be32 *p, +struct nfs4_fsinfo_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (!status) status =encode_fsinfo (&xdr, args->bitmask, &hdr);@@ -2144,17 +2283,19 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsin/* * a PATHCONF request */ -static int nfs4_xdr_enc_pathconf (struct rpc_rqst *req,__be32 *p,const struct nfs4_pathconf_arg *args) +static int nfs4_xdr_enc_pathconf (struct rpc_rqst *req,__be32 *p, +const struct nfs4_pathconf_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (!status) status = encode_getattr_one(&xdr,@@ -2167,22 +2308,25 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct n/* * a STATFS request */ -static int nfs4_xdr_enc_statfs (struct rpc_rqst *req,__be32 *p,const struct nfs4_statfs_arg *args) +static int nfs4_xdr_enc_statfs (struct rpc_rqst *req,__be32 *p, +const struct nfs4_statfs_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status ==0 ) status =encode_getattr_two (&xdr, args->bitmask[0 ] & nfs4_statfs_bitmap[0 ], - args->bitmask[1 ] & nfs4_statfs_bitmap[1 ], &hdr); + args->bitmask[1 ] & nfs4_statfs_bitmap[1 ], + &hdr);encode_nops (nops, &hdr);return status; }@@ -2190,18 +2334,20 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs/* * GETATTR_BITMAP request */ -static int nfs4_xdr_enc_server_caps (struct rpc_rqst *req,__be32 *p,const struct nfs_fh *fhandle) +static int nfs4_xdr_enc_server_caps (struct rpc_rqst *req,__be32 *p, +struct nfs4_server_caps_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); - status =encode_putfh (&xdr, fhandle, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); + status =encode_putfh (&xdr, args->fhandle, &hdr);if (status ==0 ) status = encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS| FATTR4_WORD0_LINK_SUPPORT|@@ -2218,7 +2364,7 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;@@ -2226,6 +2372,7 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_clientxdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); status =encode_renew (&xdr, clp, &hdr); +encode_nops (nops, &hdr);return status; }@@ -2237,7 +2384,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4 {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;@@ -2245,6 +2392,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); status =encode_setclientid (&xdr, sc, &hdr); +encode_nops (nops, &hdr);return status; }@@ -2256,7 +2404,7 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };const u32 lease_bitmap[2 ] = {FATTR4_WORD0_LEASE_TIME ,0 };int status;@@ -2276,17 +2424,19 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str/* * DELEGRETURN request */ -static int nfs4_xdr_enc_delegreturn (struct rpc_rqst *req,__be32 *p,const struct nfs4_delegreturnargs *args) +static int nfs4_xdr_enc_delegreturn (struct rpc_rqst *req,__be32 *p, +const struct nfs4_delegreturnargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fhandle, &hdr);if (status !=0 ) goto out;@@ -2302,11 +2452,12 @@ out:/* * Encode FS_LOCATIONS request */ -static int nfs4_xdr_enc_fs_locations (struct rpc_rqst *req,__be32 *p,struct nfs4_fs_locations_arg *args) +static int nfs4_xdr_enc_fs_locations (struct rpc_rqst *req,__be32 *p, +struct nfs4_fs_locations_arg *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;int replen;@@ -2315,6 +2466,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfsxdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr);if ((status =encode_putfh (&xdr, args->dir_fh, &hdr)) !=0 ) goto out;if ((status =encode_lookup (&xdr, args->name, &hdr)) !=0 )@@ -2325,7 +2477,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs* toplevel_status + OP_PUTFH + status * + OP_LOOKUP + status + OP_GETATTR + status = 7 */ - replen = (RPC_REPHDRSIZE + auth->au_rslack +7 ) <<2 ; + replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_enc_fsinfo_sz) <<2 ;xdr_inline_pages (&req->rq_rcv_buf, replen, &args->page,0 ,PAGE_SIZE ); out:@@ -3963,19 +4115,48 @@ static int decode_delegreturn(struct xdr_stream *xdr)return decode_op_hdr (xdr,OP_DELEGRETURN ); } +#if defined(CONFIG_NFS_V4_1 ) +static int decode_sequence (struct xdr_stream *xdr, +struct nfs41_sequence_res *res, +struct rpc_rqst *rqstp) +{ +if (rqstp->rq_task->tk_client->cl_mvers ==0 ) +return 0 ; + +/* stub */ + +return 0 ; +} +#else /* CONFIG_NFS_V4_1 */ +static inline int decode_sequence (struct xdr_stream *xdr, +struct nfs41_sequence_res *res, +struct rpc_rqst *rqstp) +{ +return 0 ; +} +#endif /* CONFIG_NFS_V4_1 */ + +/* +* END OF "GENERIC" DECODE ROUTINES. +*/ +/* * Decode OPEN_DOWNGRADE response */ -static int nfs4_xdr_dec_open_downgrade (struct rpc_rqst *rqstp,__be32 *p,struct nfs_closeres *res) +static int nfs4_xdr_dec_open_downgrade (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_closeres *res) { -struct xdr_stream xdr; -struct compound_hdr hdr; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr; +int status; -xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); - status =decode_compound_hdr (&xdr, &hdr); -if (status) - goto out; +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -3988,20 +4169,21 @@ out: }/* -* END OF "GENERIC" DECODE ROUTINES. -*/ - -/* * Decode ACCESS response */ -static int nfs4_xdr_dec_access (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_accessres *res) +static int nfs4_xdr_dec_access (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_accessres *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out; status =decode_putfh (&xdr);if (status !=0 )@@ -4017,14 +4199,19 @@ out:/* * Decode LOOKUP response */ -static int nfs4_xdr_dec_lookup (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_lookup_res *res) +static int nfs4_xdr_dec_lookup (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_lookup_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;@@ -4040,14 +4227,19 @@ out:/* * Decode LOOKUP_ROOT response */ -static int nfs4_xdr_dec_lookup_root (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_lookup_res *res) +static int nfs4_xdr_dec_lookup_root (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_lookup_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putrootfh (&xdr)) !=0 ) goto out;@@ -4060,14 +4252,19 @@ out:/* * Decode REMOVE response */ -static int nfs4_xdr_dec_remove (struct rpc_rqst *rqstp,__be32 *p,struct nfs_removeres *res) +static int nfs4_xdr_dec_remove (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_removeres *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;@@ -4081,14 +4278,19 @@ out:/* * Decode RENAME response */ -static int nfs4_xdr_dec_rename (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_rename_res *res) +static int nfs4_xdr_dec_rename (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_rename_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status; - +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;@@ -4111,14 +4313,19 @@ out:/* * Decode LINK response */ -static int nfs4_xdr_dec_link (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_link_res *res) +static int nfs4_xdr_dec_link (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_link_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;@@ -4144,14 +4351,19 @@ out:/* * Decode CREATE response */ -static int nfs4_xdr_dec_create (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_create_res *res) +static int nfs4_xdr_dec_create (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_create_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status; - +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;@@ -4181,7 +4393,8 @@ static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_c/* * Decode GETATTR response */ -static int nfs4_xdr_dec_getattr (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_getattr_res *res) +static int nfs4_xdr_dec_getattr (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_getattr_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4191,56 +4404,65 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out; status =decode_getfattr (&xdr, res->fattr, res->server); out:return status; - }/* * Encode an SETACL request */ static int -nfs4_xdr_enc_setacl (struct rpc_rqst *req,__be32 *p,struct nfs_setaclargs *args) +nfs4_xdr_enc_setacl (struct rpc_rqst *req,__be32 *p, +struct nfs_setaclargs *args) {struct xdr_stream xdr;struct compound_hdr hdr = { - .nops =0 , + .minorversion = req->rq_task->tk_client->cl_mvers, };int status;__be32 *nops;xdr_init_encode (&xdr, &req->rq_snd_buf, p); nops =encode_compound_hdr (&xdr, &hdr); +encode_sequence (&xdr, &args->seq_args, &hdr); status =encode_putfh (&xdr, args->fh, &hdr);if (status) goto out; status =encode_setacl (&xdr, args, &hdr); out: -encode_nops (nops, &hdr);return status; } +/* * Decode SETACL response */ static int -nfs4_xdr_dec_setacl (struct rpc_rqst *rqstp,__be32 *p,void *res) +nfs4_xdr_dec_setacl (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_setaclres *res) {struct xdr_stream xdr;struct compound_hdr hdr; +struct nfs_setattrres *sattrp =NULL ;int status;xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out; - status =decode_setattr (&xdr, res); + status =decode_setattr (&xdr, sattrp); out:return status; }@@ -4249,7 +4471,8 @@ out:* Decode GETACL response */ static int -nfs4_xdr_dec_getacl (struct rpc_rqst *rqstp,__be32 *p,size_t *acl_len) +nfs4_xdr_dec_getacl (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_getaclres *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4259,10 +4482,13 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len) status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out; - status =decode_getacl (&xdr, rqstp, acl_len); + status =decode_getacl (&xdr, rqstp, res->acl_len); out:return status;@@ -4271,16 +4497,20 @@ out:/* * Decode CLOSE response */ -static int nfs4_xdr_dec_close (struct rpc_rqst *rqstp,__be32 *p,struct nfs_closeres *res) +static int nfs4_xdr_dec_close (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_closeres *res) { -struct xdr_stream xdr; -struct compound_hdr hdr; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr; +int status; -xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); - status =decode_compound_hdr (&xdr, &hdr); -if (status) - goto out; +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4301,16 +4531,20 @@ out:/* * Decode OPEN response */ -static int nfs4_xdr_dec_open (struct rpc_rqst *rqstp,__be32 *p,struct nfs_openres *res) +static int nfs4_xdr_dec_open (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_openres *res) { -struct xdr_stream xdr; -struct compound_hdr hdr; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr; +int status; -xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); - status =decode_compound_hdr (&xdr, &hdr); -if (status) - goto out; +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4355,16 +4589,20 @@ out:/* * Decode OPEN response */ -static int nfs4_xdr_dec_open_noattr (struct rpc_rqst *rqstp,__be32 *p,struct nfs_openres *res) +static int nfs4_xdr_dec_open_noattr (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_openres *res) { -struct xdr_stream xdr; -struct compound_hdr hdr; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr; +int status; -xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); - status =decode_compound_hdr (&xdr, &hdr); -if (status) - goto out; +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4379,16 +4617,20 @@ out:/* * Decode SETATTR response */ -static int nfs4_xdr_dec_setattr (struct rpc_rqst *rqstp,__be32 *p,struct nfs_setattrres *res) +static int nfs4_xdr_dec_setattr (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_setattrres *res) { -struct xdr_stream xdr; -struct compound_hdr hdr; -int status; +struct xdr_stream xdr; +struct compound_hdr hdr; +int status; -xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); - status =decode_compound_hdr (&xdr, &hdr); -if (status) - goto out; +xdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4405,7 +4647,8 @@ out:/* * Decode LOCK response */ -static int nfs4_xdr_dec_lock (struct rpc_rqst *rqstp,__be32 *p,struct nfs_lock_res *res) +static int nfs4_xdr_dec_lock (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_lock_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4415,6 +4658,9 @@ static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_ status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4426,7 +4672,8 @@ out:/* * Decode LOCKT response */ -static int nfs4_xdr_dec_lockt (struct rpc_rqst *rqstp,__be32 *p,struct nfs_lockt_res *res) +static int nfs4_xdr_dec_lockt (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_lockt_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4436,6 +4683,9 @@ static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4447,7 +4697,8 @@ out:/* * Decode LOCKU response */ -static int nfs4_xdr_dec_locku (struct rpc_rqst *rqstp,__be32 *p,struct nfs_locku_res *res) +static int nfs4_xdr_dec_locku (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_locku_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4457,6 +4708,9 @@ static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4468,7 +4722,8 @@ out:/* * Decode READLINK response */ -static int nfs4_xdr_dec_readlink (struct rpc_rqst *rqstp,__be32 *p,void *res) +static int nfs4_xdr_dec_readlink (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_readlink_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4478,6 +4733,9 @@ static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res) status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4489,7 +4747,8 @@ out:/* * Decode READDIR response */ -static int nfs4_xdr_dec_readdir (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_readdir_res *res) +static int nfs4_xdr_dec_readdir (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_readdir_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4499,6 +4758,9 @@ static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_r status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4510,7 +4772,8 @@ out:/* * Decode Read response */ -static int nfs4_xdr_dec_read (struct rpc_rqst *rqstp,__be32 *p,struct nfs_readres *res) +static int nfs4_xdr_dec_read (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_readres *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4520,6 +4783,9 @@ static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readr status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4533,7 +4799,8 @@ out:/* * Decode WRITE response */ -static int nfs4_xdr_dec_write (struct rpc_rqst *rqstp,__be32 *p,struct nfs_writeres *res) +static int nfs4_xdr_dec_write (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_writeres *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4543,6 +4810,9 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writ status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4559,7 +4829,8 @@ out:/* * Decode COMMIT response */ -static int nfs4_xdr_dec_commit (struct rpc_rqst *rqstp,__be32 *p,struct nfs_writeres *res) +static int nfs4_xdr_dec_commit (struct rpc_rqst *rqstp,__be32 *p, +struct nfs_writeres *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4569,6 +4840,9 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_wri status =decode_compound_hdr (&xdr, &hdr);if (status) goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) + goto out; status =decode_putfh (&xdr);if (status) goto out;@@ -4583,7 +4857,8 @@ out:/* * FSINFO request */ -static int nfs4_xdr_dec_fsinfo (struct rpc_rqst *req,__be32 *p,struct nfs_fsinfo *fsinfo) +static int nfs4_xdr_dec_fsinfo (struct rpc_rqst *req,__be32 *p, +struct nfs4_fsinfo_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4592,16 +4867,19 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfxdr_init_decode (&xdr, &req->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr);if (!status) + status =decode_sequence (&xdr, &res->seq_res, req); +if (!status) status =decode_putfh (&xdr);if (!status) - status =decode_fsinfo (&xdr, fsinfo); + status =decode_fsinfo (&xdr, res->fsinfo);return status; }/* * PATHCONF request */ -static int nfs4_xdr_dec_pathconf (struct rpc_rqst *req,__be32 *p,struct nfs_pathconf *pathconf) +static int nfs4_xdr_dec_pathconf (struct rpc_rqst *req,__be32 *p, +struct nfs4_pathconf_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4610,16 +4888,19 @@ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_patxdr_init_decode (&xdr, &req->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr);if (!status) + status =decode_sequence (&xdr, &res->seq_res, req); +if (!status) status =decode_putfh (&xdr);if (!status) - status =decode_pathconf (&xdr, pathconf); + status =decode_pathconf (&xdr, res->pathconf);return status; }/* * STATFS request */ -static int nfs4_xdr_dec_statfs (struct rpc_rqst *req,__be32 *p,struct nfs_fsstat *fsstat) +static int nfs4_xdr_dec_statfs (struct rpc_rqst *req,__be32 *p, +struct nfs4_statfs_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4628,23 +4909,30 @@ static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fsstaxdr_init_decode (&xdr, &req->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr);if (!status) + status =decode_sequence (&xdr, &res->seq_res, req); +if (!status) status =decode_putfh (&xdr);if (!status) - status =decode_statfs (&xdr, fsstat); + status =decode_statfs (&xdr, res->fsstat);return status; }/* * GETATTR_BITMAP request */ -static int nfs4_xdr_dec_server_caps (struct rpc_rqst *req,__be32 *p,struct nfs4_server_caps_res *res) +static int nfs4_xdr_dec_server_caps (struct rpc_rqst *req,__be32 *p, +struct nfs4_server_caps_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;int status;xdr_init_decode (&xdr, &req->rq_rcv_buf, p); -if ((status =decode_compound_hdr (&xdr, &hdr)) !=0 ) + status =decode_compound_hdr (&xdr, &hdr); +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, req); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;@@ -4709,7 +4997,8 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str/* * DELEGRETURN request */ -static int nfs4_xdr_dec_delegreturn (struct rpc_rqst *rqstp,__be32 *p,struct nfs4_delegreturnres *res) +static int nfs4_xdr_dec_delegreturn (struct rpc_rqst *rqstp,__be32 *p, +struct nfs4_delegreturnres *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4717,7 +5006,10 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nfxdr_init_decode (&xdr, &rqstp->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr); -if (status !=0 ) +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, rqstp); +if (status) goto out; status =decode_putfh (&xdr);if (status !=0 )@@ -4731,7 +5023,8 @@ out:/* * FS_LOCATIONS request */ -static int nfs4_xdr_dec_fs_locations (struct rpc_rqst *req,__be32 *p,struct nfs4_fs_locations *res) +static int nfs4_xdr_dec_fs_locations (struct rpc_rqst *req,__be32 *p, +struct nfs4_fs_locations_res *res) {struct xdr_stream xdr;struct compound_hdr hdr;@@ -4739,14 +5032,18 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfsxdr_init_decode (&xdr, &req->rq_rcv_buf, p); status =decode_compound_hdr (&xdr, &hdr); -if (status !=0 ) +if (status) + goto out; + status =decode_sequence (&xdr, &res->seq_res, req); +if (status) goto out;if ((status =decode_putfh (&xdr)) !=0 ) goto out;if ((status =decode_lookup (&xdr)) !=0 ) goto out;xdr_enter_page (&xdr,PAGE_SIZE ); - status =decode_getfattr (&xdr, &res->fattr, res->server); + status =decode_getfattr (&xdr, &res->fs_locations->fattr, + res->fs_locations->server); out:return status; }@@ -4877,10 +5174,10 @@ nfs4_stat_to_errno(int stat)#define PROC (proc, argtype, restype) \ [NFSPROC4_CLNT_##proc] = { \ .p_proc = NFSPROC4_COMPOUND, \ - .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \ - .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \ - .p_arglen = NFS4_##argtype##_sz, \ - .p_replen = NFS4_##restype##_sz, \ + .p_encode = (kxdrproc_t) nfs4##_xdr_##argtype, \ + .p_decode = (kxdrproc_t) nfs4##_xdr_##restype, \ + .p_arglen = NFS4##_##argtype##_sz, \ + .p_replen = NFS4##_##restype##_sz, \ .p_statidx = NFSPROC4_CLNT_##proc, \ .p_name = #proc, \ }@@ -4922,11 +5219,6 @@ struct rpc_procinfo nfs4_procedures[] = { PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), }; -#if defined(CONFIG_NFS_V4_1 ) -struct rpc_procinfo nfs41_procedures[] = { -}; -#endif /* CONFIG_NFS_V4_1 */ -struct rpc_version nfs_version4 = { .number =4 , .nrprocs =ARRAY_SIZE (nfs4_procedures),@@ -4936,8 +5228,9 @@ struct rpc_version nfs_version4 = {#ifdef CONFIG_NFS_V4_1 struct rpc_version nfs_version41 = { .number =4 , - .nrprocs =ARRAY_SIZE (nfs41_procedures), - .procs = nfs41_procedures + .minorversion =1 , + .nrprocs =ARRAY_SIZE (nfs4_procedures), + .procs = nfs4_procedures };#endif /* CONFIG_NFS_V4_1 */ include/linux/sunrpc/clnt.h +0
-0
include/linux/sunrpc/clnt.h struct rpc_clnt { · line 35
Quoted 4 lines
include/linux/sunrpc/clnt.h +1
-0@@ -32,6 +32,7 @@ struct rpc_clnt {struct rpc_procinfo * cl_procinfo;/* procedure info */ u32 cl_prog,/* RPC program number */ cl_vers,/* RPC version number */ + cl_mvers, /* RPC minorversion number */
review 11-14: this is problemtic.
Trond suggest passing a pointer to the nfs_server (as void *cl_private)
include/linux/sunrpc/clnt.h get_rpc_version(struct rpc_program *prog, u32 vers, int minorvers) · line 86
Quoted 8 lines
include/linux/sunrpc/clnt.h +1
-0cl_maxproc;/* max procedure number */ char * cl_server;/* server machine name */ @@ -82,6 +83,7 @@ get_rpc_version(struct rpc_program *prog, u32 vers, int minorvers)struct rpc_version {u32 number;/* version number */ +u32 minorversion;/* minorversion number */
review 11-14: remove this.
Quoted 23 lines
include/linux/sunrpc/clnt.h +0
-0unsigned int nrprocs;/* number of procs */ struct rpc_procinfo * procs;/* procedure array */ };net/sunrpc/clnt.c +2
-0@@ -177,6 +177,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru clnt->cl_protname = program->name; clnt->cl_prog = args->prognumber ? : program->number; clnt->cl_vers = version->number; + clnt->cl_mvers = version->minorversion; clnt->cl_stats = program->stats; clnt->cl_metrics =rpc_alloc_iostats (clnt); err = -ENOMEM ;@@ -491,6 +492,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old, clnt->cl_protname = program->name; clnt->cl_prog = program->number; clnt->cl_vers = version->number; + clnt->cl_mvers = version->minorversion; clnt->cl_stats = program->stats; err =rpc_ping (clnt,RPC_TASK_SOFT );if (err !=0 ) {
RFC 24/85 nfs41: stubs for nfs41 procedures
In reply to Benny Halevy--- fs/nfs/nfs4_fs.h | 2 ++ fs/nfs/nfs4proc.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 0 deletions(-)
fs/nfs/nfs4_fs.h +2 -0
@@ -192,6 +192,8 @@ extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;extern void nfs4_put_session (struct nfs4_session **session);extern void nfs4_get_session (struct nfs_client *clp);extern struct nfs4_session *nfs4_alloc_session (void ); +extern int nfs4_proc_create_session (struct nfs4_session *); +extern int nfs4_proc_destroy_session (struct nfs4_session *);#endif /* CONFIG_NFS_V4_1 */ extern const u32 nfs4_fattr_bitmap[2 ];
fs/nfs/nfs4proc.c +26 -0
@@ -3825,6 +3825,11 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, }#ifdef CONFIG_NFS_V4_1 +static int nfs4_proc_exchange_id (struct nfs_client *clp,struct rpc_cred *cred) +{ +return -1 ;/* stub */ +} +/* * Initialize slot table *
@@ -3947,6 +3952,27 @@ void nfs4_get_session(struct nfs_client *clp)if (clp->cl_minorversion ==1 )atomic_inc (&clp->cl_session->ref_count); } + +int nfs4_proc_create_session (struct nfs4_session *session) +{ +return -1 ;/* stub */ +} + +int nfs4_proc_destroy_session (struct nfs4_session *session) +{ +return -1 ;/* stub */ +} + +static int nfs4_proc_sequence (struct nfs_client *clp,struct rpc_cred *cred) +{ +return -1 ;/* stub */ +} + +static int nfs41_proc_async_sequence (struct nfs_client *clp, +struct rpc_cred *cred) +{ +return -1 ;/* stub */ +}#endif /* CONFIG_NFS_V4_1 */ struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
Signature · 1 line
1.6.0.2
RFC 25/85 nfs41: make nfs4_wait_bit_killable public
In reply to Benny HalevyFrom: Rahul Iyer <[email protected]>
nfs4_wait_bit_killable to be used by NFSv4.1 session recover logic.
--- fs/nfs/nfs4_fs.h | 1 + fs/nfs/nfs4proc.c | 2 +- 2 files changed, 2 insertions(+), 1 deletions(-)
fs/nfs/nfs4_fs.h +1 -0
@@ -179,6 +179,7 @@ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, strucextern int nfs4_proc_setclientid_confirm (struct nfs_client *,struct rpc_cred *);extern int nfs4_proc_async_renew (struct nfs_client *,struct rpc_cred *);extern int nfs4_proc_renew (struct nfs_client *,struct rpc_cred *); +extern int nfs4_wait_bit_killable (void *);extern int nfs4_do_close (struct path *path,struct nfs4_state *state,int wait);extern struct dentry *nfs4_atomic_open (struct inode *,struct dentry *,struct nameidata *);extern int nfs4_open_revalidate (struct inode *,struct dentry *,int ,struct nameidata *);
fs/nfs/nfs4proc.c +1 -1
@@ -2929,7 +2929,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)return 0 ; } -static int nfs4_wait_bit_killable (void *word) +int nfs4_wait_bit_killable (void *word) {if (fatal_signal_pending (current))return -ERESTARTSYS ;
Signature · 1 line
1.6.0.2
RFC 26/85 nfs41: introduce nfs4_call_sync
In reply to Benny HalevyUse nfs4_call_sync rather than rpc_call_sync to provide for a nfs41 sessions-enabled interface for sessions manipulation.
The nfs41 rpc logic uses the rpc_call_validate_args method to recover and create the session, as well as selecting a free slot id and the rpc_call_done to free the slot and update slot table related metadata.
--- fs/nfs/nfs4proc.c | 127 ++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 96 insertions(+), 31 deletions(-)
fs/nfs/nfs4proc.c +96 -31
@@ -349,6 +349,19 @@ nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)#endif /* CONFIG_NFS_V4_1 */ +static int _nfs4_call_sync (struct nfs_server *server, +struct rpc_message *msg, +struct nfs41_sequence_args *args, +struct nfs41_sequence_res *res, +int cache_reply) +{ +return rpc_call_sync (server->client, msg,0 ); +} + +#define nfs4_call_sync (server, msg, args, res, cache_reply) \ + _nfs4_call_sync((server), (msg), &(args)->seq_args, \ + &(res)->seq_res, (cache_reply)) +static void update_changeattr (struct inode *dir,struct nfs4_change_info *cinfo) {struct nfs_inode *nfsi =NFS_I (dir);
@@ -1318,7 +1331,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, }else memcpy (&arg.stateid, &zero_stateid,sizeof (arg.stateid)); - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &arg, &res,1 );if (status ==0 && state !=NULL )renew_lease (server, timestamp);return status;
@@ -1620,15 +1633,19 @@ out_drop:static int _nfs4_server_capabilities (struct nfs_server *server,struct nfs_fh *fhandle) { +struct nfs4_server_caps_arg args = { + .fhandle = fhandle, + };struct nfs4_server_caps_res res = {};struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_SERVER_CAPS ), - .rpc_argp = fhandle, + .rpc_argp = &args, .rpc_resp = &res, };int status; - status =rpc_call_sync (server->client, &msg,0 ); +dprintk ("--> %s\n" , __func__); + status =nfs4_call_sync (server, &msg, &args, &res,0 );if (status ==0 ) {memcpy (server->attr_bitmask, res.attr_bitmask,sizeof (server->attr_bitmask));if (res.attr_bitmask[0 ] &FATTR4_WORD0_ACL )
@@ -1639,6 +1656,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f server->caps |=NFS_CAP_SYMLINKS ; server->acl_bitmask = res.acl_bitmask; } + +dprintk ("<-- %s status= %d\n" , __func__, status);return status; }
@@ -1670,8 +1689,13 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, .rpc_argp = &args, .rpc_resp = &res, }; +int status; + +dprintk ("--> %s\n" , __func__);nfs_fattr_init (info->fattr); -return rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 ); +dprintk ("<-- %s status= %d\n" , __func__, status); +return status; } static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -1759,9 +1783,12 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, .rpc_argp = &args, .rpc_resp = &res, }; +int status;nfs_fattr_init (fattr); -return rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 ); + +return status; }static int nfs4_proc_getattr (struct nfs_server *server,struct nfs_fh *fhandle,struct nfs_fattr *fattr)
@@ -1843,10 +1870,10 @@ static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *d };nfs_fattr_init (fattr); -dprintk ("NFS call lookupfh %s\n" , name->name); - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 );dprintk ("NFS reply lookupfh: %d\n" , status); +return status; }
@@ -1931,7 +1958,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry args.access |=NFS4_ACCESS_EXECUTE ; }nfs_fattr_init (&fattr); - status =rpc_call_sync (NFS_CLIENT (inode), &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 );if (!status) { entry->mask =0 ;if (res.access &NFS4_ACCESS_READ )
@@ -1991,13 +2018,17 @@ static int _nfs4_proc_readlink(struct inode *inode, struct page *page, .pglen = pglen, .pages = &page, }; +struct nfs4_readlink_res res;struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_READLINK ), .rpc_argp = &args, - .rpc_resp =NULL , + .rpc_resp = &res, }; +int status; + + status =nfs4_call_sync (server, &msg, &args, &res,0 ); -return rpc_call_sync (NFS_CLIENT (inode), &msg,0 ); +return status; } static int nfs4_proc_readlink(struct inode *inode, struct page *page,
@@ -2090,11 +2121,12 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)int status;nfs_fattr_init (&res.dir_attr); - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,1 );if (status ==0 ) {update_changeattr (dir, &res.cinfo);nfs_post_op_update_inode (dir, &res.dir_attr); } +return status; }
@@ -2158,14 +2190,14 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,nfs_fattr_init (res.old_fattr);nfs_fattr_init (res.new_fattr); - status =rpc_call_sync (server->client, &msg,0 ); - + status =nfs4_call_sync (server, &msg, &arg, &res,1 );if (!status) {update_changeattr (old_dir, &res.old_cinfo);nfs_post_op_update_inode (old_dir, res.old_fattr);update_changeattr (new_dir, &res.new_cinfo);nfs_post_op_update_inode (new_dir, res.new_fattr); } +return status; }
@@ -2207,7 +2239,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *nfs_fattr_init (res.fattr);nfs_fattr_init (res.dir_attr); - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &arg, &res,1 );if (!status) {update_changeattr (dir, &res.cinfo);nfs_post_op_update_inode (dir, res.dir_attr);
@@ -2269,7 +2301,9 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,static int nfs4_do_create (struct inode *dir,struct dentry *dentry,struct nfs4_createdata *data) { -int status =rpc_call_sync (NFS_CLIENT (dir), &data->msg,0 ); +struct nfs_server *server =NFS_SERVER (dir); +int status =nfs4_call_sync (server, &data->msg, + &data->arg, &data->res,1 );if (status ==0 ) {update_changeattr (dir, &data->res.dir_cinfo);nfs_post_op_update_inode (dir, data->res.dir_fattr);
@@ -2378,12 +2412,14 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long long)cookie); +nfs4_setup_readdir (cookie,NFS_COOKIEVERF (dir), dentry, &args); res.pgbase = args.pgbase; - status =rpc_call_sync (NFS_CLIENT (dir), &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 );if (status ==0 )memcpy (NFS_COOKIEVERF (dir), res.verifier.data,NFS4_VERIFIER_SIZE ); +nfs_invalidate_atime (dir);dprintk ("%s: returns %d\n" , __func__, status);
@@ -2458,14 +2494,20 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, .fh = fhandle, .bitmask = server->attr_bitmask, }; +struct nfs4_statfs_res res = { + .fsstat = fsstat, + };struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_STATFS ), .rpc_argp = &args, - .rpc_resp = fsstat, + .rpc_resp = &res, }; +int status;nfs_fattr_init (fsstat->fattr); -return rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 ); + +return status; }static int nfs4_proc_statfs (struct nfs_server *server,struct nfs_fh *fhandle,struct nfs_fsstat *fsstat)
@@ -2487,13 +2529,21 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, .fh = fhandle, .bitmask = server->attr_bitmask, }; +struct nfs4_fsinfo_res res = { + .fsinfo = fsinfo, + };struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_FSINFO ), .rpc_argp = &args, - .rpc_resp = fsinfo, + .rpc_resp = &res, }; +int status; + +dprintk ("--> %s\n" , __func__); + status =nfs4_call_sync (server, &msg, &args, &res,0 ); -return rpc_call_sync (server->client, &msg,0 ); +dprintk ("<-- %s status= %d\n" , __func__, status); +return status; }static int nfs4_do_fsinfo (struct nfs_server *server,struct nfs_fh *fhandle,struct nfs_fsinfo *fsinfo)
@@ -2522,20 +2572,28 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle .fh = fhandle, .bitmask = server->attr_bitmask, }; +struct nfs4_pathconf_res res = { + .pathconf = pathconf, + };struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_PATHCONF ), .rpc_argp = &args, - .rpc_resp = pathconf, + .rpc_resp = &res, }; +int status =0 ; +dprintk ("--> %s\n" , __func__);/* None of the pathconf attributes are mandatory to implement */ if ((args.bitmask[0 ] & nfs4_pathconf_bitmap[0 ]) ==0 ) {memset (pathconf,0 ,sizeof (*pathconf)); -return 0 ; + goto out; }nfs_fattr_init (pathconf->fattr); -return rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 ); +out: +dprintk ("<-- %s status= %d\n" , __func__, status); +return status; } static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -2778,18 +2836,21 @@ out:static ssize_t __nfs4_get_acl_uncached (struct inode *inode,void *buf,size_t buflen) {struct page *pages[NFS4ACL_MAXPAGES ]; +size_t resp_len = buflen;struct nfs_getaclargs args = { .fh =NFS_FH (inode), .acl_pages = pages, .acl_len = buflen, }; -size_t resp_len = buflen; +struct nfs_getaclres res = { + .acl_len = &resp_len, + };void *resp_buf;struct nfs_server *server =NFS_SERVER (inode);struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_GETACL ), .rpc_argp = &args, - .rpc_resp = &resp_len, + .rpc_resp = &res, };struct page *localpage =NULL ;int ret;
@@ -2808,7 +2869,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu resp_buf = buf;buf_to_pages (buf, buflen, args.acl_pages, &args.acl_pgbase); } - ret =rpc_call_sync (NFS_CLIENT (inode), &msg,0 ); + ret =nfs4_call_sync (server, &msg, &args, &res,0 );if (ret) goto out_free;if (resp_len > args.acl_len)
@@ -2869,10 +2930,11 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl .acl_pages = pages, .acl_len = buflen, }; +struct nfs_setaclres res;struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_SETACL ), .rpc_argp = &arg, - .rpc_resp =NULL , + .rpc_resp = &res, };int ret;
@@ -2880,7 +2942,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflreturn -EOPNOTSUPP ;nfs_inode_return_delegation (inode);buf_to_pages (buf, buflen, arg.acl_pages, &arg.acl_pgbase); - ret =rpc_call_sync (NFS_CLIENT (inode), &msg,0 ); + ret =nfs4_call_sync (server, &msg, &arg, &res,1 );nfs_access_zap_cache (inode);nfs_zap_acl_cache (inode);return ret;
@@ -3240,7 +3302,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock goto out; lsp = request->fl_u.nfs4_fl.owner; arg.lock_owner.id = lsp->ls_id.id; - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &arg, &res,1 );switch (status) {case 0 : request->fl_type =F_UNLCK ;
@@ -3808,10 +3870,13 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, .page = page, .bitmask = bitmask, }; +struct nfs4_fs_locations_res res = { + .fs_locations = fs_locations, + };struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_FS_LOCATIONS ), .rpc_argp = &args, - .rpc_resp = fs_locations, + .rpc_resp = &res, };int status;
@@ -3819,7 +3884,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,nfs_fattr_init (&fs_locations->fattr); fs_locations->server = server; fs_locations->nlocations =0 ; - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 );dprintk ("%s: returned status = %d\n" , __func__, status);return status; }
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 26/85] nfs41: introduce nfs4_call_sync
Quoted 9 lines · Benny Halevy
Use
nfs4_call_syncrather thanrpc_call_syncto provide for a nfs41 sessions-enabled interface for sessions manipulation.The nfs41 rpc logic uses the
rpc_call_validate_argsmethod to recover and create the session, as well as selecting a free slot id and therpc_call_doneto free the slot and update slot table related metadata.Signed-off-by Benny Halevy <[email protected]>
review 11-14: define two functions one for v4 and one for v41 add a pointer to struct nfs4_client to the correct one.
Quoted 373 lines
--- fs/nfs/nfs4proc.c | 127 ++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 96 insertions(+), 31 deletions(-)fs/nfs/nfs4proc.c +96
-31@@ -349,6 +349,19 @@ nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)#endif /* CONFIG_NFS_V4_1 */ +static int _nfs4_call_sync (struct nfs_server *server, +struct rpc_message *msg, +struct nfs41_sequence_args *args, +struct nfs41_sequence_res *res, +int cache_reply) +{ +return rpc_call_sync (server->client, msg,0 ); +} + +#define nfs4_call_sync (server, msg, args, res, cache_reply) \ + _nfs4_call_sync((server), (msg), &(args)->seq_args, \ + &(res)->seq_res, (cache_reply)) +static void update_changeattr (struct inode *dir,struct nfs4_change_info *cinfo) {struct nfs_inode *nfsi =NFS_I (dir);@@ -1318,7 +1331,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, }else memcpy (&arg.stateid, &zero_stateid,sizeof (arg.stateid)); - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &arg, &res,1 );if (status ==0 && state !=NULL )renew_lease (server, timestamp);return status;@@ -1620,15 +1633,19 @@ out_drop:static int _nfs4_server_capabilities (struct nfs_server *server,struct nfs_fh *fhandle) { +struct nfs4_server_caps_arg args = { + .fhandle = fhandle, + };struct nfs4_server_caps_res res = {};struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_SERVER_CAPS ), - .rpc_argp = fhandle, + .rpc_argp = &args, .rpc_resp = &res, };int status; - status =rpc_call_sync (server->client, &msg,0 ); +dprintk ("--> %s\n" , __func__); + status =nfs4_call_sync (server, &msg, &args, &res,0 );if (status ==0 ) {memcpy (server->attr_bitmask, res.attr_bitmask,sizeof (server->attr_bitmask));if (res.attr_bitmask[0 ] &FATTR4_WORD0_ACL )@@ -1639,6 +1656,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f server->caps |=NFS_CAP_SYMLINKS ; server->acl_bitmask = res.acl_bitmask; } + +dprintk ("<-- %s status= %d\n" , __func__, status);return status; }@@ -1670,8 +1689,13 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, .rpc_argp = &args, .rpc_resp = &res, }; +int status; + +dprintk ("--> %s\n" , __func__);nfs_fattr_init (info->fattr); -return rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 ); +dprintk ("<-- %s status= %d\n" , __func__, status); +return status; } static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,@@ -1759,9 +1783,12 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, .rpc_argp = &args, .rpc_resp = &res, }; +int status;nfs_fattr_init (fattr); -return rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 ); + +return status; }static int nfs4_proc_getattr (struct nfs_server *server,struct nfs_fh *fhandle,struct nfs_fattr *fattr)@@ -1843,10 +1870,10 @@ static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *d };nfs_fattr_init (fattr); -dprintk ("NFS call lookupfh %s\n" , name->name); - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 );dprintk ("NFS reply lookupfh: %d\n" , status); +return status; }@@ -1931,7 +1958,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry args.access |=NFS4_ACCESS_EXECUTE ; }nfs_fattr_init (&fattr); - status =rpc_call_sync (NFS_CLIENT (inode), &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 );if (!status) { entry->mask =0 ;if (res.access &NFS4_ACCESS_READ )@@ -1991,13 +2018,17 @@ static int _nfs4_proc_readlink(struct inode *inode, struct page *page, .pglen = pglen, .pages = &page, }; +struct nfs4_readlink_res res;struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_READLINK ), .rpc_argp = &args, - .rpc_resp =NULL , + .rpc_resp = &res, }; +int status; + + status =nfs4_call_sync (server, &msg, &args, &res,0 ); -return rpc_call_sync (NFS_CLIENT (inode), &msg,0 ); +return status; } static int nfs4_proc_readlink(struct inode *inode, struct page *page,@@ -2090,11 +2121,12 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)int status;nfs_fattr_init (&res.dir_attr); - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,1 );if (status ==0 ) {update_changeattr (dir, &res.cinfo);nfs_post_op_update_inode (dir, &res.dir_attr); } +return status; }@@ -2158,14 +2190,14 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,nfs_fattr_init (res.old_fattr);nfs_fattr_init (res.new_fattr); - status =rpc_call_sync (server->client, &msg,0 ); - + status =nfs4_call_sync (server, &msg, &arg, &res,1 );if (!status) {update_changeattr (old_dir, &res.old_cinfo);nfs_post_op_update_inode (old_dir, res.old_fattr);update_changeattr (new_dir, &res.new_cinfo);nfs_post_op_update_inode (new_dir, res.new_fattr); } +return status; }@@ -2207,7 +2239,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *nfs_fattr_init (res.fattr);nfs_fattr_init (res.dir_attr); - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &arg, &res,1 );if (!status) {update_changeattr (dir, &res.cinfo);nfs_post_op_update_inode (dir, res.dir_attr);@@ -2269,7 +2301,9 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,static int nfs4_do_create (struct inode *dir,struct dentry *dentry,struct nfs4_createdata *data) { -int status =rpc_call_sync (NFS_CLIENT (dir), &data->msg,0 ); +struct nfs_server *server =NFS_SERVER (dir); +int status =nfs4_call_sync (server, &data->msg, + &data->arg, &data->res,1 );if (status ==0 ) {update_changeattr (dir, &data->res.dir_cinfo);nfs_post_op_update_inode (dir, data->res.dir_fattr);@@ -2378,12 +2412,14 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long long)cookie); +nfs4_setup_readdir (cookie,NFS_COOKIEVERF (dir), dentry, &args); res.pgbase = args.pgbase; - status =rpc_call_sync (NFS_CLIENT (dir), &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 );if (status ==0 )memcpy (NFS_COOKIEVERF (dir), res.verifier.data,NFS4_VERIFIER_SIZE ); +nfs_invalidate_atime (dir);dprintk ("%s: returns %d\n" , __func__, status);@@ -2458,14 +2494,20 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, .fh = fhandle, .bitmask = server->attr_bitmask, }; +struct nfs4_statfs_res res = { + .fsstat = fsstat, + };struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_STATFS ), .rpc_argp = &args, - .rpc_resp = fsstat, + .rpc_resp = &res, }; +int status;nfs_fattr_init (fsstat->fattr); -return rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 ); + +return status; }static int nfs4_proc_statfs (struct nfs_server *server,struct nfs_fh *fhandle,struct nfs_fsstat *fsstat)@@ -2487,13 +2529,21 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, .fh = fhandle, .bitmask = server->attr_bitmask, }; +struct nfs4_fsinfo_res res = { + .fsinfo = fsinfo, + };struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_FSINFO ), .rpc_argp = &args, - .rpc_resp = fsinfo, + .rpc_resp = &res, }; +int status; + +dprintk ("--> %s\n" , __func__); + status =nfs4_call_sync (server, &msg, &args, &res,0 ); -return rpc_call_sync (server->client, &msg,0 ); +dprintk ("<-- %s status= %d\n" , __func__, status); +return status; }static int nfs4_do_fsinfo (struct nfs_server *server,struct nfs_fh *fhandle,struct nfs_fsinfo *fsinfo)@@ -2522,20 +2572,28 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle .fh = fhandle, .bitmask = server->attr_bitmask, }; +struct nfs4_pathconf_res res = { + .pathconf = pathconf, + };struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_PATHCONF ), .rpc_argp = &args, - .rpc_resp = pathconf, + .rpc_resp = &res, }; +int status =0 ; +dprintk ("--> %s\n" , __func__);/* None of the pathconf attributes are mandatory to implement */ if ((args.bitmask[0 ] & nfs4_pathconf_bitmap[0 ]) ==0 ) {memset (pathconf,0 ,sizeof (*pathconf)); -return 0 ; + goto out; }nfs_fattr_init (pathconf->fattr); -return rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 ); +out: +dprintk ("<-- %s status= %d\n" , __func__, status); +return status; } static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,@@ -2778,18 +2836,21 @@ out:static ssize_t __nfs4_get_acl_uncached (struct inode *inode,void *buf,size_t buflen) {struct page *pages[NFS4ACL_MAXPAGES ]; +size_t resp_len = buflen;struct nfs_getaclargs args = { .fh =NFS_FH (inode), .acl_pages = pages, .acl_len = buflen, }; -size_t resp_len = buflen; +struct nfs_getaclres res = { + .acl_len = &resp_len, + };void *resp_buf;struct nfs_server *server =NFS_SERVER (inode);struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_GETACL ), .rpc_argp = &args, - .rpc_resp = &resp_len, + .rpc_resp = &res, };struct page *localpage =NULL ;int ret;@@ -2808,7 +2869,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu resp_buf = buf;buf_to_pages (buf, buflen, args.acl_pages, &args.acl_pgbase); } - ret =rpc_call_sync (NFS_CLIENT (inode), &msg,0 ); + ret =nfs4_call_sync (server, &msg, &args, &res,0 );if (ret) goto out_free;if (resp_len > args.acl_len)@@ -2869,10 +2930,11 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl .acl_pages = pages, .acl_len = buflen, }; +struct nfs_setaclres res;struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_SETACL ), .rpc_argp = &arg, - .rpc_resp =NULL , + .rpc_resp = &res, };int ret;@@ -2880,7 +2942,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflreturn -EOPNOTSUPP ;nfs_inode_return_delegation (inode);buf_to_pages (buf, buflen, arg.acl_pages, &arg.acl_pgbase); - ret =rpc_call_sync (NFS_CLIENT (inode), &msg,0 ); + ret =nfs4_call_sync (server, &msg, &arg, &res,1 );nfs_access_zap_cache (inode);nfs_zap_acl_cache (inode);return ret;@@ -3240,7 +3302,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock goto out; lsp = request->fl_u.nfs4_fl.owner; arg.lock_owner.id = lsp->ls_id.id; - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &arg, &res,1 );switch (status) {case 0 : request->fl_type =F_UNLCK ;@@ -3808,10 +3870,13 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, .page = page, .bitmask = bitmask, }; +struct nfs4_fs_locations_res res = { + .fs_locations = fs_locations, + };struct rpc_message msg = { .rpc_proc =nfs4_proc (server->nfs_client,NFSPROC4_CLNT_FS_LOCATIONS ), .rpc_argp = &args, - .rpc_resp = fs_locations, + .rpc_resp = &res, };int status;@@ -3819,7 +3884,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,nfs_fattr_init (&fs_locations->fattr); fs_locations->server = server; fs_locations->nlocations =0 ; - status =rpc_call_sync (server->client, &msg,0 ); + status =nfs4_call_sync (server, &msg, &args, &res,0 );dprintk ("%s: returned status = %d\n" , __func__, status);return status; }
RFC 27/85 nfs41: nfs4_setup_sequence
In reply to Benny HalevyPerform the nfs4_setup_sequence in the rpc_call_prepare state.
If a session slot is not available, we will rpc_sleep_on the slot wait queue leaving the tk_action as rpc_call_prepare.
Once we have a session slot, hang on to it even through rpc_restart_calls. Ensure the nfs41_sequence_res sr_slot pointer is NULL before rpc_run_task is called as nfs41_setup_sequence will only find a new slot if it is NULL.
A future patch will call free slot after any rpc_restart_calls, and handle the rpc restart that result from a sequence operation error.
nfs41: simplify nfs4_call_sync
--- fs/nfs/nfs4proc.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs_xdr.h | 2 +- 2 files changed, 94 insertions(+), 1 deletions(-)
fs/nfs/nfs4proc.c +93 -0
@@ -347,6 +347,70 @@ nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)return slot; } +static int nfs41_setup_sequence (struct nfs4_session *session, +struct nfs41_sequence_args *args, +struct nfs41_sequence_res *res, +int cache_reply, +struct rpc_task *task) +{ +/* stub */ +return 0 ; +} + +int nfs4_setup_sequence (struct nfs_client *clp, +struct nfs41_sequence_args *args, +struct nfs41_sequence_res *res, +int cache_reply, +struct rpc_task *task) +{ +int ret =0 ; + +dprintk ("--> %s clp %p session %p cl_minorversion %d res->sr_slot %p\n" , + __func__, clp, clp->cl_session, clp->cl_minorversion, + res->sr_slot); + +if (clp->cl_minorversion ==0 || res->sr_slot) + goto out; +BUG_ON (clp->cl_minorversion !=1 ); + ret =nfs41_setup_sequence (clp->cl_session, args, res, + cache_reply, task); +if (ret) { +memset (res,0 ,sizeof (*res)); +if (ret != -EAGAIN ) { +/* terminate rpc task */ + task->tk_status = ret; + task->tk_action =NULL ; + } + } +out: +dprintk ("<-- %s status=%d\n" , __func__, ret); +return ret; +} + +struct nfs41_call_sync_data { +struct nfs_server *server; +struct rpc_message *msg; +struct nfs41_sequence_args *seq_args; +struct nfs41_sequence_res *seq_res; +int cache_reply; +}; + +static void nfs41_call_sync_prepare (struct rpc_task *task,void *calldata) +{ +struct nfs41_call_sync_data *data = calldata; + +dprintk ("--> %s data->server->session %p\n" , __func__, + data->server->nfs_client->cl_session); +if (nfs4_setup_sequence (data->server->nfs_client, data->seq_args, + data->seq_res, data->cache_reply, task)) +return ; +rpc_call_start (task); +} + +struct rpc_call_ops nfs41_call_sync_ops = { + .rpc_call_prepare = nfs41_call_sync_prepare, +}; +#endif /* CONFIG_NFS_V4_1 */ static int _nfs4_call_sync(struct nfs_server *server,
@@ -355,6 +419,35 @@ static int _nfs4_call_sync(struct nfs_server *server, struct nfs41_sequence_res *res, int cache_reply) { +#ifdef CONFIG_NFS_V4_1 +if (server->nfs_client->cl_minorversion) { +int ret; +struct rpc_task *task; +struct nfs41_call_sync_data data = { + .server = server, + .msg = msg, + .seq_args = args, + .seq_res = res, + .cache_reply = cache_reply, + }; +struct rpc_task_setup task_setup = { + .rpc_client = server->client, + .rpc_message = msg, + .callback_ops = &nfs41_call_sync_ops, + .callback_data = &data + }; + + res->sr_slot =NULL ; + task =rpc_run_task (&task_setup); +if (IS_ERR (task)) + ret =PTR_ERR (task); +else { + ret = task->tk_status; +rpc_put_task (task); + } +return ret; + } +#endif /* CONFIG_NFS_V4_1 */ return rpc_call_sync (server->client, msg,0 ); }
include/linux/nfs_xdr.h +1 -1
@@ -134,7 +134,7 @@ struct nfs41_sequence_args {#define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100struct nfs41_sequence_res { -/* stub */ +struct nfs4_slot *sr_slot;/* slot used to send request */ };#if defined(CONFIG_NFS_V4_1 )
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 27/85] nfs41: nfs4_setup_sequence
Quoted 122 lines · Benny Halevy
Perform the
nfs4_setup_sequencein therpc_call_preparestate.If a session slot is not available, we will
rpc_sleep_onthe slot wait queue leaving thetk_actionasrpc_call_prepare.Once we have a session slot, hang on to it even through
rpc_restart_calls. Ensure thenfs41_sequence_ressr_slotpointer is NULL beforerpc_run_taskis called asnfs41_setup_sequencewill only find a new slot if it is NULL.A future patch will call free slot after any
rpc_restart_calls, and handle the rpc restart that result from a sequence operation error.Signed-off-by Rahul Iyer <[email protected]>Signed-off-by Andy Adamson<[email protected]>Signed-off-by Benny Halevy <[email protected]>nfs41: simplify
nfs4_call_syncSigned-off-by Benny Halevy <[email protected]>--- fs/nfs/nfs4proc.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs_xdr.h | 2 +- 2 files changed, 94 insertions(+), 1 deletions(-)fs/nfs/nfs4proc.c +83
-0@@ -347,6 +347,70 @@ nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)return slot; } +static int nfs41_setup_sequence (struct nfs4_session *session, +struct nfs41_sequence_args *args, +struct nfs41_sequence_res *res, +int cache_reply, +struct rpc_task *task) +{ +/* stub */ +return 0 ; +} + +int nfs4_setup_sequence (struct nfs_client *clp, +struct nfs41_sequence_args *args, +struct nfs41_sequence_res *res, +int cache_reply, +struct rpc_task *task) +{ +int ret =0 ; + +dprintk ("--> %s clp %p session %p cl_minorversion %d res->sr_slot %p\n" , + __func__, clp, clp->cl_session, clp->cl_minorversion, + res->sr_slot); + +if (clp->cl_minorversion ==0 || res->sr_slot) + goto out; +BUG_ON (clp->cl_minorversion !=1 ); + ret =nfs41_setup_sequence (clp->cl_session, args, res, + cache_reply, task); +if (ret) { +memset (res,0 ,sizeof (*res)); +if (ret != -EAGAIN ) { +/* terminate rpc task */ + task->tk_status = ret; + task->tk_action =NULL ; + } + } +out: +dprintk ("<-- %s status=%d\n" , __func__, ret); +return ret; +} + +struct nfs41_call_sync_data { +struct nfs_server *server; +struct rpc_message *msg; +struct nfs41_sequence_args *seq_args; +struct nfs41_sequence_res *seq_res; +int cache_reply; +}; + +static void nfs41_call_sync_prepare (struct rpc_task *task,void *calldata) +{ +struct nfs41_call_sync_data *data = calldata; + +dprintk ("--> %s data->server->session %p\n" , __func__, + data->server->nfs_client->cl_session); +if (nfs4_setup_sequence (data->server->nfs_client, data->seq_args, + data->seq_res, data->cache_reply, task)) +return ; +rpc_call_start (task); +} + +struct rpc_call_ops nfs41_call_sync_ops = { + .rpc_call_prepare = nfs41_call_sync_prepare, +}; +#endif /* CONFIG_NFS_V4_1 */ static int _nfs4_call_sync(struct nfs_server *server,@@ -355,6 +419,35 @@ static int _nfs4_call_sync(struct nfs_server *server, struct nfs41_sequence_res *res, int cache_reply) { +#ifdef CONFIG_NFS_V4_1 +if (server->nfs_client->cl_minorversion) { +int ret; +struct rpc_task *task; +struct nfs41_call_sync_data data = { + .server = server, + .msg = msg, + .seq_args = args, + .seq_res = res, + .cache_reply = cache_reply, + }; +struct rpc_task_setup task_setup = { + .rpc_client = server->client, + .rpc_message = msg, + .callback_ops = &nfs41_call_sync_ops, + .callback_data = &data + }; + + res->sr_slot =NULL ;
fs/nfs/nfs4proc.c static int _nfs4_call_sync(struct nfs_server *server, · line 450
Quoted 10 lines
fs/nfs/nfs4proc.c +10
-0+ task =rpc_run_task (&task_setup); +if (IS_ERR (task)) + ret =PTR_ERR (task); +else { + ret = task->tk_status; +rpc_put_task (task); + } + return ret; + } +#endif /* CONFIG_NFS_V4_1 */
review 11-14: move out into _nfs4_call_sync_seq
Quoted 16 lines
fs/nfs/nfs4proc.c +0
-0return rpc_call_sync (server->client, msg,0 ); }include/linux/nfs_xdr.h +1
-1@@ -134,7 +134,7 @@ struct nfs41_sequence_args {#define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100struct nfs41_sequence_res { -/* stub */ +struct nfs4_slot *sr_slot;/* slot used to send request */ };#if defined(CONFIG_NFS_V4_1 )
RFC 28/85 nfs41: setup_sequence method
In reply to Benny HalevyAllocate a slot in the session slot table and set the sequence op arguments.
Called at the rpc prepare stage.
--- fs/nfs/nfs4proc.c | 23 ++++++++++++++++++++++- include/linux/nfs_xdr.h | 5 ++++- 2 files changed, 26 insertions(+), 2 deletions(-)
fs/nfs/nfs4proc.c +22 -1
@@ -353,7 +353,28 @@ static int nfs41_setup_sequence(struct nfs4_session *session,int cache_reply, struct rpc_task *task) { -/* stub */ + struct nfs4_slot *slot; +struct nfs4_slot_table *tbl; + +dprintk ("--> %s\n" , __func__); + tbl = &session->fore_channel.slot_table; + slot =nfs4_find_slot (tbl, task); + +if (!slot) { +rpc_sleep_on (&tbl->slot_tbl_waitq, task,NULL ); +dprintk ("<-- %s: no free slots\n" , __func__); +return -EAGAIN ; + } + + args->sa_session = session; + args->sa_slot = slot; + args->sa_cache_this = cache_reply; + +dprintk ("<-- %s slot=%p slotid=%d seqid=%d\n" , __func__, + slot,slot_idx (tbl, slot), slot->seq_nr); + + res->sr_slot = slot; + res->sr_renewal_time = jiffies;return 0 ; }
include/linux/nfs_xdr.h +4 -1
@@ -120,7 +120,9 @@ struct sessionid4 { };struct nfs41_sequence_args { -/* stub */ +struct nfs4_session *sa_session; +struct nfs4_slot *sa_slot; +u32 sa_cache_this; };#define SEQ4_STATUS_CB_PATH_DOWN 0x00000001
@@ -135,6 +137,7 @@ struct nfs41_sequence_args {struct nfs41_sequence_res {struct nfs4_slot *sr_slot;/* slot used to send request */ +unsigned long sr_renewal_time; };#if defined(CONFIG_NFS_V4_1 )
Signature · 1 line
1.6.0.2
RFC 29/85 nfs41: nfs41_sequence_done
In reply to Benny HalevyHandle session level errors, update slot sequence id and sessions bookeeping, free slot.
--- fs/nfs/nfs4proc.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs_xdr.h | 3 ++ 2 files changed, 64 insertions(+), 0 deletions(-)
fs/nfs/nfs4proc.c +61 -0
@@ -296,6 +296,66 @@ nfs41_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)rpc_wake_up_next (&tbl->slot_tbl_waitq); } +/* For pNFS filelayout data servers: +* the nfs_client is NULL - to signal no lease update. +* session is the data server. +*/ +static void nfs41_sequence_done (struct nfs_client *clp, +struct nfs41_sequence_res *res, +int rpc_status) +{ +unsigned long timestamp; +struct nfs4_slot_table *tbl; +struct nfs4_slot *slot; +int status =NFS4_OK ; + +if (res->sr_flags &SEQ4_STATUS_USE_TK_STATUS ) + status = rpc_status; + + tbl = &res->sr_session->fore_channel.slot_table; + slot = res->sr_slot; + +switch (status) { +case NFS4_OK : +/* +* The sequence call was successful, +* Update the slot's sequence and client's lease renewal timers +*/ + ++slot->seq_nr; +if (!clp) +break ; + timestamp = res->sr_renewal_time; +spin_lock (&clp->cl_lock); +if (time_before (clp->cl_last_renewal, timestamp)) + clp->cl_last_renewal = timestamp; +spin_unlock (&clp->cl_lock); +break ; + +case -NFS4ERR_BADSESSION : +case -NFS4ERR_BADSLOT : +case -NFS4ERR_BADXDR : +case -NFS4ERR_BAD_HIGH_SLOT : +case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION : +case -NFS4ERR_DEADSESSION : +case -NFS4ERR_DELAY : +case -NFS4ERR_REP_TOO_BIG : +case -NFS4ERR_REP_TOO_BIG_TO_CACHE : +case -NFS4ERR_REQ_TOO_BIG : +case -NFS4ERR_RETRY_UNCACHED_REP : +case -NFS4ERR_SEQUENCE_POS : +case -NFS4ERR_SEQ_FALSE_RETRY : +case -NFS4ERR_SEQ_MISORDERED : +case -NFS4ERR_TOO_MANY_OPS : +dprintk ("%s: status %d\n" , __func__, status); +break ; + +default : +printk (KERN_WARNING "%s: Unexpected status %d\n" , __func__, + status); + } +nfs41_free_slot (tbl, slot); +} +/* * nfs4_find_slot - efficiently look for a free slot *
@@ -373,6 +433,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,dprintk ("<-- %s slot=%p slotid=%d seqid=%d\n" , __func__, slot,slot_idx (tbl, slot), slot->seq_nr); + res->sr_session = session; res->sr_slot = slot; res->sr_renewal_time = jiffies;return 0 ;
include/linux/nfs_xdr.h +3 -0
@@ -134,8 +134,11 @@ struct nfs41_sequence_args {#define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040#define SEQ4_STATUS_LEASE_MOVED 0x00000080#define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100 +#define SEQ4_STATUS_USE_TK_STATUS 0x10000000/* internal error */ struct nfs41_sequence_res { +struct nfs4_session *sr_session; +u32 sr_flags;struct nfs4_slot *sr_slot;/* slot used to send request */ unsigned long sr_renewal_time; };
Signature · 1 line
1.6.0.2
Re: [pnfs] [RFC 29/85] nfs41: nfs41_sequence_done
Quoted 15 lines · Benny Halevy
Handle session level errors, update slot sequence id and sessions bookeeping, free slot.
Signed-off-by Andy Adamson<[email protected]>Signed-off-by Benny Halevy <[email protected]>--- fs/nfs/nfs4proc.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs_xdr.h | 3 ++ 2 files changed, 64 insertions(+), 0 deletions(-)fs/nfs/nfs4proc.c +0
-0
fs/nfs/nfs4proc.c nfs41_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot) · line 305
Quoted 10 lines
fs/nfs/nfs4proc.c +7
-0@@ -296,6 +296,66 @@ nfs41_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)rpc_wake_up_next (&tbl->slot_tbl_waitq); } +/* For pNFS filelayout data servers: +* the nfs_client is NULL - to signal no lease update. +* session is the data server. +*/ +static void nfs41_sequence_done (struct nfs_client *clp, +struct nfs41_sequence_res *res, +int rpc_status)
review 11-14: cache the seq_status in struct nfs41_sequence_res. initialize to non zero so that we intercept rpc level failures in which we do not go through decode_sequence, which will be the only place where res->seq_status will be set to 0.
get rid of SEQ4_STATUS_USE_TK_STATUS.
no need to pass rpc_status either.
Quoted 80 lines
fs/nfs/nfs4proc.c +54
-0+{ +unsigned long timestamp; +struct nfs4_slot_table *tbl; +struct nfs4_slot *slot; +int status =NFS4_OK ; + +if (res->sr_flags &SEQ4_STATUS_USE_TK_STATUS ) + status = rpc_status; + + tbl = &res->sr_session->fore_channel.slot_table; + slot = res->sr_slot; + +switch (status) { +case NFS4_OK : +/* +* The sequence call was successful, +* Update the slot's sequence and client's lease renewal timers +*/ + ++slot->seq_nr; +if (!clp) +break ; + timestamp = res->sr_renewal_time; +spin_lock (&clp->cl_lock); +if (time_before (clp->cl_last_renewal, timestamp)) + clp->cl_last_renewal = timestamp; +spin_unlock (&clp->cl_lock); +break ; + +case -NFS4ERR_BADSESSION : +case -NFS4ERR_BADSLOT : +case -NFS4ERR_BADXDR : +case -NFS4ERR_BAD_HIGH_SLOT : +case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION : +case -NFS4ERR_DEADSESSION : +case -NFS4ERR_DELAY : +case -NFS4ERR_REP_TOO_BIG : +case -NFS4ERR_REP_TOO_BIG_TO_CACHE : +case -NFS4ERR_REQ_TOO_BIG : +case -NFS4ERR_RETRY_UNCACHED_REP : +case -NFS4ERR_SEQUENCE_POS : +case -NFS4ERR_SEQ_FALSE_RETRY : +case -NFS4ERR_SEQ_MISORDERED : +case -NFS4ERR_TOO_MANY_OPS : +dprintk ("%s: status %d\n" , __func__, status); +break ; + +default : +printk (KERN_WARNING "%s: Unexpected status %d\n" , __func__, + status); + } +nfs41_free_slot (tbl, slot); +} +/* * nfs4_find_slot - efficiently look for a free slot * @@ -373,6 +433,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,dprintk ("<-- %s slot=%p slotid=%d seqid=%d\n" , __func__, slot,slot_idx (tbl, slot), slot->seq_nr); + res->sr_session = session; res->sr_slot = slot; res->sr_renewal_time = jiffies;return 0 ;include/linux/nfs_xdr.h +3
-0@@ -134,8 +134,11 @@ struct nfs41_sequence_args {#define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040#define SEQ4_STATUS_LEASE_MOVED 0x00000080#define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100 +#define SEQ4_STATUS_USE_TK_STATUS 0x10000000/* internal error */ struct nfs41_sequence_res { +struct nfs4_session *sr_session; +u32 sr_flags;struct nfs4_slot *sr_slot;/* slot used to send request */ unsigned long sr_renewal_time; };
RFC 30/85 nfs41: nfs41_call_sync_done
In reply to Benny HalevyImplement nfs4.1 synchronous rpc_call_done method that essentially just calls nfs4_sequence_done, that turns around and calls nfs41_sequence_done for minorversion1 rpcs.
--- fs/nfs/nfs4proc.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-)
fs/nfs/nfs4proc.c +18 -0
@@ -489,8 +489,17 @@ static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata) rpc_call_start(task); } +static void nfs41_call_sync_done (struct rpc_task *task,void *calldata) +{ +struct nfs41_call_sync_data *data = calldata; +struct nfs_server *server = data->server; + +nfs41_sequence_done (server->nfs_client, data->seq_res, task->tk_status); +} +struct rpc_call_ops nfs41_call_sync_ops = { .rpc_call_prepare = nfs41_call_sync_prepare, + .rpc_call_done = nfs41_call_sync_done, };#endif /* CONFIG_NFS_V4_1 */
@@ -537,6 +546,15 @@ static int _nfs4_call_sync(struct nfs_server *server,_nfs4_call_sync ((server), (msg), &(args)->seq_args, \ &(res)->seq_res, (cache_reply)) +static void nfs4_sequence_done (const struct nfs_server *server, +struct nfs41_sequence_res *res,int rpc_status) +{ +#ifdef CONFIG_NFS_V4_1 +if (server->nfs_client->cl_minorversion) +nfs41_sequence_done (server->nfs_client, res, rpc_status); +#endif /* CONFIG_NFS_V4_1 */ +} +static void update_changeattr (struct inode *dir,struct nfs4_change_info *cinfo) {struct nfs_inode *nfsi =NFS_I (dir);
Signature · 1 line
1.6.0.2
RFC 31/85 nfs41: separate free slot from sequence done
In reply to Benny HalevyFrom: Andy Adamson <[email protected]>
Don't free the slot until after all rpc_restart_calls have completed. Session reset will require more work.
--- fs/nfs/internal.h | 14 ++++++++++++++ fs/nfs/nfs4proc.c | 36 +++++++++++++++++++++++++++++------- fs/nfs/read.c | 8 ++++++-- fs/nfs/write.c | 1 + 4 files changed, 50 insertions(+), 9 deletions(-)
fs/nfs/internal.h +14 -0
@@ -180,6 +180,20 @@ extern int nfs4_path_walk(struct nfs_server *server, const char *path);#endif +/* nfs4proc.c */ +#ifdef CONFIG_NFS_V4_1 +extern void nfs41_sequence_free_slot (struct nfs41_sequence_res *res); +#endif /* CONFIG_NFS_V4_1 */ + +static inline void nfs4_sequence_free_slot (const struct nfs_server *server, +struct nfs41_sequence_res *res) +{ +#ifdef CONFIG_NFS_V4_1 +if (server->nfs_client->cl_minorversion) +nfs41_sequence_free_slot (res); +#endif /* CONFIG_NFS_V4_1 */ +} +/* * Determine the device name as a string */
fs/nfs/nfs4proc.c +29 -7
@@ -258,7 +258,7 @@ static inline int bmp2idx(unsigned long *base, unsigned long *bmp,* word in the bitmap. * If none found, highest_used_slotid is set to -1. */ -static void +void nfs41_free_slot (struct nfs4_slot_table *tbl,struct nfs4_slot *slot) {int slotid =slot_idx (tbl, slot);
@@ -296,6 +296,17 @@ nfs41_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)rpc_wake_up_next (&tbl->slot_tbl_waitq); } +void nfs41_sequence_free_slot (struct nfs41_sequence_res *res) +{ +if (res->sr_session ==NULL || res->sr_slot ==NULL ) { +dprintk ("%s: %s\n" , __func__, + res->sr_session ==NULL ?"No session" :"No slot" ); +return ; + } +nfs41_free_slot (&res->sr_session->fore_channel.slot_table, + res->sr_slot); +} +/* For pNFS filelayout data servers: * the nfs_client is NULL - to signal no lease update. * session is the data server.
@@ -346,14 +357,18 @@ static void nfs41_sequence_done(struct nfs_client *clp,case -NFS4ERR_SEQ_FALSE_RETRY :case -NFS4ERR_SEQ_MISORDERED :case -NFS4ERR_TOO_MANY_OPS : -dprintk ("%s: status %d\n" , __func__, status); +dprintk ("%s: Free Slot: status %d\n" , __func__, status); +/* The session needs to be reset, so free the slot and set the +* sr_slot to NULL so that nfs4_setup_sequence calls +* nfs41_find_slot and kicks off session reset. */ +nfs41_sequence_free_slot (res); + res->sr_slot =NULL ;break ;default :printk (KERN_WARNING "%s: Unexpected status %d\n" , __func__, status); } -nfs41_free_slot (tbl, slot); }/*
@@ -495,6 +510,7 @@ static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)struct nfs_server *server = data->server;nfs41_sequence_done (server->nfs_client, data->seq_res, task->tk_status); +nfs41_sequence_free_slot (data->seq_res); }struct rpc_call_ops nfs41_call_sync_ops = {
@@ -1592,6 +1608,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)return ; } } +nfs4_sequence_free_slot (server, &calldata->res.seq_res);nfs_refresh_inode (calldata->inode, calldata->res.fattr); }
@@ -2352,6 +2369,7 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)if (nfs4_async_handle_error (task, res->server) == -EAGAIN )return 0 ; +nfs4_sequence_free_slot (res->server, &res->seq_res);update_changeattr (dir, &res->cinfo);nfs_post_op_update_inode (dir, &res->dir_attr);return 1 ;
@@ -2855,11 +2873,13 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messagstatic int nfs4_commit_done (struct rpc_task *task,struct nfs_write_data *data) {struct inode *inode = data->inode; - -if (nfs4_async_handle_error (task,NFS_SERVER (inode)) == -EAGAIN ) { +struct nfs_server *server =NFS_SERVER (inode); + +if (nfs4_async_handle_error (task, server) == -EAGAIN ) {rpc_restart_call (task);return -EAGAIN ; } +nfs4_sequence_free_slot (server, &data->res.seq_res);nfs_refresh_inode (inode, data->res.fattr);return 0 ; }
@@ -3585,6 +3605,7 @@ static void nfs4_locku_release_calldata(void *data)static void nfs4_locku_done (struct rpc_task *task,void *data) {struct nfs4_unlockdata *calldata = data; +const struct nfs_server *server = calldata->server;if (RPC_ASSASSINATED (task))return ;
@@ -3593,15 +3614,16 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)memcpy (calldata->lsp->ls_stateid.data, calldata->res.stateid.data,sizeof (calldata->lsp->ls_stateid.data)); -renew_lease (calldata->server, calldata->timestamp); +renew_lease (server, calldata->timestamp);break ;case -NFS4ERR_STALE_STATEID :case -NFS4ERR_EXPIRED :break ;default : -if (nfs4_async_handle_error (task, calldata->server) == -EAGAIN ) +if (nfs4_async_handle_error (task, server) == -EAGAIN )rpc_restart_call (task); } +nfs4_sequence_free_slot (server, &calldata->res.seq_res); }static void nfs4_locku_prepare (struct rpc_task *task,void *data)
fs/nfs/read.c +6 -2
@@ -351,19 +351,23 @@ static void nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *datastruct nfs_readres *resp = &data->res;if (resp->eof || resp->count == argp->count) -return ; + goto out;/* This is a short read! */ nfs_inc_stats (data->inode,NFSIOS_SHORTREAD );/* Has the server at least made some progress? */ if (resp->count ==0 ) -return ; + goto out;/* Yes, so retry the read at the end of the data */ argp->offset += resp->count; argp->pgbase += resp->count; argp->count -= resp->count;rpc_restart_call (task); +return ; +out: +nfs4_sequence_free_slot (NFS_SERVER (data->inode), &data->res.seq_res); +return ; }/*
fs/nfs/write.c +1 -0
@@ -1171,6 +1171,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)/* Can't do anything about it except throw an error. */ task->tk_status = -EIO ; } +nfs4_sequence_free_slot (NFS_SERVER (data->inode), &data->res.seq_res);return 0 ; }
Signature · 1 line
1.6.0.2
RFC 32/85 nfs41: sequence setup/done support
In reply to Benny HalevyImlpement the rpc_call_validate_args methods for asynchronuos nfs rpcs, call nfs41_setup_sequence from respective rpc_call_validate_args methods.
Call nfs4_sequence_done from respective rpc_call_done methods.
Note that we need to pass a pointer to the nfs_server in calls data for passing on to nfs4_sequence_done.
--- fs/nfs/direct.c | 1 + fs/nfs/nfs4_fs.h | 10 ++++++ fs/nfs/nfs4proc.c | 80 ++++++++++++++++++++++++++++++++++++++++++++--- fs/nfs/read.c | 23 +++++++++++++ fs/nfs/unlink.c | 16 +++++++++ fs/nfs/write.c | 23 +++++++++++++ include/linux/nfs_xdr.h | 7 ++-- 7 files changed, 152 insertions(+), 8 deletions(-)
fs/nfs/direct.c +1 -0
@@ -306,6 +306,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,if (unlikely (!data))break ; + data->args.server =NFS_SERVER (inode);down_read (¤t->mm->mmap_sem); result =get_user_pages (current, current->mm, user_addr, data->npages,1 ,0 , data->pagevec,NULL );
fs/nfs/nfs4_fs.h +10 -0
@@ -190,11 +190,21 @@ extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;#if defined(CONFIG_NFS_V4_1 ) +extern int nfs4_setup_sequence (struct nfs_client *clp, +struct nfs41_sequence_args *args,struct nfs41_sequence_res *res, +int cache_reply,struct rpc_task *task);extern void nfs4_put_session (struct nfs4_session **session);extern void nfs4_get_session (struct nfs_client *clp);extern struct nfs4_session *nfs4_alloc_session (void );extern int nfs4_proc_create_session (struct nfs4_session *);extern int nfs4_proc_destroy_session (struct nfs4_session *); +#else /* CONFIG_NFS_v4_1 */ +static inline int nfs4_setup_sequence (struct nfs_client *clp, +struct nfs41_sequence_args *args,struct nfs41_sequence_res *res, +int cache_reply,struct rpc_task *task) +{ +return 0 ; +}#endif /* CONFIG_NFS_V4_1 */ extern const u32 nfs4_fattr_bitmap[2 ];
fs/nfs/nfs4proc.c +75 -5
212 lines not on this page · raw message
fs/nfs/read.c +23 -0
@@ -22,6 +22,7 @@#include <asm/system.h> +#include "nfs4_fs.h" #include "internal.h" #include "iostat.h"
@@ -175,6 +176,7 @@ static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, .flags = RPC_TASK_ASYNC | swap_flags, }; +BUG_ON (data->args.server ==NULL ); data->req = req; data->inode = inode; data->cred = msg.rpc_cred;
@@ -254,6 +256,7 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne data =nfs_readdata_alloc (1 );if (!data) goto out_bad; + data->args.server =NFS_SERVER (inode);list_add (&data->pages, &list); requests++; nbytes -= len;
@@ -305,6 +308,7 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsignedif (!data) goto out_bad; + data->args.server =NFS_SERVER (inode); pages = data->pagevec;while (!list_empty (head)) { req =nfs_list_entry (head->next);
@@ -404,7 +408,23 @@ static void nfs_readpage_release_partial(void *calldata)nfs_readdata_release (calldata); } +#if defined(CONFIG_NFS_V4_1 ) +void nfs_read_prepare (struct rpc_task *task,void *calldata) +{ +struct nfs_read_data *data = calldata; +struct nfs_server *server = data->args.server; + +if (nfs4_setup_sequence (server->nfs_client, &data->args.seq_args, + &data->res.seq_res,0 , task)) +return ; +rpc_call_start (task); +} +#endif /* CONFIG_NFS_V4_1 */ +static const struct rpc_call_ops nfs_read_partial_ops = { +#if defined(CONFIG_NFS_V4_1) + .rpc_call_prepare = nfs_read_prepare, +#endif .rpc_call_done = nfs_readpage_result_partial, .rpc_release = nfs_readpage_release_partial, };
@@ -468,6 +488,9 @@ static void nfs_readpage_release_full(void *calldata) }static const struct rpc_call_ops nfs_read_full_ops = { +#if defined(CONFIG_NFS_V4_1) + .rpc_call_prepare = nfs_read_prepare, +#endif .rpc_call_done = nfs_readpage_result_full, .rpc_release = nfs_readpage_release_full, };
fs/nfs/unlink.c +16 -0
@@ -15,6 +15,7 @@#include <linux/wait.h> #include "internal.h" +#include "nfs4_fs.h" struct nfs_unlinkdata {struct hlist_node list;
@@ -102,9 +103,24 @@ static void nfs_async_unlink_release(void *calldata)nfs_sb_deactive (sb); } +#if defined(CONFIG_NFS_V4_1 ) +void nfs_unlink_prepare (struct rpc_task *task,void *calldata) +{ +struct nfs_unlinkdata *data = calldata; +struct nfs_server *server =NFS_SERVER (data->dir); + +if (nfs4_setup_sequence (server->nfs_client, &data->args.seq_args, + &data->res.seq_res,1 , task)) +return ; +rpc_call_start (task); +} +#endif /* CONFIG_NFS_V4_1 */ static const struct rpc_call_ops nfs_unlink_ops = { .rpc_call_done = nfs_async_unlink_done, .rpc_release = nfs_async_unlink_release, +#if defined(CONFIG_NFS_V4_1) + .rpc_call_prepare = nfs_unlink_prepare, +#endif };static int nfs_do_call_unlink (struct dentry *parent,struct inode *dir,struct nfs_unlinkdata *data)
fs/nfs/write.c +23 -0
@@ -25,6 +25,7 @@#include "delegation.h" #include "internal.h" #include "iostat.h" +#include "nfs4_fs.h" #define NFSDBG_FACILITY NFSDBG_PAGECACHE
@@ -1026,7 +1027,23 @@ out:nfs_writedata_release (calldata); } +#if defined(CONFIG_NFS_V4_1 ) +void nfs_write_prepare (struct rpc_task *task,void *calldata) +{ +struct nfs_write_data *data = calldata; +struct nfs_server *server =NFS_SERVER (data->inode); + +if (nfs4_setup_sequence (server->nfs_client, &data->args.seq_args, + &data->res.seq_res,1 , task)) +return ; +rpc_call_start (task); +} +#endif /* CONFIG_NFS_V4_1 */ +static const struct rpc_call_ops nfs_write_partial_ops = { +#if defined(CONFIG_NFS_V4_1) + .rpc_call_prepare = nfs_write_prepare, +#endif .rpc_call_done = nfs_writeback_done_partial, .rpc_release = nfs_writeback_release_partial, };
@@ -1089,6 +1106,9 @@ remove_request: }static const struct rpc_call_ops nfs_write_full_ops = { +#if defined(CONFIG_NFS_V4_1) + .rpc_call_prepare = nfs_write_prepare, +#endif .rpc_call_done = nfs_writeback_done_full, .rpc_release = nfs_writeback_release_full, };
@@ -1328,6 +1348,9 @@ static void nfs_commit_release(void *calldata) }static const struct rpc_call_ops nfs_commit_ops = { +#if defined(CONFIG_NFS_V4_1) + .rpc_call_prepare = nfs_write_prepare, +#endif .rpc_call_done = nfs_commit_done, .rpc_release = nfs_commit_release, };
include/linux/nfs_xdr.h +4 -3
@@ -172,7 +172,7 @@ struct nfs_openargs {int delegation_type;/* CLAIM_PREVIOUS */ } u;const struct qstr * name; -const struct nfs_server *server;/* Needed for ID mapping */ +struct nfs_server * server;/* Needed for ID mapping */ const u32 * bitmask;__u32 claim;struct nfs41_sequence_args seq_args;
@@ -292,7 +292,7 @@ struct nfs4_delegreturnargs {struct nfs4_delegreturnres {struct nfs_fattr * fattr; -const struct nfs_server *server; +struct nfs_server *server;struct nfs41_sequence_res seq_res; };
@@ -306,6 +306,7 @@ struct nfs_readargs {__u32 count;unsigned int pgbase;struct page ** pages; +struct nfs_server *server;struct nfs41_sequence_args seq_args; };
@@ -355,7 +356,7 @@ struct nfs_removeargs { };struct nfs_removeres { -const struct nfs_server *server; +struct nfs_server *server;struct nfs4_change_info cinfo;struct nfs_fattr dir_attr;struct nfs41_sequence_res seq_res;
Signature · 1 line
1.6.0.2
RFC 33/85 nfs41: Support sessions with O_DIRECT.
In reply to Benny HalevyFrom: Dean Hildebrand <[email protected]>
--- fs/nfs/direct.c | 9 +++++++++ fs/nfs/internal.h | 6 ++++++ 2 files changed, 15 insertions(+), 0 deletions(-)
fs/nfs/direct.c +9 -0
@@ -259,6 +259,9 @@ static void nfs_direct_read_release(void *calldata) }static const struct rpc_call_ops nfs_read_direct_ops = { +#if defined(CONFIG_NFS_V4_1) + .rpc_call_prepare = nfs_read_prepare, +#endif /* CONFIG_NFS_V4_1 */ .rpc_call_done = nfs_direct_read_result, .rpc_release = nfs_direct_read_release, };
@@ -536,6 +539,9 @@ static void nfs_direct_commit_release(void *calldata) }static const struct rpc_call_ops nfs_commit_direct_ops = { +#if defined(CONFIG_NFS_V4_1) + .rpc_call_prepare = nfs_write_prepare, +#endif /* CONFIG_NFS_V4_1 */ .rpc_call_done = nfs_direct_commit_result, .rpc_release = nfs_direct_commit_release, };
@@ -674,6 +680,9 @@ out_unlock: }static const struct rpc_call_ops nfs_write_direct_ops = { +#if defined(CONFIG_NFS_V4_1) + .rpc_call_prepare = nfs_write_prepare, +#endif /* CONFIG_NFS_V4_1 */ .rpc_call_done = nfs_direct_write_result, .rpc_release = nfs_direct_write_release, };
fs/nfs/internal.h +6 -0
@@ -180,6 +180,12 @@ extern int nfs4_path_walk(struct nfs_server *server, const char *path);#endif +/* read.c */ +extern void nfs_read_prepare (struct rpc_task *task,void *calldata); + +/* write.c */ +extern void nfs_write_prepare (struct rpc_task *task,void *calldata); +/* nfs4proc.c */ #ifdef CONFIG_NFS_V4_1 extern void nfs41_sequence_free_slot (struct nfs41_sequence_res *res);
Signature · 1 line
1.6.0.2
RFC 34/85 nfs41: exchange_id operation
In reply to Benny HalevyImplement the exchange_id operation conforming to
http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-26
Unlike NFSv4.0, NFSv4.1 requires machine credentials. RPC_AUTH_GSS machine credentials will be passed into the kernel at mount time to be available for the exchange_id operation.
RPC_AUTH_UNIX root mounts can use the UNIX root credential. Store the root credential in the nfs_client struct.
Without a credential, NFSv4.1 state renewal fails.
nfs41: establish clientid via exchange id only if cred != NULL
Quoted 1 line
From 2.6.26
reclaimer()uses machine cred for setting up the client id
therefore it is never expected to be NULL.
Note: NFS4_OPAQUE_LIMIT moved from include/linux/nfsd/state.h to include/linux/nfs4.h since it's now used also for client side exchange_id xdr data type.
--- fs/nfs/nfs4proc.c | 63 +++++++++++++++++++- fs/nfs/nfs4xdr.c | 143 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs4.h | 1 + include/linux/nfs_fs_sb.h | 6 ++ include/linux/nfs_xdr.h | 42 +++++++++++++ include/linux/nfsd/state.h | 1 - 6 files changed, 254 insertions(+), 2 deletions(-)
fs/nfs/nfs4proc.c +62 -1
@@ -48,6 +48,7 @@#include <linux/smp_lock.h> #include <linux/namei.h> #include <linux/mount.h> +#include <linux/module.h> #include "nfs4_fs.h" #include "delegation.h"
@@ -4175,9 +4176,69 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, }#ifdef CONFIG_NFS_V4_1 +/* +* nfs4_proc_exchange_id() +* +* Since the clientid has expired, all compounds using sessions +* associated with the stale clientid will be returning +* NFS4ERR_BADSESSION in the sequence operation, and will therefore +* be in some phase of session reset. +*/ static int nfs4_proc_exchange_id (struct nfs_client *clp,struct rpc_cred *cred) { -return -1 ;/* stub */ +nfs4_verifier verifier; +struct nfs41_exchange_id_args args = { + .flags = clp->cl_exchange_flags, + }; +struct nfs41_exchange_id_res res = { + .client = clp, + }; +int status; +int loop =0 ; +struct rpc_message msg = { + .rpc_proc =nfs4_proc (clp,NFSPROC4_CLNT_EXCHANGE_ID ), + .rpc_argp = &args, + .rpc_resp = &res, + .rpc_cred = cred, + }; +__be32 *p; + +dprintk ("--> %s\n" , __func__); +BUG_ON (clp ==NULL ); + p = (u32 *)verifier.data; + *p++ =htonl ((u32 )clp->cl_boot_time.tv_sec); + *p =htonl ((u32 )clp->cl_boot_time.tv_nsec); + args.verifier = &verifier; + +while (1 ) { + args.id_len =scnprintf (args.id,sizeof (args.id), +"%s/%s %u" , + clp->cl_ipaddr, +rpc_peeraddr2str (clp->cl_rpcclient, +RPC_DISPLAY_ADDR ), + clp->cl_id_uniquifier); + + status =rpc_call_sync (clp->cl_rpcclient, &msg,0 ); + +if (status !=NFS4ERR_CLID_INUSE ) +break ; + +if (signalled ()) +break ; + +/* Andy Adamson <andros at netapp.com>: Waiting a lease period +* allows the server to throw away a clientid previously +* established by this client. Of course, it doesn't help when +* the conflicting clientid was established by another client. +*/ +if (loop++ &1 ) +ssleep (clp->cl_lease_time +1 ); +else if (++clp->cl_id_uniquifier ==0 ) +break ; + } + +dprintk ("<-- %s status= %d\n" , __func__, status); +return status; }/*
fs/nfs/nfs4xdr.c +143 -0
185 lines not on this page · raw message
include/linux/nfs4.h +1 -0
@@ -21,6 +21,7 @@#define NFS4_FHSIZE 128#define NFS4_MAXPATHLEN PATH_MAX#define NFS4_MAXNAMLEN NAME_MAX +#define NFS4_OPAQUE_LIMIT 1024#define NFS4_MAX_SESSIONID_LEN 16#define NFS4_ACCESS_READ 0x0001
include/linux/nfs_fs_sb.h +6 -0
@@ -75,6 +75,12 @@ struct nfs_client {#endif /* CONFIG_NFS_V4 */ #ifdef CONFIG_NFS_V4_1 +/* clientid returned from EXCHANGE_ID, used by session operations */ +u64 cl_ex_clid; +/* The sequence id to use for the next CREATE_SESSION */ +u32 cl_seqid; +/* The flags used for obtaining the clientid during EXCHANGE_ID */ +u32 cl_exchange_flags;struct nfs4_session *cl_session;/* sharred session */ #endif /* CONFIG_NFS_V4_1 */ };
include/linux/nfs_xdr.h +42 -0
48 lines not on this page · raw message
include/linux/nfsd/state.h +0 -1
@@ -41,7 +41,6 @@#include <linux/kref.h> #include <linux/sunrpc/clnt.h> -#define NFS4_OPAQUE_LIMIT 1024 typedef struct { u32 cl_boot; u32 cl_id;
Signature · 1 line
1.6.0.2
RFC 35/85 nfs41: get_lease_time
In reply to Benny Halevyget_lease_time uses the FSINFO rpc operation to
get the lease time attribute.
--- fs/nfs/nfs4proc.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nfs/nfs4xdr.c | 56 +++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 0 deletions(-)
fs/nfs/nfs4proc.c +84 -0
@@ -4241,6 +4241,90 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)return status; } +struct nfs4_get_lease_time_data { +struct nfs4_get_lease_time_args *args; +struct nfs4_get_lease_time_res *res; +struct nfs_client *clp; +struct nfs4_session *session; +}; + +static void nfs4_get_lease_time_prepare (struct rpc_task *task, +void *calldata) +{ +int ret; +struct nfs4_get_lease_time_data *data = + (struct nfs4_get_lease_time_data *)calldata; + +dprintk ("--> %s\n" , __func__); +/* just setup sequence, do not trigger session recovery +since we're invoked within one */ + ret =nfs41_setup_sequence (data->session, + &data->args->la_seq_args, + &data->res->lr_seq_res,0 , task); + +BUG_ON (ret == -EAGAIN ); +rpc_call_start (task); +dprintk ("<-- %s\n" , __func__); +} + +static void nfs4_get_lease_time_done (struct rpc_task *task, +void *calldata) +{ +struct nfs4_get_lease_time_data *data = + (struct nfs4_get_lease_time_data *)calldata; + +dprintk ("--> %s\n" , __func__); +nfs41_sequence_done (data->clp, &data->res->lr_seq_res, task->tk_status); +nfs41_sequence_free_slot (&data->res->lr_seq_res); +dprintk ("<-- %s\n" , __func__); +} + +struct rpc_call_ops nfs4_get_lease_time_ops = { + .rpc_call_prepare = nfs4_get_lease_time_prepare, + .rpc_call_done = nfs4_get_lease_time_done, +}; + +int nfs4_proc_get_lease_time (struct nfs_client *clp, +struct nfs4_session *session,struct nfs_fsinfo *fsinfo) +{ +struct rpc_task *task; +struct nfs4_get_lease_time_args args; +struct nfs4_get_lease_time_res res = { + .lr_fsinfo = fsinfo, + }; +struct nfs4_get_lease_time_data data = { + .args = &args, + .res = &res, + .clp = clp, + .session = session, + }; +struct rpc_message msg = { + .rpc_proc =nfs4_proc (clp,NFSPROC4_CLNT_GET_LEASE_TIME ), + .rpc_argp = &args, + .rpc_resp = &res, + }; +struct rpc_task_setup task_setup = { + .rpc_client = session->clnt, + .rpc_message = &msg, + .callback_ops = &nfs4_get_lease_time_ops, + .callback_data = &data + }; +int status; + +dprintk ("--> %s\n" , __func__); + task =rpc_run_task (&task_setup); + +if (IS_ERR (task)) + status =PTR_ERR (task); +else { + status = task->tk_status; +rpc_put_task (task); + } +dprintk ("<-- %s return %d\n" , __func__, status); + +return status; +} +/* * Initialize slot table *
fs/nfs/nfs4xdr.c +56 -0
80 lines not on this page · raw message
Signature · 1 line
1.6.0.2
RFC 36/85 nfs41: create_session operation
In reply to Benny HalevyFrom: Andy Adamson <[email protected]>
Implement the create_session operation conforming to
http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-26
--- fs/nfs/nfs4proc.c | 141 ++++++++++++++++++++++++++++++++++- fs/nfs/nfs4xdr.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/nfs_xdr.h | 17 ++++ 3 files changed, 350 insertions(+), 1 deletions(-)
fs/nfs/nfs4proc.c +140 -1
@@ -55,6 +55,7 @@#include "internal.h" #include "iostat.h" #if defined(CONFIG_NFS_V4_1 ) +#include "callback.h" #include <linux/nfs4_session.h> #endif /* CONFIG_NFS_V4_1 */
@@ -4448,9 +4449,147 @@ void nfs4_get_session(struct nfs_client *clp)atomic_inc (&clp->cl_session->ref_count); } +/* Initialize the values to be used by the client in CREATE_SESSION */ +static void nfs4_init_channel_attrs (struct nfs_client *clp, +struct nfs4_channel_attrs *fc_attrs, +struct nfs4_channel_attrs *bc_attrs) +{ +/* XXX: We need to have good values here... 32K is a wild guess */ + fc_attrs->headerpadsz = bc_attrs->headerpadsz =0 ; + fc_attrs->max_rqst_sz = bc_attrs->max_rqst_sz =NFS_MAX_FILE_IO_SIZE ; + fc_attrs->max_resp_sz = bc_attrs->max_resp_sz =NFS_MAX_FILE_IO_SIZE ; + fc_attrs->max_resp_sz_cached = bc_attrs->max_resp_sz_cached = +NFS_MAX_FILE_IO_SIZE ; + fc_attrs->max_ops = bc_attrs->max_ops =0xFFFFFFFF ; + fc_attrs->max_reqs = bc_attrs->max_reqs = + clp->cl_rpcclient->cl_xprt->max_reqs; + fc_attrs->rdma_attrs = bc_attrs->rdma_attrs =0 ; +} + +/* Check the values returned by the server for CREATE_SESSION. Since we made +* our needs known, if the server gives us more than we need, we don't bother +* with it. +*/ +static void nfs4_adjust_channel_attrs (struct nfs4_channel_attrs *req_attrs, +struct nfs4_channel_attrs *resp_attrs) +{ +dprintk ("%s: before adjusting: max_rqst_sz=%u max_resp_sz=%u " +"max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n" , + __func__, + resp_attrs->max_rqst_sz, resp_attrs->max_resp_sz, + resp_attrs->max_resp_sz_cached, resp_attrs->max_ops, + resp_attrs->max_reqs); + +if (req_attrs->max_rqst_sz < resp_attrs->max_rqst_sz) + resp_attrs->max_rqst_sz = req_attrs->max_rqst_sz; + +if (req_attrs->max_resp_sz < resp_attrs->max_resp_sz) + resp_attrs->max_resp_sz = req_attrs->max_resp_sz; + +if (req_attrs->max_resp_sz_cached < resp_attrs->max_resp_sz) + resp_attrs->max_resp_sz = req_attrs->max_resp_sz_cached; + +if (req_attrs->max_ops < resp_attrs->max_ops) + resp_attrs->max_ops = req_attrs->max_ops; + +if (req_attrs->max_reqs < resp_attrs->max_reqs) + resp_attrs->max_reqs = req_attrs->max_reqs; + +dprintk ("%s: after adjusting: max_rqst_sz=%u max_resp_sz=%u " +"max_resp_sz_cached=%u max_ops=%u max_reqs=%u\n" , + __func__, + resp_attrs->max_rqst_sz, resp_attrs->max_resp_sz, + resp_attrs->max_resp_sz_cached, resp_attrs->max_ops, + resp_attrs->max_reqs); + +/* We ignore the rdma channel attributes */ +} + +static int _nfs4_proc_create_session (struct nfs4_session *session) +{ +struct nfs_client *clp = session->clp; +struct nfs41_create_session_args args = { + .client = clp, + .session = session, + .cb_program =NFS4_CALLBACK , + }; + +struct nfs41_create_session_res res = { + .client = clp, + .session = session, + }; + +struct rpc_message msg = { + .rpc_proc =nfs4_proc (clp,NFSPROC4_CLNT_CREATE_SESSION ), + .rpc_argp = &args, + .rpc_resp = &res, + }; +int status; + +nfs4_init_channel_attrs (clp, &args.fc_attrs, &args.bc_attrs); + args.flags = (SESSION4_PERSIST ); + + status =rpc_call_sync (session->clnt, &msg,0 ); + +/* Set the negotiated values in the session's channel_attrs struct */ + +if (!status) { +nfs4_adjust_channel_attrs (&args.fc_attrs, + &session->fore_channel.chan_attrs); +nfs4_adjust_channel_attrs (&args.bc_attrs, + &session->back_channel.chan_attrs); +/* Increment the clientid slot sequence id */ + clp->cl_seqid++; + } + +return status; +} + +/* +* Issues a CREATE_SESSION operation to the server. +* It is the responsibility of the caller to verify the session is +* expired before calling this routine. +*/ int nfs4_proc_create_session (struct nfs4_session *session) { -return -1 ;/* stub */ +int status; +u32 *ptr; +struct nfs_fsinfo fsinfo; +struct nfs_client *clp = session->clp; + +dprintk ("--> %s clp=%p session=%p\n" , __func__, clp, session); + + status =_nfs4_proc_create_session (session); +if (status) + goto out; + + session->clnt = clp->cl_rpcclient; + +/* Init the fore channel */ + status =nfs4_init_slot_table (&session->fore_channel); +dprintk ("fore channel initialization returned %d\n" , status); +if (status) + goto out; + +dprintk ("%s client>seqid %d\n" , __func__, clp->cl_seqid); + ptr = (int *)session->sess_id; +dprintk ("sessionid is: %u:%u:%u:%u\n" , ptr[0 ], ptr[1 ], ptr[2 ], ptr[3 ]); + +/* Get the lease time */ + status =nfs4_proc_get_lease_time (clp, session, &fsinfo); +if (status ==0 ) { +/* Update lease time and schedule renewal */ +spin_lock (&clp->cl_lock); + clp->cl_lease_time = fsinfo.lease_time *HZ ; + clp->cl_last_renewal = jiffies; +clear_bit (NFS4CLNT_LEASE_EXPIRED , &clp->cl_state); +spin_unlock (&clp->cl_lock); + +nfs4_schedule_state_renewal (clp); + } +out: +dprintk ("<-- %s\n" , __func__); +return status; }int nfs4_proc_destroy_session (struct nfs4_session *session)
fs/nfs/nfs4xdr.c +193 -0
241 lines not on this page · raw message
include/linux/nfs_xdr.h +17 -0
@@ -2,6 +2,9 @@#define _LINUX_NFS_XDR_H#include <linux/nfsacl.h> +#ifdef CONFIG_NFS_V4_1 +#include <linux/nfs4_session.h> +#endif /* * To change the maximum rsize and wsize supported by the NFS client, adjust
@@ -899,6 +902,20 @@ struct nfs41_exchange_id_res {struct server_scope server_scope; struct nfs_impl_id4 impl_id; }; + +struct nfs41_create_session_args { +struct nfs_client *client; +struct nfs4_session *session; +uint32_t flags; +uint32_t cb_program; +struct nfs4_channel_attrs fc_attrs;/* Fore Channel */ +struct nfs4_channel_attrs bc_attrs;/* Back Channel */ +}; + +struct nfs41_create_session_res { +struct nfs_client *client; +struct nfs4_session *session; +};#endif /* CONFIG_NFS_V4_1 */ struct nfs_page ;
Signature · 1 line
1.6.0.2
RFC 37/85 nfs41: destroy_session operation
In reply to Benny HalevyImplement the destroy_session operation conforming to
http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-26
--- fs/nfs/nfs4proc.c | 23 ++++++++++++++++++- fs/nfs/nfs4xdr.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nfs/super.c | 2 + 3 files changed, 86 insertions(+), 1 deletions(-)
fs/nfs/nfs4proc.c +22 -1
@@ -4592,9 +4592,30 @@ out:return status; } +/* +* Issue the over-the-wire RPC DESTROY_SESSION. +* The caller must serialize access to this routine. +*/ int nfs4_proc_destroy_session (struct nfs4_session *session) { -return -1 ;/* stub */ +int status =0 ; +struct rpc_message msg; + +dprintk ("--> nfs4_proc_destroy_session\n" ); + + msg.rpc_proc =nfs4_proc (session->clp,NFSPROC4_CLNT_DESTROY_SESSION ); + msg.rpc_argp = session; + msg.rpc_resp =NULL ; + msg.rpc_cred =NULL ; + status =rpc_call_sync (session->clnt, &msg,0 ); + +if (status) +printk (KERN_WARNING +"Got error %d from the server on DESTROY_SESSION. " +"Session has been destroyed regardless...\n" , status); + +dprintk ("<-- nfs4_proc_destroy_session\n" ); +return status; }static int nfs4_proc_sequence (struct nfs_client *clp,struct rpc_cred *cred)
fs/nfs/nfs4xdr.c +62 -0
104 lines not on this page · raw message
fs/nfs/super.c +2 -0
@@ -2431,11 +2431,13 @@ static void nfs4_kill_super(struct super_block *sb) {struct nfs_server *server =NFS_SB (sb); +dprintk ("--> %s\n" , __func__);nfs_return_all_delegations (sb);kill_anon_super (sb);nfs4_renewd_prepare_shutdown (server);nfs_free_server (server); +dprintk ("<-- %s\n" , __func__); }/*
Signature · 1 line
1.6.0.2
RFC 38/85 nfs41: sequence operation
In reply to Benny HalevyImplement the sequence operation conforming to
http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-26
Check returned sessionid, slotid and slot sequenceid in decode_sequence.
Pass the sequence operation status to nfs41_sequence_done in order to determine when to increment the slot sequence ID.
Free slot is separated from sequence done.
--- fs/nfs/nfs4proc.c | 92 +++++++++++++++++++++++++++++++++++++++++- fs/nfs/nfs4xdr.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 201 insertions(+), 6 deletions(-)
fs/nfs/nfs4proc.c +90 -2
@@ -4620,13 +4620,101 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)static int nfs4_proc_sequence (struct nfs_client *clp,struct rpc_cred *cred) { -return -1 ;/* stub */ +struct nfs41_sequence_args args; +struct nfs41_sequence_res res; +struct nfs_server *server; + +struct rpc_message msg = { + .rpc_proc =nfs4_proc (clp,NFSPROC4_CLNT_SEQUENCE ), + .rpc_argp = &args, + .rpc_resp = &res, + .rpc_cred = cred, + }; +int status; + +/* +* We need to renew the lease on the server. For this, we use any +* session we have on the server to send the SEQUENCE op +*/ +BUG_ON (list_empty (&clp->cl_superblocks)); + + server = list_entry(clp->cl_superblocks.next, struct nfs_server, + client_link); + + args.sa_cache_this =0 ; + + status =_nfs4_call_sync (server, &msg, &args, &res,0 ); +return status; +} + +void nfs41_sequence_call_done (struct rpc_task *task,void *data) +{ +struct nfs_server *server = (struct nfs_server *)data; + +nfs4_sequence_done (server, task->tk_msg.rpc_resp, task->tk_status); +nfs4_sequence_free_slot (server, task->tk_msg.rpc_resp); +dprintk ("%s rpc_cred %p\n" , __func__, task->tk_msg.rpc_cred); + +put_rpccred (task->tk_msg.rpc_cred); +kfree (task->tk_msg.rpc_argp); +kfree (task->tk_msg.rpc_resp); + +dprintk ("<-- %s\n" , __func__); +} + +static void nfs41_sequence_prepare (struct rpc_task *task,void *data) +{ +struct nfs_server *server; +struct nfs41_sequence_args *args; +struct nfs41_sequence_res *res; + + server = (struct nfs_server *)data; + args = task->tk_msg.rpc_argp; + res = task->tk_msg.rpc_resp; + +if (nfs4_setup_sequence (server->nfs_client, args, res,0 , task)) +return ; +rpc_call_start (task); } +static const struct rpc_call_ops nfs41_sequence_ops = { + .rpc_call_done = nfs41_sequence_call_done, + .rpc_call_prepare = nfs41_sequence_prepare, +}; +static int nfs41_proc_async_sequence (struct nfs_client *clp,struct rpc_cred *cred) { -return -1 ;/* stub */ +struct nfs41_sequence_args *args; +struct nfs41_sequence_res *res; +struct nfs_server *server; +struct rpc_message msg = { + .rpc_proc =nfs4_proc (clp,NFSPROC4_CLNT_SEQUENCE ), + .rpc_cred = cred, + }; + + args =kzalloc (sizeof (*args),GFP_KERNEL ); +if (!args) +return -ENOMEM ; + res =kzalloc (sizeof (*res),GFP_KERNEL ); +if (!res) { +kfree (args); +return -ENOMEM ; + } + msg.rpc_argp = args; + msg.rpc_resp = res; + +/* +* We need to renew the lease on the server. For this, we use any +* session we have on the server to send the SEQUENCE op +*/ +BUG_ON (list_empty (&clp->cl_superblocks)); + + server = list_entry(clp->cl_superblocks.next, struct nfs_server, + client_link); + +return rpc_call_async (server->client, &msg,RPC_TASK_SOFT , + &nfs41_sequence_ops, (void *)server); }#endif /* CONFIG_NFS_V4_1 */
fs/nfs/nfs4xdr.c +111 -4
165 lines not on this page · raw message
Signature · 1 line
1.6.0.2
RFC 39/85 nfs41: session recovery infrastructure
In reply to Benny HalevyFrom: Andy Adamson <[email protected]>
FIXME: review comment message.
NFSv4.1 session recovery.
Sessions are created in the "alloc" state and session recovery is used to initiate session creation as well.
nfs41: Correctly use new session in exception handling
We will need to handle several layers of session recovery depending on the error. As a last resort, we will need to use the big hammer; destroy an existing session and create a new one.
The current code creates a new session without destroying the old one. Destroy the existing session and initialize a new session before calling nfs41_recover_session_sync.
nfs41: correctly expire and validate session
Do not expire session in session_reclaimer error case where the session could be ok (create session succeeded) but nfs4_proc_get_lease_time failed. Leave the session expiration (as well as new session initialization) to callers.
The session is valid as soon as the create session rpc completes successfully, and is not dependant upon a successful nfs4_proc_get_lease_time rpc. Move session validation from nfs4_proc_create_session to the success case of _nfs4_proc_create_session.
nfs41: add nfs_client pointer to struct nfs4_session
The session is always associated with a struct nfs_client that holds the exchange_id results. Add an nfs_client struct backpointer to the session and refactor the session recovery routines to only require a struct nfs4_sessions parameter.
--- fs/nfs/Makefile | 1 + fs/nfs/client.c | 2 +- fs/nfs/nfs41_session_recovery.c | 186 ++++++++++++++++++++++++++++++++ fs/nfs/nfs4proc.c | 17 +++- include/linux/nfs41_session_recovery.h | 40 +++++++ 5 files changed, 242 insertions(+), 4 deletions(-) create mode 100644 fs/nfs/nfs41_session_recovery.c create mode 100644 include/linux/nfs41_session_recovery.h
fs/nfs/Makefile +1 -0
@@ -14,4 +14,5 @@ nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \ delegation.o idmap.o \ callback.o callback_xdr.o callback_proc.o \ nfs4namespace.o +nfs-$(CONFIG_NFS_V4_1) += nfs41_session_recovery.o nfs-$(CONFIG_SYSCTL) += sysctl.o
fs/nfs/client.c +1 -1
@@ -38,7 +38,7 @@#include <net/ipv6.h> #include <linux/nfs_xdr.h> #if defined(CONFIG_NFS_V4_1 ) -#include <linux/nfs4_session.h> +#include <linux/nfs41_session_recovery.h> #endif /* CONFIG_NFS_V4_1 */ #include <asm/system.h>
fs/nfs/nfs41_session_recovery.c new file +186 -0
186 lines not on this page · raw message
fs/nfs/nfs4proc.c +14 -3
@@ -56,7 +56,7 @@#include "iostat.h" #if defined(CONFIG_NFS_V4_1 )#include "callback.h" -#include <linux/nfs4_session.h> +#include <linux/nfs41_session_recovery.h> #endif /* CONFIG_NFS_V4_1 */ #define NFSDBG_FACILITY NFSDBG_PROC
@@ -68,7 +68,7 @@ struct nfs4_opendata;static int _nfs4_proc_open (struct nfs4_opendata *data);static int nfs4_do_fsinfo (struct nfs_server *,struct nfs_fh *,struct nfs_fsinfo *);static int nfs4_async_handle_error (struct rpc_task *,const struct nfs_server *); -static int nfs4_handle_exception (const struct nfs_server *server,int errorcode,struct nfs4_exception *exception); +static int nfs4_handle_exception (struct nfs_server *server,int errorcode,struct nfs4_exception *exception);static int nfs4_wait_clnt_recover (struct rpc_clnt *clnt,struct nfs_client *clp);static int _nfs4_proc_lookup (struct inode *dir,const struct qstr *name,struct nfs_fh *fhandle,struct nfs_fattr *fattr);static int _nfs4_proc_getattr (struct nfs_server *server,struct nfs_fh *fhandle,struct nfs_fattr *fattr);
@@ -3280,7 +3280,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)/* This is the error handling routine for processes that are allowed * to sleep. */ -static int nfs4_handle_exception (const struct nfs_server *server,int errorcode,struct nfs4_exception *exception) +static int nfs4_handle_exception (struct nfs_server *server,int errorcode,struct nfs4_exception *exception) {struct nfs_client *clp = server->nfs_client;int ret = errorcode;
@@ -4420,6 +4420,8 @@ struct nfs4_session *nfs4_alloc_session(void)if (!session)return NULL ; +nfs41_set_session_alloc (session); +atomic_set (&session->ref_count,1 );nfs4_init_channel (&session->fore_channel);
@@ -4538,6 +4540,8 @@ static int _nfs4_proc_create_session(struct nfs4_session *session) &session->fore_channel.chan_attrs);nfs4_adjust_channel_attrs (&args.bc_attrs, &session->back_channel.chan_attrs); +nfs41_set_session_valid (session);/* Activate session */ +/* Increment the clientid slot sequence id */ clp->cl_seqid++; }
@@ -4603,6 +4607,10 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)dprintk ("--> nfs4_proc_destroy_session\n" ); +/* session is still being created */ +if (nfs41_test_session_alloc (session)) +return status; + msg.rpc_proc =nfs4_proc (session->clp,NFSPROC4_CLNT_DESTROY_SESSION ); msg.rpc_argp = session; msg.rpc_resp =NULL ;
@@ -4641,6 +4649,9 @@ static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred) server = list_entry(clp->cl_superblocks.next, struct nfs_server, client_link); +if (nfs41_test_session_alloc (clp->cl_session)) +return -NFS4ERR_STALE_CLIENTID ; + args.sa_cache_this =0 ; status =_nfs4_call_sync (server, &msg, &args, &res,0 );
include/linux/nfs41_session_recovery.h new file +40 -0
@@ -0,0 +1,40 @@ +/* +* Session Recovery header file +* +* Author: Rahul Iyer <[email protected]> +* +* This code is released under GPL. For details see Documentation/COPYING +*/ + +#ifndef __NFS41_SESSION_RECOVERY_H__ +#define __NFS41_SESSION_RECOVERY_H__ + +#if defined(CONFIG_NFS_V4_1 ) + +/* +* Session state bits +*/ +enum nfs41_session_state { +NFS41_SESSION_ALLOC =0 , +NFS41_SESSION_RECOVER , +}; + +/* +* Set the session state to alloc +*/ +static inline int nfs41_set_session_alloc (struct nfs4_session *session) +{ +return test_and_set_bit (NFS41_SESSION_ALLOC , &session->session_state); +} + +static inline int nfs41_test_session_alloc (struct nfs4_session *session) +{ +return test_bit (NFS41_SESSION_ALLOC , &session->session_state); +} + +int nfs41_set_session_valid (struct nfs4_session *); +int nfs41_recover_session (struct nfs4_session *); +int nfs41_recover_session_sync (struct nfs4_session *); + +#endif /* CONFIG_NFS_V4_1 */ +#endif /* __NFS41_SESSION_RECOVERY_H__ */
Signature · 1 line
1.6.0.2
RFC 40/85 nfs41: schedule async session reset
In reply to Benny HalevyFrom: Andy Adamson <[email protected]>
Define a new session reset state which is set upon a sequence operation error in both the sync and async error handlers.
Place all new requests and all but the last outstanding rpc on the slot_tbl_waitq. Spawn the recovery thread when the last slot is free. Call nfs4_proc_destroy_session, reinitialize the session, call nfs4_proc_create_session, clear the session reset state, and wake up the next task on the slot_tbl_waitq.
Return the nfs4_proc_destroy_session status to the session reclaimer and check for NFS4ERR_BADSESSION and NFS4ERR_DEADSESSION. Other destroy session errors should be handled in nfs4_proc_destroy_session where the call can be retried with adjusted arguments.
--- fs/nfs/nfs41_session_recovery.c | 51 +++++++++++++++++++++-- fs/nfs/nfs4_fs.h | 2 +- fs/nfs/nfs4proc.c | 69 +++++++++++++++++++++++++++++-- include/linux/nfs41_session_recovery.h | 30 ++++++++++++++ 4 files changed, 141 insertions(+), 11 deletions(-)
fs/nfs/nfs41_session_recovery.c +46 -5
@@ -48,6 +48,17 @@ static int nfs41_start_session_recovery(struct nfs4_session *session)return ret; } +/* +* Session reset +*/ + +int nfs41_wait_session_reset (struct nfs4_session *session) +{ +might_sleep (); +return wait_on_bit (&session->session_state,NFS41_SESSION_RESET , + nfs4_wait_bit_killable,TASK_KILLABLE ); +} +struct reclaimer_arg {struct nfs4_session *session; };
@@ -74,17 +85,49 @@ static int nfs41_wait_session_recover_sync(struct nfs4_session *session)static int session_reclaimer (void *arg) { -int ret; +int ret, reset;struct reclaimer_arg *rec = (struct reclaimer_arg *)arg; -dprintk ("--> %s\n" , __func__); +dprintk ("--> %s session %p\n" , __func__, rec->session);allow_signal (SIGKILL ); - ret =nfs4_proc_create_session (rec->session); + reset =nfs41_test_session_reset (rec->session); +if (reset) { +dprintk ("%s Session Reset\n" , __func__); +/* Reset is called only when all slots are clear. +* +* Bail on the reset if destroy session op fails or if +* the session ref_count is not 1 +* +* Of course since we are resetting the session, +* it's OK if the session is already destroyed +* on the server. +*/ + ret =nfs4_proc_destroy_session (rec->session); +switch (ret) { +case 0 : +case -NFS4ERR_BADSESSION : +case -NFS4ERR_DEADSESSION : +break ; +default : + goto out_error; + } +memset (rec->session->sess_id,0 ,sizeof (nfs41_sessionid)); + } + ret =nfs4_proc_create_session (rec->session, reset);if (ret) goto out_error; out: +if (reset) { +struct nfs4_slot_table *tbl; + + tbl = &rec->session->fore_channel.slot_table; +/* Need to clear reset bit and wake up the next rpc task +* even on error */ +nfs41_clear_session_reset (rec->session); +rpc_wake_up_next (&tbl->slot_tbl_waitq); + }nfs41_end_session_recovery (rec->session);kfree (rec);module_put_and_exit (0 );
@@ -96,8 +139,6 @@ out_error:switch (ret) {case -NFS4ERR_STALE_CLIENTID : -case -NFS4ERR_STALE_STATEID : -case -NFS4ERR_EXPIRED :set_bit (NFS4CLNT_LEASE_EXPIRED , &rec->session->clp->cl_state);break ; }
fs/nfs/nfs4_fs.h +1 -1
@@ -196,7 +196,7 @@ extern int nfs4_setup_sequence(struct nfs_client *clp,extern void nfs4_put_session (struct nfs4_session **session);extern void nfs4_get_session (struct nfs_client *clp);extern struct nfs4_session *nfs4_alloc_session (void ); -extern int nfs4_proc_create_session (struct nfs4_session *); +extern int nfs4_proc_create_session (struct nfs4_session *,int reset);extern int nfs4_proc_destroy_session (struct nfs4_session *);#else /* CONFIG_NFS_v4_1 */ static inline int nfs4_setup_sequence(struct nfs_client *clp,
fs/nfs/nfs4proc.c +64 -5
117 lines not on this page · raw message
include/linux/nfs41_session_recovery.h +30 -0
@@ -13,10 +13,17 @@/* * Session state bits +* +* State machine. +* NFS41_SESSION_ALLOC bit set: session is ready for create_session call. +* NFS41_SESSION_RECOVER bit set: session is being reset/recovered +* NFS41_SESSION_ALLOC bit unset: valid session in use. +* NFS41_SESSION_RESET bit set: session is being reset. */ enum nfs41_session_state {NFS41_SESSION_ALLOC =0 ,NFS41_SESSION_RECOVER , +NFS41_SESSION_RESET , };/*
@@ -32,6 +39,29 @@ static inline int nfs41_test_session_alloc(struct nfs4_session *session)return test_bit (NFS41_SESSION_ALLOC , &session->session_state); } +/* +* Set, test, and clear the session reset state +*/ +static inline int nfs41_set_session_reset (struct nfs4_session *session) +{ +return test_and_set_bit (NFS41_SESSION_RESET , &session->session_state); +} + +static inline int nfs41_test_session_reset (struct nfs4_session *session) +{ +return test_bit (NFS41_SESSION_RESET , &session->session_state); +} + +static inline void nfs41_clear_session_reset (struct nfs4_session *session) +{ +smp_mb__before_clear_bit (); +clear_bit (NFS41_SESSION_RESET , + &session->session_state); +smp_mb__after_clear_bit (); +wake_up_bit (&session->session_state,NFS41_SESSION_RESET ); +} + +int nfs41_wait_session_reset (struct nfs4_session *session);int nfs41_set_session_valid (struct nfs4_session *);int nfs41_recover_session (struct nfs4_session *);int nfs41_recover_session_sync (struct nfs4_session *);
Signature · 1 line
1.6.0.2
RFC 41/85 nfs41: lease renewal
In reply to Benny HalevySend a NFSv4.1 SEQUENCE op rather than RENEW that was deprecated in minorversion 1.
Use the nfs_client minorversion to select reboot_recover/ network_partition_recovery/state_renewal ops.
Note: we use reclaimer to create the nfs41 session before there are any cl_superblocks for the nfs_client.
--- fs/nfs/nfs4_fs.h | 11 +++++++- fs/nfs/nfs4proc.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++- fs/nfs/nfs4renewd.c | 5 ++- fs/nfs/nfs4state.c | 21 +++++++++-------- 4 files changed, 81 insertions(+), 16 deletions(-)
fs/nfs/nfs4_fs.h +9 -2
@@ -162,6 +162,11 @@ struct nfs4_exception {struct nfs4_state_recovery_ops {int (*recover_open)(struct nfs4_state_owner *,struct nfs4_state *);int (*recover_lock)(struct nfs4_state *,struct file_lock *); +int (*renew_lease)(struct nfs_client *,struct rpc_cred *); +}; + +struct nfs4_state_maintenance_ops { +int (*sched_state_renewal)(struct nfs_client *,struct rpc_cred *); };extern struct dentry_operations nfs4_dentry_operations;
@@ -187,8 +192,8 @@ extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhextern int nfs4_proc_fs_locations (struct inode *dir,const struct qstr *name,struct nfs4_fs_locations *fs_locations,struct page *page); -extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops; -extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops; +extern struct nfs4_state_recovery_ops *nfs4_reboot_recovery_ops[]; +extern struct nfs4_state_recovery_ops *nfs4_network_partition_recovery_ops[];#if defined(CONFIG_NFS_V4_1 ) extern int nfs4_setup_sequence(struct nfs_client *clp, struct nfs41_sequence_args *args, struct nfs41_sequence_res *res,
@@ -207,6 +212,8 @@ static inline int nfs4_setup_sequence(struct nfs_client *clp, }#endif /* CONFIG_NFS_V4_1 */ +extern struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[]; +extern const u32 nfs4_fattr_bitmap[2 ];extern const u32 nfs4_statfs_bitmap[2 ];extern const u32 nfs4_pathconf_bitmap[2 ];
fs/nfs/nfs4proc.c +58 -2
78 lines not on this page · raw message
fs/nfs/nfs4renewd.c +3 -2
@@ -59,12 +59,14 @@void nfs4_renew_state (struct work_struct *work) { +struct nfs4_state_maintenance_ops *ops;struct nfs_client *clp = container_of(work, struct nfs_client, cl_renewd.work);struct rpc_cred *cred;long lease, timeout;unsigned long last, now; + ops = nfs4_state_renewal_ops[clp->cl_minorversion];down_read (&clp->cl_sem);dprintk ("%s: start\n" , __func__);/* Are there any active superblocks? */
@@ -86,8 +88,7 @@ nfs4_renew_state(struct work_struct *work) }spin_unlock (&clp->cl_lock);/* Queue an asynchronous RENEW. */ -nfs4_proc_async_renew (clp, cred); -put_rpccred (cred); + ops->sched_state_renewal (clp, cred); timeout = (2 * lease) /3 ;spin_lock (&clp->cl_lock); }else
fs/nfs/nfs4state.c +11 -10
@@ -952,24 +952,24 @@ static int reclaimer(void *ptr)/* Ensure exclusive access to NFSv4 state */ down_write (&clp->cl_sem);/* Are there any NFS mounts out there? */ -if (list_empty (&clp->cl_superblocks)) +if (clp->cl_minorversion ==0 &&list_empty (&clp->cl_superblocks)) goto out; restart_loop:dprintk ("%s: starting loop\n" , __func__); - ops = &nfs4_network_partition_recovery_ops; + ops = nfs4_network_partition_recovery_ops[clp->cl_minorversion];/* Are there any open files on this volume? */ cred =nfs4_get_renew_cred (clp);if (cred !=NULL ) {/* Yes there are: try to renew the old lease */ - status =nfs4_proc_renew (clp, cred); + status = ops->renew_lease (clp, cred);put_rpccred (cred);switch (status) { -case 0 : -case -NFS4ERR_CB_PATH_DOWN : - goto out; -case -NFS4ERR_STALE_CLIENTID : -case -NFS4ERR_LEASE_MOVED : - ops = &nfs4_reboot_recovery_ops; +case 0 : +case -NFS4ERR_CB_PATH_DOWN : + goto out; +case -NFS4ERR_STALE_CLIENTID : +case -NFS4ERR_LEASE_MOVED : + ops = nfs4_reboot_recovery_ops[clp->cl_minorversion]; } }else {/* "reboot" to ensure we clear all state on the server */
@@ -998,7 +998,8 @@ restart_loop: status =nfs4_reclaim_open_state (ops, sp);if (status <0 ) {if (status == -NFS4ERR_NO_GRACE ) { - ops = &nfs4_network_partition_recovery_ops; + ops = nfs4_network_partition_recovery_ops[ + clp->cl_minorversion]; status =nfs4_reclaim_open_state (ops, sp); }if (status == -NFS4ERR_STALE_CLIENTID )
Signature · 1 line
1.6.0.2
RFC 42/85 nfs41: sunrpc: Export the call prepare state for session reset
In reply to Benny HalevyFrom: Andy Adamson <[email protected]>
--- include/linux/sunrpc/clnt.h | 1 + include/linux/sunrpc/sched.h | 1 + net/sunrpc/clnt.c | 13 +++++++++++++ net/sunrpc/sched.c | 2 +- 4 files changed, 16 insertions(+), 1 deletions(-)
include/linux/sunrpc/clnt.h +1 -0
@@ -151,6 +151,7 @@ int rpc_call_sync(struct rpc_clnt *clnt, const struct rpc_message *msg, int flags);struct rpc_task *rpc_call_null (struct rpc_clnt *clnt,struct rpc_cred *cred,int flags); +void rpc_restart_call_prepare (struct rpc_task *);void rpc_restart_call (struct rpc_task *);void rpc_setbufsize (struct rpc_clnt *,unsigned int ,unsigned int );size_t rpc_max_payload (struct rpc_clnt *);
include/linux/sunrpc/sched.h +1 -0
@@ -237,6 +237,7 @@ void rpc_show_tasks(void);int rpc_init_mempool (void );void rpc_destroy_mempool (void );extern struct workqueue_struct *rpciod_workqueue; +void rpc_prepare_task (struct rpc_task *task);static inline void rpc_exit (struct rpc_task *task,int status) {
net/sunrpc/clnt.c +13 -0
@@ -684,6 +684,19 @@ void rpc_force_rebind(struct rpc_clnt *clnt)EXPORT_SYMBOL_GPL (rpc_force_rebind);/* +* Restart an (async) RPC call from the call_prepare state. +* Usually called from within the exit handler. +*/ +void +rpc_restart_call_prepare (struct rpc_task *task) +{ +if (RPC_ASSASSINATED (task)) +return ; + task->tk_action = rpc_prepare_task; +} +EXPORT_SYMBOL_GPL (rpc_restart_call_prepare); + +/* * Restart an (async) RPC call. Usually called from within the * exit handler. */
net/sunrpc/sched.c +1 -1
@@ -574,7 +574,7 @@ EXPORT_SYMBOL_GPL(rpc_delay);/* * Helper to call task->tk_ops->rpc_call_prepare */ -static void rpc_prepare_task (struct rpc_task *task) +void rpc_prepare_task (struct rpc_task *task) { task->tk_ops->rpc_call_prepare (task, task->tk_calldata); }
Signature · 1 line
1.6.0.2