+ rpc-add-wrapper-for-svc_reserve-to-account-for-checksum.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     RPC: add wrapper for svc_reserve to account for checksum
has been added to the -mm tree.  Its filename is
     rpc-add-wrapper-for-svc_reserve-to-account-for-checksum.patch

*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: RPC: add wrapper for svc_reserve to account for checksum
From: Jeff Layton <jlayton@xxxxxxxxxx>

When the kernel calls svc_reserve to downsize the expected size of an RPC
reply, it fails to account for the possibility of a checksum at the end of
the packet.  If a client mounts a NFSv2/3 with sec=krb5i/p, and does I/O
then you'll generally see messages similar to this in the server's ring
buffer:

RPC request reserved 164 but used 208

While I was never able to verify it, I suspect that this problem is also
the root cause of some oopses I've seen under these conditions:

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=227726

This is probably also a problem for other sec= types and for NFSv4.  The
large reserved size for NFSv4 compound packets seems to generally paper
over the problem, however.

This patch adds a wrapper for svc_reserve that accounts for the possibility
of a checksum.  It also fixes up the appropriate callers of svc_reserve to
call the wrapper.  For now, it just uses a hardcoded value that I
determined via testing.  That value may need to be revised upward as things
change, or we may want to eventually add a new auth_op that attempts to
calculate this somehow.

Unfortunately, there doesn't seem to be a good way to reliably determine
the expected checksum length prior to actually calculating it, particularly
with schemes like spkm3.

Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
Cc: Neil Brown <neilb@xxxxxxx>
Cc: Trond Myklebust <trond.myklebust@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 fs/nfsd/nfs3proc.c         |    2 +-
 fs/nfsd/nfsproc.c          |    2 +-
 include/linux/sunrpc/svc.h |   20 ++++++++++++++++++++
 net/sunrpc/svc.c           |    2 +-
 4 files changed, 23 insertions(+), 3 deletions(-)

diff -puN fs/nfsd/nfs3proc.c~rpc-add-wrapper-for-svc_reserve-to-account-for-checksum fs/nfsd/nfs3proc.c
--- a/fs/nfsd/nfs3proc.c~rpc-add-wrapper-for-svc_reserve-to-account-for-checksum
+++ a/fs/nfsd/nfs3proc.c
@@ -177,7 +177,7 @@ nfsd3_proc_read(struct svc_rqst *rqstp, 
 	if (max_blocksize < resp->count)
 		resp->count = max_blocksize;
 
-	svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);
+	svc_reserve_auth(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);
 
 	fh_copy(&resp->fh, &argp->fh);
 	nfserr = nfsd_read(rqstp, &resp->fh, NULL,
diff -puN fs/nfsd/nfsproc.c~rpc-add-wrapper-for-svc_reserve-to-account-for-checksum fs/nfsd/nfsproc.c
--- a/fs/nfsd/nfsproc.c~rpc-add-wrapper-for-svc_reserve-to-account-for-checksum
+++ a/fs/nfsd/nfsproc.c
@@ -155,7 +155,7 @@ nfsd_proc_read(struct svc_rqst *rqstp, s
 				argp->count);
 		argp->count = NFSSVC_MAXBLKSIZE_V2;
 	}
-	svc_reserve(rqstp, (19<<2) + argp->count + 4);
+	svc_reserve_auth(rqstp, (19<<2) + argp->count + 4);
 
 	resp->count = argp->count;
 	nfserr = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh), NULL,
diff -puN include/linux/sunrpc/svc.h~rpc-add-wrapper-for-svc_reserve-to-account-for-checksum include/linux/sunrpc/svc.h
--- a/include/linux/sunrpc/svc.h~rpc-add-wrapper-for-svc_reserve-to-account-for-checksum
+++ a/include/linux/sunrpc/svc.h
@@ -396,4 +396,24 @@ char *		   svc_print_addr(struct svc_rqs
 
 #define	RPC_MAX_ADDRBUFLEN	(63U)
 
+/*
+ * When we want to reduce the size of the reserved space in the response
+ * buffer, we need to take into account the size of any checksum data that
+ * may be at the end of the packet. For now, just use a hardcoded value
+ * for each possible authflavor. This will need to be updated when new
+ * encryption types or algorithms are added, or we'll have to come up with
+ * a way to reasonably calculate this on the fly (maybe via a new auth_op).
+ */
+static inline void
+svc_reserve_auth(struct svc_rqst *rqstp, int space)
+{
+	int			added_space = 0;
+
+	switch(rqstp->rq_authop->flavour) {
+		case RPC_AUTH_GSS:
+			added_space = 56; /* determined empirically */
+	}
+	return svc_reserve(rqstp, space + added_space);
+}
+
 #endif /* SUNRPC_SVC_H */
diff -puN net/sunrpc/svc.c~rpc-add-wrapper-for-svc_reserve-to-account-for-checksum net/sunrpc/svc.c
--- a/net/sunrpc/svc.c~rpc-add-wrapper-for-svc_reserve-to-account-for-checksum
+++ a/net/sunrpc/svc.c
@@ -907,7 +907,7 @@ svc_process(struct svc_rqst *rqstp)
 	 * better idea of reply size
 	 */
 	if (procp->pc_xdrressize)
-		svc_reserve(rqstp, procp->pc_xdrressize<<2);
+		svc_reserve_auth(rqstp, procp->pc_xdrressize<<2);
 
 	/* Call the function that processes the request. */
 	if (!versp->vs_dispatch) {
_

Patches currently in -mm which might be from jlayton@xxxxxxxxxx are

make-iunique-use-a-do-while-loop-rather-than-its-obscure-goto-loop.patch
make-static-counters-in-new_inode-and-iunique-be-32-bits.patch
make-static-counters-in-new_inode-and-iunique-be-32-bits-comments.patch
change-libfs-sb-creation-routines-to-avoid-collisions-with-their-root-inodes.patch
rpc-add-wrapper-for-svc_reserve-to-account-for-checksum.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux