[PATCH 009 of 16] knfsd: nfsd4: fix corruption on readdir encoding with 64k pages

From: NeilBrown
Date: Mon Apr 03 2006 - 01:21:50 EST



Fix corruption on readdir encoding with 64k pages.

Signed-off-by: J. Bruce Fields <bfields@xxxxxxxxxxxxxx>
Signed-off-by: Neil Brown <neilb@xxxxxxx>

### Diffstat output
./fs/nfsd/nfs4xdr.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)

diff ./fs/nfsd/nfs4xdr.c~current~ ./fs/nfsd/nfs4xdr.c
--- ./fs/nfsd/nfs4xdr.c~current~ 2006-04-03 15:12:11.000000000 +1000
+++ ./fs/nfsd/nfs4xdr.c 2006-04-03 15:12:13.000000000 +1000
@@ -2157,7 +2157,7 @@ nfsd4_encode_readdir(struct nfsd4_compou
{
int maxcount;
loff_t offset;
- u32 *page, *savep;
+ u32 *page, *savep, *tailbase;
ENCODE_HEAD;

if (nfserr)
@@ -2173,6 +2173,7 @@ nfsd4_encode_readdir(struct nfsd4_compou
WRITE32(0);
ADJUST_ARGS();
resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;
+ tailbase = p;

maxcount = PAGE_SIZE;
if (maxcount > readdir->rd_maxcount)
@@ -2217,14 +2218,12 @@ nfsd4_encode_readdir(struct nfsd4_compou
*p++ = htonl(readdir->common.err == nfserr_eof);
resp->xbuf->page_len = ((char*)p) - (char*)page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);

- /* allocate a page for the tail */
- svc_take_page(resp->rqstp);
- resp->xbuf->tail[0].iov_base =
- page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
- resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1;
+ /* Use rest of head for padding and remaining ops: */
+ resp->rqstp->rq_restailpage = 0;
+ resp->xbuf->tail[0].iov_base = tailbase;
resp->xbuf->tail[0].iov_len = 0;
resp->p = resp->xbuf->tail[0].iov_base;
- resp->end = resp->p + PAGE_SIZE/4;
+ resp->end = resp->p + (PAGE_SIZE - resp->xbuf->head[0].iov_len)/4;

return 0;
err_no_verf:
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/