Skip to content

Commit

Permalink
[PATCH] knfsd: nfsd4: fix corruption of returned data when using 64k …
Browse files Browse the repository at this point in the history
…pages

In v4 we grab an extra page just for the padding of returned data.  The
formula that the rpc server uses to allocate pages for the response doesn't
take into account this extra page.

Instead of adjusting those formulae, we adopt the same solution as v2 and v3,
and put the "tail" data in the same page as the "head" data.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
NeilBrown authored and Linus Torvalds committed Apr 11, 2006
1 parent f0e2993 commit 6ed6dec
Showing 1 changed file with 17 additions and 25 deletions.
42 changes: 17 additions & 25 deletions fs/nfsd/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2084,27 +2084,20 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read
WRITE32(eof);
WRITE32(maxcount);
ADJUST_ARGS();
resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;

resp->xbuf->head[0].iov_len = (char*)p
- (char*)resp->xbuf->head[0].iov_base;
resp->xbuf->page_len = maxcount;

/* read zero bytes -> don't set up tail */
if(!maxcount)
return 0;

/* set up page for remaining responses */
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 = p;
resp->xbuf->tail[0].iov_len = 0;
resp->p = resp->xbuf->tail[0].iov_base;
resp->end = resp->p + PAGE_SIZE/4;

if (maxcount&3) {
*(resp->p)++ = 0;
RESERVE_SPACE(4);
WRITE32(0);
resp->xbuf->tail[0].iov_base += maxcount&3;
resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
ADJUST_ARGS();
}
return 0;
}
Expand Down Expand Up @@ -2141,21 +2134,20 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r

WRITE32(maxcount);
ADJUST_ARGS();
resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;
resp->xbuf->head[0].iov_len = (char*)p
- (char*)resp->xbuf->head[0].iov_base;
resp->xbuf->page_len = maxcount;

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 = p;
resp->xbuf->tail[0].iov_len = 0;
resp->p = resp->xbuf->tail[0].iov_base;
resp->end = resp->p + PAGE_SIZE/4;

resp->xbuf->page_len = maxcount;
if (maxcount&3) {
*(resp->p)++ = 0;
RESERVE_SPACE(4);
WRITE32(0);
resp->xbuf->tail[0].iov_base += maxcount&3;
resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
ADJUST_ARGS();
}
return 0;
}
Expand Down

0 comments on commit 6ed6dec

Please sign in to comment.