Re: [PATCH v2 001/118] NFSD: Fix returned READDIR offset cookie

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Nov 20, 2020 at 03:33:51PM -0500, Chuck Lever wrote:
> Code inspection shows that the server's NFSv3 READDIR implementation
> returns the same offset cookie as the client sent, instead of the
> last cookie it returns in the reply's dirlist. This is unlike the
> NFSv2 READDIR, NFSv3 READDIRPLUS, and NFSv4 READDIR implementations,
> and it's been like this since the beginning of kernel git history.

Surely this should have caused actual failures in practice.

> I copied the logic from nfsd3_proc_readdirplus().
> 
> Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
> ---
>  fs/nfsd/nfs3proc.c |    7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
> index d9be589fed15..e0ad18d6b5a8 100644
> --- a/fs/nfsd/nfs3proc.c
> +++ b/fs/nfsd/nfs3proc.c
> @@ -430,6 +430,7 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
>  	struct nfsd3_readdirargs *argp = rqstp->rq_argp;
>  	struct nfsd3_readdirres  *resp = rqstp->rq_resp;
>  	int		count = 0;
> +	loff_t		offset;
>  	struct page	**p;
>  	caddr_t		page_addr = NULL;
>  
> @@ -448,7 +449,9 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
>  	resp->common.err = nfs_ok;
>  	resp->buffer = argp->buffer;
>  	resp->rqstp = rqstp;
> -	resp->status = nfsd_readdir(rqstp, &resp->fh, (loff_t *)&argp->cookie,

Doesn't nfsd_readdir() update argp->cookie to point to the last offset?

> +	offset = argp->cookie;
> +
> +	resp->status = nfsd_readdir(rqstp, &resp->fh, &offset,
>  				    &resp->common, nfs3svc_encode_entry);
>  	memcpy(resp->verf, argp->verf, 8);
>  	count = 0;
> @@ -464,8 +467,6 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp)
>  	}
>  	resp->count = count >> 2;
>  	if (resp->offset) {
> -		loff_t offset = argp->cookie;

So, this shouldn't be equal to the initial cookie any more.

Am I missing something?

--b.

> -
>  		if (unlikely(resp->offset1)) {
>  			/* we ended up with offset on a page boundary */
>  			*resp->offset = htonl(offset >> 32);
> 



[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux