From: Neil Brown <neilb@cse.unsw.edu.au>,

From: Miquel van Smoorenburg <miquels@cistron.nl>

While I was stress-testing NFS/XFS on 2.6.1/2.6.2-rc, I found that
sometimes my "dd" would exit with:

	#  dd if=/dev/zero bs=4096 > /mnt/file
	dd: writing `standard output': Invalid argument
	1100753+0 records in
	1100752+0 records out

After adding some debug printk's to the server and client code and some
tcpdump-ing, I found that the NFSERR_INVAL was returned by nfsd_commit on
the server.

Turns out that the "offset" argument is off_t instead of loff_t.  It isn't
used at all (unfortunately), but it _is_ checked for sanity, so that's
where the error came from.



---

 fs/nfsd/nfs3proc.c        |    4 ++--
 fs/nfsd/vfs.c             |    2 +-
 include/linux/nfsd/nfsd.h |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff -puN fs/nfsd/nfs3proc.c~nfsd-needs-loff_t fs/nfsd/nfs3proc.c
--- 25/fs/nfsd/nfs3proc.c~nfsd-needs-loff_t	2004-02-09 22:21:25.000000000 -0800
+++ 25-akpm/fs/nfsd/nfs3proc.c	2004-02-09 22:21:25.000000000 -0800
@@ -595,10 +595,10 @@ nfsd3_proc_commit(struct svc_rqst * rqst
 {
 	int	nfserr;
 
-	dprintk("nfsd: COMMIT(3)   %s %d@%ld\n",
+	dprintk("nfsd: COMMIT(3)   %s %u@%Lu\n",
 				SVCFH_fmt(&argp->fh),
 				argp->count,
-				(unsigned long) argp->offset);
+				(unsigned long long) argp->offset);
 
 	if (argp->offset > NFS_OFFSET_MAX)
 		RETURN_STATUS(nfserr_inval);
diff -puN fs/nfsd/vfs.c~nfsd-needs-loff_t fs/nfsd/vfs.c
--- 25/fs/nfsd/vfs.c~nfsd-needs-loff_t	2004-02-09 22:21:25.000000000 -0800
+++ 25-akpm/fs/nfsd/vfs.c	2004-02-09 22:21:25.000000000 -0800
@@ -823,7 +823,7 @@ out:
  */
 int
 nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
-               off_t offset, unsigned long count)
+               loff_t offset, unsigned long count)
 {
 	struct file	file;
 	int		err;
diff -puN include/linux/nfsd/nfsd.h~nfsd-needs-loff_t include/linux/nfsd/nfsd.h
--- 25/include/linux/nfsd/nfsd.h~nfsd-needs-loff_t	2004-02-09 22:21:25.000000000 -0800
+++ 25-akpm/include/linux/nfsd/nfsd.h	2004-02-09 22:21:25.000000000 -0800
@@ -86,7 +86,7 @@ int		nfsd_create_v3(struct svc_rqst *, s
 				struct svc_fh *res, int createmode,
 				u32 *verifier, int *truncp);
 int		nfsd_commit(struct svc_rqst *, struct svc_fh *,
-				off_t, unsigned long);
+				loff_t, unsigned long);
 #endif /* CONFIG_NFSD_V3 */
 int		nfsd_open(struct svc_rqst *, struct svc_fh *, int,
 				int, struct file *);

_