97 lines
3.6 KiB
Diff
97 lines
3.6 KiB
Diff
From 7147868788966e9032cdeb0cf33bd1ae47785088 Mon Sep 17 00:00:00 2001
|
|
From: Mike Snitzer <snitzer@kernel.org>
|
|
Date: Tue, 13 May 2025 12:08:31 -0400
|
|
Subject: NFS: always probe for LOCALIO support asynchronously
|
|
|
|
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>
|
|
Reviewed-by: Jeff Layton <jlayton@kernel.org>
|
|
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
|
|
---
|
|
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(-)
|
|
|
|
--- a/fs/nfs/client.c
|
|
+++ b/fs/nfs/client.c
|
|
@@ -439,7 +439,7 @@ struct nfs_client *nfs_get_client(const
|
|
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;
|
|
}
|
|
|
|
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
|
|
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
|
|
@@ -400,7 +400,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_la
|
|
* 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);
|
|
--- a/fs/nfs/internal.h
|
|
+++ b/fs/nfs/internal.h
|
|
@@ -455,7 +455,6 @@ extern int nfs_wait_bit_killable(struct
|
|
|
|
#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 *,
|
|
--- a/fs/nfs/localio.c
|
|
+++ b/fs/nfs/localio.c
|
|
@@ -171,7 +171,7 @@ static bool nfs_server_uuid_is_local(str
|
|
* - 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 *
|
|
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)
|