aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2004-08-22 23:02:30 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-22 23:02:30 -0700
commiteb229d253e6cf376756101ea3fdfd4a17edc5450 (patch)
tree0b43a21df0c47a01166f2819487ebd7e77b2bce0 /fs
parent57b6949e9ca8964dcb4ba712fe3876eb21fe84ae (diff)
downloadhistory-eb229d253e6cf376756101ea3fdfd4a17edc5450.tar.gz
[PATCH] kNFSd: fix two xdr-encode bugs for readdirplus reply
More fall-out from the change to allow multi-page replies to readdir requests. Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs3proc.c12
-rw-r--r--fs/nfsd/nfs3xdr.c10
2 files changed, 18 insertions, 4 deletions
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 941ceaec1a1d5d..effcd19130908c 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -492,8 +492,16 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
count += PAGE_SIZE;
}
resp->count = count >> 2;
- if (resp->offset)
- xdr_encode_hyper(resp->offset, offset);
+ if (resp->offset) {
+ if (unlikely(resp->offset1)) {
+ /* we ended up with offset on a page boundary */
+ *resp->offset = htonl(offset >> 32);
+ *resp->offset1 = htonl(offset & 0xffffffff);
+ resp->offset1 = NULL;
+ } else {
+ xdr_encode_hyper(resp->offset, offset);
+ }
+ }
RETURN_STATUS(nfserr);
}
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index e7f907dfa2b953..f3fbef66ec0f9b 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -762,10 +762,16 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
/* stupid readdir cookie */
memcpy(p, resp->verf, 8); p += 2;
xdr_ressize_check(rqstp, p);
- p = resp->buffer;
+ if (rqstp->rq_res.head[0].iov_len + (2<<2) > PAGE_SIZE)
+ return 1; /*No room for trailer */
+ rqstp->rq_res.page_len = (resp->count) << 2;
+
+ /* add the 'tail' to the end of the 'head' page - page 0. */
+ rqstp->rq_restailpage = 0;
+ rqstp->rq_res.tail[0].iov_base = p;
*p++ = 0; /* no more entries */
*p++ = htonl(resp->common.err == nfserr_eof);
- rqstp->rq_res.page_len = (resp->count + 2) << 2;
+ rqstp->rq_res.tail[0].iov_len = 2<<2;
return 1;
} else
return xdr_ressize_check(rqstp, p);