nfsd/nfsd3_proc_readdir: fix buffer count and page pointers
After this commitf875a79
nfsd: allow nfsv3 readdir request to be larger. nfsv3 readdir request size can be larger than PAGE_SIZE. So if the directory been read is large enough, we can use multiple pages in rq_respages. Update buffer count and page pointers like we do in readdirplus to make this happen. Now listing a directory within 3000 files will panic because we are counting in a wrong way and would write on random page. Fixes:f875a79
"nfsd: allow nfsv3 readdir request to be larger" Signed-off-by: Murphy Zhou <jencce.kernel@gmail.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
@@ -573,6 +573,7 @@ int
|
||||
nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
|
||||
{
|
||||
struct nfsd3_readdirargs *args = rqstp->rq_argp;
|
||||
int len;
|
||||
u32 max_blocksize = svc_max_payload(rqstp);
|
||||
|
||||
p = decode_fh(p, &args->fh);
|
||||
@@ -582,8 +583,14 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
|
||||
args->verf = p; p += 2;
|
||||
args->dircount = ~0;
|
||||
args->count = ntohl(*p++);
|
||||
args->count = min_t(u32, args->count, max_blocksize);
|
||||
args->buffer = page_address(*(rqstp->rq_next_page++));
|
||||
len = args->count = min_t(u32, args->count, max_blocksize);
|
||||
|
||||
while (len > 0) {
|
||||
struct page *p = *(rqstp->rq_next_page++);
|
||||
if (!args->buffer)
|
||||
args->buffer = page_address(p);
|
||||
len -= PAGE_SIZE;
|
||||
}
|
||||
|
||||
return xdr_argsize_check(rqstp, p);
|
||||
}
|
||||
|
Reference in New Issue
Block a user