* [PATCH] NFS: always probe for LOCALIO support asynchronously
@ 2025-05-13 16:08 Mike Snitzer
2025-05-13 17:31 ` Jeff Layton
0 siblings, 1 reply; 2+ messages in thread
From: Mike Snitzer @ 2025-05-13 16:08 UTC (permalink / raw)
To: Trond Myklebust, anna; +Cc: jlayton, linux-nfs
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.
Suggested-by: Jeff Layton <jlayton@kernel.org> # to always probe async
Fixes: 76d4cb6345da ("nfs: probe for LOCALIO when v4 client reconnects to server")
Cc: stable@vger.kernel.org # 6.14+
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
---
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)
--
2.44.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] NFS: always probe for LOCALIO support asynchronously
2025-05-13 16:08 [PATCH] NFS: always probe for LOCALIO support asynchronously Mike Snitzer
@ 2025-05-13 17:31 ` Jeff Layton
0 siblings, 0 replies; 2+ messages in thread
From: Jeff Layton @ 2025-05-13 17:31 UTC (permalink / raw)
To: Mike Snitzer, Trond Myklebust, anna; +Cc: linux-nfs
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@kernel.org> # to always probe async
> Fixes: 76d4cb6345da ("nfs: probe for LOCALIO when v4 client reconnects to server")
> Cc: stable@vger.kernel.org # 6.14+
> Signed-off-by: Mike Snitzer <snitzer@kernel.org>
> ---
> 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@kernel.org>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-05-13 17:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-13 16:08 [PATCH] NFS: always probe for LOCALIO support asynchronously Mike Snitzer
2025-05-13 17:31 ` Jeff Layton
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.