[PATCH] NFSv3/v2: Fix data corruption with NFS short reads.

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

 



This bug seems to be present in v2.6.37 or lower versions. The code was
re-organized in v2.6.38 that eliminated the bug. Current upstream code
doesn't have this bug. This may be applicable to some longterm releases!

Here are the bug details:

1. nfs_read_rpcsetup(), args.count and res.count are both set to the
   actual number of bytes to be read. Let us assume that the request is
   for 16K, so arg.count = res.count = 16K
2. nfs3_xdr_readres() conditionally sets res.count to to the actual
   number of bytes read. This condition is true for the first response
   as res.count was set to args.count before the first request. Let us
   say the server returned only 4K bytes. res.count=4K
3. Another read request is sent for the remaining data. Note that
   res.count is NOT updated. It is still set to the actual amount of
   bytes we got in the first response.  The client will send a READ
   request for the remaining 12K.
4. Assume that the server gave all 12K bytes. We still think we got ony
   4K bytes due to conditional update in nfs3_xdr_readres(). The client
   sends further requests, if not EOF! If this response includes EOF, it
   truncates pages beyond 4K+4K causing data corruption beyond 8K. The
   corrupted data is filled with zeros!

Signed-off-by: Malahal Naineni <malahal@xxxxxxxxxx>
---
 fs/nfs/nfs2xdr.c | 3 +--
 fs/nfs/nfs3xdr.c | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 5914a19..710ca56 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -287,8 +287,7 @@ nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
 	}
 
 	dprintk("RPC:      readres OK count %u\n", count);
-	if (count < res->count)
-		res->count = count;
+	res->count = count;
 
 	return count;
 }
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index f6cc60f..152a5e4 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -914,8 +914,7 @@ nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
 		res->eof = 0;
 	}
 
-	if (count < res->count)
-		res->count = count;
+	res->count = count;
 
 	return count;
 }
-- 
1.7.11.7

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




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux