Re: [PATCH 2/2] nfs: Fix a missed page unlock after pg_doio()

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

 



On Wed, 2018-10-17 at 12:05 -0400, Benjamin Coddington wrote:
> We must check pg_error and call error_cleanup after any call to
> pg_doio.
> Currently, we are skipping the unlock of a page if we encounter an
> error in
> nfs_pageio_complete() before handing off the work to the RPC layer.
> 
> Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx>
> ---
>  fs/nfs/pagelist.c | 33 ++++++++++++++++++---------------
>  1 file changed, 18 insertions(+), 15 deletions(-)
> 
> diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
> index cd3bc41ab68d..54c2bfc45a57 100644
> --- a/fs/nfs/pagelist.c
> +++ b/fs/nfs/pagelist.c
> @@ -1110,6 +1110,20 @@ static int
> nfs_pageio_add_request_mirror(struct nfs_pageio_descriptor *desc,
>  	return ret;
>  }
>  
> +static void nfs_pageio_error_cleanup(struct nfs_pageio_descriptor
> *desc)
> +{
> +	u32 midx;
> +	struct nfs_pgio_mirror *mirror;
> +
> +	if (!desc->pg_error)
> +		return;
> +
> +	for (midx = 0; midx < desc->pg_mirror_count; midx++) {
> +		mirror = &desc->pg_mirrors[midx];
> +		desc->pg_completion_ops->error_cleanup(&mirror-
> >pg_list);
> +	}
> +}
> +
>  int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
>  			   struct nfs_page *req)
>  {
> @@ -1160,20 +1174,7 @@ int nfs_pageio_add_request(struct
> nfs_pageio_descriptor *desc,
>  	return 1;
>  
>  out_failed:
> -	/*
> -	 * We might have failed before sending any reqs over wire.
> -	 * Clean up rest of the reqs in mirror pg_list.
> -	 */
> -	if (desc->pg_error) {
> -		struct nfs_pgio_mirror *mirror;
> -		void (*func)(struct list_head *);
> -
> -		func = desc->pg_completion_ops->error_cleanup;
> -		for (midx = 0; midx < desc->pg_mirror_count; midx++) {
> -			mirror = &desc->pg_mirrors[midx];
> -			func(&mirror->pg_list);
> -		}
> -	}
> +	nfs_pageio_error_cleanup(desc);
>  	return 0;
>  }
>  
> @@ -1245,7 +1246,9 @@ void nfs_pageio_complete(struct
> nfs_pageio_descriptor *desc)
>  	for (midx = 0; midx < desc->pg_mirror_count; midx++)
>  		nfs_pageio_complete_mirror(desc, midx);
>  
> -	if (desc->pg_ops->pg_cleanup)
> +	if (desc->pg_error < 0)
> +		nfs_pageio_error_cleanup(desc);
> +	else if (desc->pg_ops->pg_cleanup)
>  		desc->pg_ops->pg_cleanup(desc);

Nice catch, but shouldn't we be calling both nfs_pageio_error_cleanup()
and pg_cleanup()? The former would appear to be cleaning up the page
stuff, while the latter is mainly cleaning up the layout.

>  	nfs_pageio_cleanup_mirroring(desc);
>  }

Should this perhaps be a stable fix?

-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@xxxxxxxxxxxxxxx






[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