Message ID | 20210930194442.249907-1-trondmy@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/2] nfsd4: Handle the NFSv4 READDIR 'dircount' hint being zero | expand |
> On Sep 30, 2021, at 3:44 PM, trondmy@kernel.org wrote: > > From: Trond Myklebust <trond.myklebust@hammerspace.com> > > RFC3530 notes that the 'dircount' field may be zero, in which case the > recommendation is to ignore it, and only enforce the 'maxcount' field. > In RFC5661, this recommendation to ignore a zero valued field becomes a > requirement. > > Fixes: aee377644146 ("nfsd4: fix rd_dircount enforcement") > Cc: <stable@vger.kernel.org> > Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Pulled into the next 5.15-rc for NFSD. Thanks! > --- > fs/nfsd/nfs4xdr.c | 19 +++++++++++-------- > 1 file changed, 11 insertions(+), 8 deletions(-) > > diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c > index 7abeccb975b2..cf030ebe2827 100644 > --- a/fs/nfsd/nfs4xdr.c > +++ b/fs/nfsd/nfs4xdr.c > @@ -3544,15 +3544,18 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, > goto fail; > cd->rd_maxcount -= entry_bytes; > /* > - * RFC 3530 14.2.24 describes rd_dircount as only a "hint", so > - * let's always let through the first entry, at least: > + * RFC 3530 14.2.24 describes rd_dircount as only a "hint", and > + * notes that it could be zero. If it is zero, then the server > + * should enforce only the rd_maxcount value. > */ > - if (!cd->rd_dircount) > - goto fail; > - name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8; > - if (name_and_cookie > cd->rd_dircount && cd->cookie_offset) > - goto fail; > - cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie); > + if (cd->rd_dircount) { > + name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8; > + if (name_and_cookie > cd->rd_dircount && cd->cookie_offset) > + goto fail; > + cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie); > + if (!cd->rd_dircount) > + cd->rd_maxcount = 0; > + } > > cd->cookie_offset = cookie_offset; > skip_entry: > -- > 2.31.1 > -- Chuck Lever
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 7abeccb975b2..cf030ebe2827 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3544,15 +3544,18 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, goto fail; cd->rd_maxcount -= entry_bytes; /* - * RFC 3530 14.2.24 describes rd_dircount as only a "hint", so - * let's always let through the first entry, at least: + * RFC 3530 14.2.24 describes rd_dircount as only a "hint", and + * notes that it could be zero. If it is zero, then the server + * should enforce only the rd_maxcount value. */ - if (!cd->rd_dircount) - goto fail; - name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8; - if (name_and_cookie > cd->rd_dircount && cd->cookie_offset) - goto fail; - cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie); + if (cd->rd_dircount) { + name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8; + if (name_and_cookie > cd->rd_dircount && cd->cookie_offset) + goto fail; + cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie); + if (!cd->rd_dircount) + cd->rd_maxcount = 0; + } cd->cookie_offset = cookie_offset; skip_entry: