From: NeilBrown More fall-out from the change to allow multi-page replies to readdir requests. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton --- 25-akpm/fs/nfsd/nfs3proc.c | 12 ++++++++++-- 25-akpm/fs/nfsd/nfs3xdr.c | 10 ++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff -puN fs/nfsd/nfs3proc.c~knfsd-fix-two-xdr-encode-bugs-for-readdirplus-reply fs/nfsd/nfs3proc.c --- 25/fs/nfsd/nfs3proc.c~knfsd-fix-two-xdr-encode-bugs-for-readdirplus-reply 2004-08-20 00:01:00.689572400 -0700 +++ 25-akpm/fs/nfsd/nfs3proc.c 2004-08-20 00:01:00.694571640 -0700 @@ -492,8 +492,16 @@ nfsd3_proc_readdirplus(struct svc_rqst * 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 -puN fs/nfsd/nfs3xdr.c~knfsd-fix-two-xdr-encode-bugs-for-readdirplus-reply fs/nfsd/nfs3xdr.c --- 25/fs/nfsd/nfs3xdr.c~knfsd-fix-two-xdr-encode-bugs-for-readdirplus-reply 2004-08-20 00:01:00.691572096 -0700 +++ 25-akpm/fs/nfsd/nfs3xdr.c 2004-08-20 00:01:00.695571488 -0700 @@ -762,10 +762,16 @@ nfs3svc_encode_readdirres(struct svc_rqs /* 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); _