Re: [PATCH] NFS: always probe for LOCALIO support asynchronously

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

 



On Tue, 2025-05-13 at 12:08 -0400, Mike Snitzer wrote:
> It was reported that NFS client mounts of AWS Elastic File System
> (EFS) volumes is slow, this is because the AWS firewall disallows
> LOCALIO (because it doesn't consider the use of NFS_LOCALIO_PROGRAM
> valid), see: https://bugzilla.redhat.com/show_bug.cgi?id=2335129
> 
> Switch to performing the LOCALIO probe asynchronously to address the
> potential for the NFS LOCALIO protocol being disallowed and/or slowed
> by the remote server's response.
> 
> While at it, fix nfs_local_probe_async() to always take/put a
> reference on the nfs_client that is using the LOCALIO protocol.
> Also, unexport the nfs_local_probe() symbol and make it private to
> fs/nfs/localio.c
> 
> This change has the side-effect of initially issuing reads, writes and
> commits over the wire via SUNRPC until the LOCALIO probe completes.
> 

Technically, this should only happen if you start doing I/O _right_
after creating the client. Usually there is a delay between mounting
and I/O so hopefully this shouldn't happen much if at all.

Either way, it's clearly a safe way to handle this, and it gets around
the synchronous blocking when the localio protocol server isn't
reachable.

> Suggested-by: Jeff Layton <jlayton@xxxxxxxxxx> # to always probe async
> Fixes: 76d4cb6345da ("nfs: probe for LOCALIO when v4 client reconnects to server")
> Cc: stable@xxxxxxxxxxxxxxx # 6.14+
> Signed-off-by: Mike Snitzer <snitzer@xxxxxxxxxx>
> ---
>  fs/nfs/client.c                           | 2 +-
>  fs/nfs/flexfilelayout/flexfilelayoutdev.c | 2 +-
>  fs/nfs/internal.h                         | 1 -
>  fs/nfs/localio.c                          | 6 ++++--
>  4 files changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index 6d63b958c4bb..d8fe7c0e7e05 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c
> @@ -439,7 +439,7 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init)
>  			spin_unlock(&nn->nfs_client_lock);
>  			new = rpc_ops->init_client(new, cl_init);
>  			if (!IS_ERR(new))
> -				 nfs_local_probe(new);
> +				 nfs_local_probe_async(new);
>  			return new;
>  		}
>  
> diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
> index 4a304cf17c4b..656d5c50bbce 100644
> --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
> +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
> @@ -400,7 +400,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
>  		 * keep ds_clp even if DS is local, so that if local IO cannot
>  		 * proceed somehow, we can fall back to NFS whenever we want.
>  		 */
> -		nfs_local_probe(ds->ds_clp);
> +		nfs_local_probe_async(ds->ds_clp);
>  		max_payload =
>  			nfs_block_size(rpc_max_payload(ds->ds_clp->cl_rpcclient),
>  				       NULL);
> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
> index 6655e5f32ec6..69c2c10ee658 100644
> --- a/fs/nfs/internal.h
> +++ b/fs/nfs/internal.h
> @@ -455,7 +455,6 @@ extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
>  
>  #if IS_ENABLED(CONFIG_NFS_LOCALIO)
>  /* localio.c */
> -extern void nfs_local_probe(struct nfs_client *);
>  extern void nfs_local_probe_async(struct nfs_client *);
>  extern void nfs_local_probe_async_work(struct work_struct *);
>  extern struct nfsd_file *nfs_local_open_fh(struct nfs_client *,
> diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c
> index 4ec952f9f47d..a4bacd9a5052 100644
> --- a/fs/nfs/localio.c
> +++ b/fs/nfs/localio.c
> @@ -171,7 +171,7 @@ static bool nfs_server_uuid_is_local(struct nfs_client *clp)
>   * - called after alloc_client and init_client (so cl_rpcclient exists)
>   * - this function is idempotent, it can be called for old or new clients
>   */
> -void nfs_local_probe(struct nfs_client *clp)
> +static void nfs_local_probe(struct nfs_client *clp)
>  {
>  	/* Disallow localio if disabled via sysfs or AUTH_SYS isn't used */
>  	if (!localio_enabled ||
> @@ -191,14 +191,16 @@ void nfs_local_probe(struct nfs_client *clp)
>  		nfs_localio_enable_client(clp);
>  	nfs_uuid_end(&clp->cl_uuid);
>  }
> -EXPORT_SYMBOL_GPL(nfs_local_probe);
>  
>  void nfs_local_probe_async_work(struct work_struct *work)
>  {
>  	struct nfs_client *clp =
>  		container_of(work, struct nfs_client, cl_local_probe_work);
>  
> +	if (!refcount_inc_not_zero(&clp->cl_count))
> +		return;
>  	nfs_local_probe(clp);
> +	nfs_put_client(clp);
>  }
>  
>  void nfs_local_probe_async(struct nfs_client *clp)

Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx>





[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