From 14b7f4a1edf15808cf52dc38277ffe1d84854839 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 5 May 2016 06:53:47 -0400 Subject: nfsd: handle seqid wraparound in nfsd4_preprocess_layout_stateid Move the existing static function to an inline helper, and call it. Reviewed-by: Christoph Hellwig Signed-off-by: Jeff Layton Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4layouts.c | 2 +- fs/nfsd/nfs4state.c | 8 +------- fs/nfsd/state.h | 5 +++++ 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'fs/nfsd') diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index 825c7bc8d789..953c0755cb37 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -289,7 +289,7 @@ nfsd4_preprocess_layout_stateid(struct svc_rqst *rqstp, status = nfserr_bad_stateid; mutex_lock(&ls->ls_mutex); - if (stateid->si_generation > stid->sc_stateid.si_generation) + if (nfsd4_stateid_generation_after(stateid, &stid->sc_stateid)) goto out_unlock_stid; if (layout_type != ls->ls_layout_type) goto out_unlock_stid; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 0462eeddfff9..f5f82e145018 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4651,12 +4651,6 @@ grace_disallows_io(struct net *net, struct inode *inode) return opens_in_grace(net) && mandatory_lock(inode); } -/* Returns true iff a is later than b: */ -static bool stateid_generation_after(stateid_t *a, stateid_t *b) -{ - return (s32)(a->si_generation - b->si_generation) > 0; -} - static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session) { /* @@ -4670,7 +4664,7 @@ static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_s return nfs_ok; /* If the client sends us a stateid from the future, it's buggy: */ - if (stateid_generation_after(in, ref)) + if (nfsd4_stateid_generation_after(in, ref)) return nfserr_bad_stateid; /* * However, we could see a stateid from the past, even from a diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index c050c53036a6..986e51e5ceac 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -573,6 +573,11 @@ enum nfsd4_cb_op { NFSPROC4_CLNT_CB_SEQUENCE, }; +/* Returns true iff a is later than b: */ +static inline bool nfsd4_stateid_generation_after(stateid_t *a, stateid_t *b) +{ + return (s32)(a->si_generation - b->si_generation) > 0; +} struct nfsd4_compound_state; struct nfsd_net; -- cgit v1.2.3 From 6625d0913771df5f12b9531c8cb8414e55f1c21d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 4 May 2016 10:52:55 -0400 Subject: svcrdma: Do not add XDR padding to xdr_buf page vector An xdr_buf has a head, a vector of pages, and a tail. Each RPC request is presented to the NFS server contained in an xdr_buf. The RDMA transport would like to supply the NFS server with only the NFS WRITE payload bytes in the page vector. In some common cases, that would allow the NFS server to swap those pages right into the target file's page cache. Have the transport's RDMA Read logic put XDR pad bytes in the tail iovec, and not in the pages that hold the data payload. The NFSv3 WRITE XDR decoder is finicky about the lengths involved, so make sure it is looking in the correct places when computing the total length of the incoming NFS WRITE request. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs3xdr.c | 2 +- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/nfsd') diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 2246454dec76..c5eff5fde11c 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -379,7 +379,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, */ hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len - - hdr; + + rqstp->rq_arg.tail[0].iov_len - hdr; /* * Round the length of the data which was specified up to * the next multiple of XDR units and then compare that diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index 3b24a646eb46..234be9de6210 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -488,7 +488,7 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt, if (page_offset & 3) { u32 pad = 4 - (page_offset & 3); - head->arg.page_len += pad; + head->arg.tail[0].iov_len += pad; head->arg.len += pad; head->arg.buflen += pad; page_offset += pad; -- cgit v1.2.3