--- /dev/null
+From stable-bounces@linux.kernel.org Fri Jan 11 14:07:21 2008
+From: NeilBrown <neilb@suse.de>
+Date: Fri, 11 Jan 2008 17:06:52 -0500
+Subject: knfsd: Allow NFSv2/3 WRITE calls to succeed when krb5i etc is used.
+To: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: NeilBrown <neilb@suse.de>, Peter Staubach <staubach@redhat.com>, "J. Bruce Fields" <bfields@citi.umich.edu>, nfs@lists.sourceforge.net, stable@kernel.org
+Message-ID: <1200089212-12204-1-git-send-email-bfields@citi.umich.edu>
+
+
+From: NeilBrown <neilb@suse.de>
+
+patch ba67a39efde8312e386c6f603054f8945433d91f in mainline.
+
+When RPCSEC/GSS and krb5i is used, requests are padded, typically to a multiple
+of 8 bytes. This can make the request look slightly longer than it
+really is.
+
+As of
+
+ f34b95689d2ce001c "The NFSv2/NFSv3 server does not handle zero
+ length WRITE request correctly",
+
+the xdr decode routines for NFSv2 and NFSv3 reject requests that aren't
+the right length, so krb5i (for example) WRITE requests can get lost.
+
+This patch relaxes the appropriate test and enhances the related comment.
+
+Signed-off-by: Neil Brown <neilb@suse.de>
+Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
+Cc: Peter Staubach <staubach@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/nfsd/nfs3xdr.c | 5 ++++-
+ fs/nfsd/nfsxdr.c | 5 ++++-
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/fs/nfsd/nfs3xdr.c
++++ b/fs/nfsd/nfs3xdr.c
+@@ -396,8 +396,11 @@ nfs3svc_decode_writeargs(struct svc_rqst
+ * Round the length of the data which was specified up to
+ * the next multiple of XDR units and then compare that
+ * against the length which was actually received.
++ * Note that when RPCSEC/GSS (for example) is used, the
++ * data buffer can be padded so dlen might be larger
++ * than required. It must never be smaller.
+ */
+- if (dlen != XDR_QUADLEN(len)*4)
++ if (dlen < XDR_QUADLEN(len)*4)
+ return 0;
+
+ if (args->count > max_blocksize) {
+--- a/fs/nfsd/nfsxdr.c
++++ b/fs/nfsd/nfsxdr.c
+@@ -313,8 +313,11 @@ nfssvc_decode_writeargs(struct svc_rqst
+ * Round the length of the data which was specified up to
+ * the next multiple of XDR units and then compare that
+ * against the length which was actually received.
++ * Note that when RPCSEC/GSS (for example) is used, the
++ * data buffer can be padded so dlen might be larger
++ * than required. It must never be smaller.
+ */
+- if (dlen != XDR_QUADLEN(len)*4)
++ if (dlen < XDR_QUADLEN(len)*4)
+ return 0;
+
+ rqstp->rq_vec[0].iov_base = (void*)p;