All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mike Snitzer <snitzer@kernel.org>
To: linux-nfs@vger.kernel.org
Cc: Jeff Layton <jlayton@kernel.org>,
	Chuck Lever <chuck.lever@oracle.com>,
	Trond Myklebust <trondmy@hammerspace.com>,
	NeilBrown <neilb@suse.de>,
	snitzer@hammerspace.com
Subject: [PATCH v5 13/19] nfs/nfsd: ensure localio server always uses its network namespace
Date: Tue, 18 Jun 2024 16:19:43 -0400	[thread overview]
Message-ID: <20240618201949.81977-14-snitzer@kernel.org> (raw)
In-Reply-To: <20240618201949.81977-1-snitzer@kernel.org>

Pass the stored cl_nfssvc_net from the client to the server as first
argument to nfsd_open_local_fh() to ensure the proper network
namespace is used for localio.

Otherwise, before this commit, the nfs_client's network namespace was
used (as extracted from the client's cl_rpcclient). This is clearly
not going to allow proper functionality if the client and server
happen to have disjoint network namespaces.

Elected to not rename the nfsd_uuid_t structure despite it growing a
non-uuid member. Can revisit later.

Signed-off-by: Mike Snitzer <snitzer@kernel.org>
---
 fs/nfs/client.c            |  1 +
 fs/nfs/localio.c           | 12 ++++++++----
 fs/nfs_common/nfslocalio.c | 15 +++++++++------
 fs/nfsd/localio.c          |  9 +++++----
 fs/nfsd/nfssvc.c           |  1 +
 fs/nfsd/vfs.h              |  3 ++-
 include/linux/nfs_fs_sb.h  |  1 +
 include/linux/nfslocalio.h | 10 ++++++----
 8 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index cbabcdf3d785..40077ad08ccb 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -171,6 +171,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
 
 	INIT_LIST_HEAD(&clp->cl_superblocks);
 	clp->cl_rpcclient = clp->cl_rpcclient_localio = ERR_PTR(-EINVAL);
+	clp->cl_nfssvc_net = NULL;
 	clp->nfsd_open_local_fh = NULL;
 
 	clp->cl_flags = cl_init->init_flags;
diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c
index ddd17549812e..d41130f5a84d 100644
--- a/fs/nfs/localio.c
+++ b/fs/nfs/localio.c
@@ -132,10 +132,11 @@ EXPORT_SYMBOL_GPL(nfs_server_is_local);
 /*
  * nfs_local_enable - attempt to enable local i/o for an nfs_client
  */
-static void nfs_local_enable(struct nfs_client *clp)
+static void nfs_local_enable(struct nfs_client *clp, struct net *net)
 {
 	if (READ_ONCE(clp->nfsd_open_local_fh)) {
 		set_bit(NFS_CS_LOCAL_IO, &clp->cl_flags);
+		clp->cl_nfssvc_net = net;
 		trace_nfs_local_enable(clp);
 	}
 }
@@ -153,6 +154,7 @@ void nfs_local_disable(struct nfs_client *clp)
 			rpc_shutdown_client(clp->cl_rpcclient_localio);
 			clp->cl_rpcclient_localio = ERR_PTR(-EINVAL);
 		}
+		clp->cl_nfssvc_net = NULL;
 	}
 }
 
@@ -192,6 +194,7 @@ static bool nfs_local_server_getuuid(struct nfs_client *clp, uuid_t *nfsd_uuid)
 void nfs_local_probe(struct nfs_client *clp)
 {
 	uuid_t uuid;
+	struct net *net = NULL;
 
 	if (!localio_enabled)
 		goto unsupported;
@@ -211,7 +214,7 @@ void nfs_local_probe(struct nfs_client *clp)
 		 * by verifying client's nfsd, with specified uuid, is local.
 		 */
 		if (!nfs_local_server_getuuid(clp, &uuid) ||
-		    !nfsd_uuid_is_local(&uuid))
+		    !nfsd_uuid_is_local(&uuid, &net))
 			goto unsupported;
 		break;
 	default:
@@ -219,7 +222,7 @@ void nfs_local_probe(struct nfs_client *clp)
 	}
 
 	dprintk("%s: detected local server.\n", __func__);
-	nfs_local_enable(clp);
+	nfs_local_enable(clp, net);
 	return;
 
 unsupported:
@@ -243,7 +246,8 @@ nfs_local_open_fh(struct nfs_client *clp, const struct cred *cred,
 	if (mode & ~(FMODE_READ | FMODE_WRITE))
 		return ERR_PTR(-EINVAL);
 
-	status = clp->nfsd_open_local_fh(clp->cl_rpcclient, cred, fh, mode, &filp);
+	status = clp->nfsd_open_local_fh(clp->cl_nfssvc_net, clp->cl_rpcclient,
+					cred, fh, mode, &filp);
 	if (status < 0) {
 		dprintk("%s: open local file failed error=%d\n",
 				__func__, status);
diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
index c454c4100976..086e09b3ec38 100644
--- a/fs/nfs_common/nfslocalio.c
+++ b/fs/nfs_common/nfslocalio.c
@@ -12,29 +12,32 @@ MODULE_LICENSE("GPL");
 /*
  * Global list of nfsd_uuid_t instances, add/remove
  * is protected by fs/nfsd/nfssvc.c:nfsd_mutex.
- * Reads are protected RCU read lock (see below).
+ * Reads are protected by RCU read lock (see below).
  */
 LIST_HEAD(nfsd_uuids);
 EXPORT_SYMBOL(nfsd_uuids);
 
 /* Must be called with RCU read lock held. */
-static const uuid_t * nfsd_uuid_lookup(const uuid_t *uuid)
+static const uuid_t * nfsd_uuid_lookup(const uuid_t *uuid,
+				struct net **netp)
 {
 	nfsd_uuid_t *nfsd_uuid;
 
 	list_for_each_entry_rcu(nfsd_uuid, &nfsd_uuids, list)
-		if (uuid_equal(&nfsd_uuid->uuid, uuid))
+		if (uuid_equal(&nfsd_uuid->uuid, uuid)) {
+			*netp = nfsd_uuid->net;
 			return &nfsd_uuid->uuid;
+		}
 
 	return &uuid_null;
 }
 
-bool nfsd_uuid_is_local(const uuid_t *uuid)
+bool nfsd_uuid_is_local(const uuid_t *uuid, struct net **netp)
 {
 	const uuid_t *nfsd_uuid;
 
 	rcu_read_lock();
-	nfsd_uuid = nfsd_uuid_lookup(uuid);
+	nfsd_uuid = nfsd_uuid_lookup(uuid, netp);
 	rcu_read_unlock();
 
 	return !uuid_is_null(nfsd_uuid);
@@ -51,7 +54,7 @@ EXPORT_SYMBOL_GPL(nfsd_uuid_is_local);
  * This allows some sanity checking, like giving up on localio if nfsd isn't loaded.
  */
 
-extern int nfsd_open_local_fh(struct rpc_clnt *rpc_clnt,
+extern int nfsd_open_local_fh(struct net *, struct rpc_clnt *rpc_clnt,
 			const struct cred *cred, const struct nfs_fh *nfs_fh,
 			const fmode_t fmode, struct file **pfilp);
 
diff --git a/fs/nfsd/localio.c b/fs/nfsd/localio.c
index 7ecd72406dc0..34678bfed579 100644
--- a/fs/nfsd/localio.c
+++ b/fs/nfsd/localio.c
@@ -103,10 +103,10 @@ nfsd_local_fakerqst_destroy(struct svc_rqst *rqstp)
 }
 
 static struct svc_rqst *
-nfsd_local_fakerqst_create(struct rpc_clnt *rpc_clnt, const struct cred *cred)
+nfsd_local_fakerqst_create(struct net *net, struct rpc_clnt *rpc_clnt,
+			const struct cred *cred)
 {
 	struct svc_rqst *rqstp;
-	struct net *net = rpc_net_ns(rpc_clnt);
 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 	int status;
 
@@ -186,7 +186,8 @@ nfsd_local_fakerqst_create(struct rpc_clnt *rpc_clnt, const struct cred *cred)
  * dependency on knfsd. So, there is no forward declaration in a header file
  * for it.
  */
-int nfsd_open_local_fh(struct rpc_clnt *rpc_clnt,
+int nfsd_open_local_fh(struct net *net,
+			 struct rpc_clnt *rpc_clnt,
 			 const struct cred *cred,
 			 const struct nfs_fh *nfs_fh,
 			 const fmode_t fmode,
@@ -203,7 +204,7 @@ int nfsd_open_local_fh(struct rpc_clnt *rpc_clnt,
 	/* Save creds before calling into nfsd */
 	save_cred = get_current_cred();
 
-	rqstp = nfsd_local_fakerqst_create(rpc_clnt, cred);
+	rqstp = nfsd_local_fakerqst_create(net, rpc_clnt, cred);
 	if (IS_ERR(rqstp)) {
 		status = PTR_ERR(rqstp);
 		goto out_revertcred;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index a81be9b39399..48bfd3c6d619 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -473,6 +473,7 @@ static int nfsd_startup_net(struct net *net, const struct cred *cred)
 #endif
 #if IS_ENABLED(CONFIG_NFSD_LOCALIO)
 	INIT_LIST_HEAD(&nn->nfsd_uuid.list);
+	nn->nfsd_uuid.net = net;
 	list_add_tail_rcu(&nn->nfsd_uuid.list, &nfsd_uuids);
 #endif
 	nn->nfsd_net_up = true;
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 91c50649a8c7..af07bb146e81 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -160,7 +160,8 @@ __be32		nfsd_permission(struct svc_rqst *, struct svc_export *,
 
 void		nfsd_filp_close(struct file *fp);
 
-int		nfsd_open_local_fh(struct rpc_clnt *rpc_clnt,
+int		nfsd_open_local_fh(struct net *net,
+				   struct rpc_clnt *rpc_clnt,
 				   const struct cred *cred,
 				   const struct nfs_fh *nfs_fh,
 				   const fmode_t fmode,
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index f5760b05ec87..f47ea512eb0a 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -132,6 +132,7 @@ struct nfs_client {
 	struct timespec64	cl_nfssvc_boot;
 	seqlock_t		cl_boot_lock;
 	struct rpc_clnt *	cl_rpcclient_localio;	/* localio RPC client handle */
+	struct net *	        cl_nfssvc_net;
 	nfs_to_nfsd_open_t	nfsd_open_local_fh;
 };
 
diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h
index b8df1b9f248d..c9592ad0afe2 100644
--- a/include/linux/nfslocalio.h
+++ b/include/linux/nfslocalio.h
@@ -8,6 +8,7 @@
 #include <linux/list.h>
 #include <linux/uuid.h>
 #include <linux/nfs.h>
+#include <net/net_namespace.h>
 
 /*
  * Global list of nfsd_uuid_t instances, add/remove
@@ -23,13 +24,14 @@ extern struct list_head nfsd_uuids;
 typedef struct {
 	uuid_t uuid;
 	struct list_head list;
+	struct net *net; /* nfsd's network namespace */
 } nfsd_uuid_t;
 
-bool nfsd_uuid_is_local(const uuid_t *uuid);
+bool nfsd_uuid_is_local(const uuid_t *uuid, struct net **netp);
 
-typedef int (*nfs_to_nfsd_open_t)(struct rpc_clnt *, const struct cred *,
-				  const struct nfs_fh *, const fmode_t,
-				  struct file **);
+typedef int (*nfs_to_nfsd_open_t)(struct net *, struct rpc_clnt *,
+				const struct cred *, const struct nfs_fh *,
+				const fmode_t, struct file **);
 
 nfs_to_nfsd_open_t get_nfsd_open_local_fh(void);
 void put_nfsd_open_local_fh(void);
-- 
2.44.0


  parent reply	other threads:[~2024-06-18 20:20 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-18 20:19 [PATCH v5 00/19] nfs/nfsd: add support for localio Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 01/19] nfs: pass nfs_client to nfs_initiate_pgio Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 02/19] nfs: pass descriptor thru nfs_initiate_pgio path Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 03/19] nfs: pass struct file to nfs_init_pgio and nfs_init_commit Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 04/19] sunrpc: add rpcauth_map_to_svc_cred_local Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 05/19] nfs_common: add NFS LOCALIO protocol extension enablement Mike Snitzer
2024-06-19  5:04   ` NeilBrown
2024-06-18 20:19 ` [PATCH v5 06/19] nfs/nfsd: add "localio" support Mike Snitzer
2024-06-18 21:28   ` Jeff Layton
2024-06-18 20:19 ` [PATCH v5 07/19] NFS: Enable localio for non-pNFS I/O Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 08/19] pnfs/flexfiles: Enable localio for flexfiles I/O Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 09/19] nfs: implement v3 and v4 client support for NFS_LOCALIO_PROGRAM Mike Snitzer
2024-06-19  5:30   ` NeilBrown
2024-06-19 13:18     ` Chuck Lever III
2024-06-18 20:19 ` [PATCH v5 10/19] nfsd: implement v3 and v4 server " Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 11/19] nfs/nfsd: consolidate {encode,decode}_opaque_fixed in nfs_xdr.h Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 12/19] nfs/localio: move managing nfsd_open_local_fh symbol to nfs_common Mike Snitzer
2024-06-18 21:32   ` Jeff Layton
2024-06-18 20:19 ` Mike Snitzer [this message]
2024-06-18 21:36   ` [PATCH v5 13/19] nfs/nfsd: ensure localio server always uses its network namespace Jeff Layton
2024-06-18 20:19 ` [PATCH v5 14/19] nfsd/localio: manage netns reference in nfsd_open_local_fh Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 15/19] nfsd: prepare to use SRCU to dereference nn->nfsd_serv Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 16/19] nfsd: " Mike Snitzer
2024-06-19 12:39   ` Jeff Layton
2024-06-19 17:26     ` Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 17/19] nfsd/localio: use SRCU to dereference nn->nfsd_serv in nfsd_open_local_fh Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 18/19] nfs/localio: use dedicated workqueues for filesystem read and write Mike Snitzer
2024-06-18 20:19 ` [PATCH v5 19/19] nfs: add Documentation/filesystems/nfs/localio.rst Mike Snitzer
2024-06-18 21:46   ` Chuck Lever
2024-06-19  5:47     ` NeilBrown
2024-06-19 18:27       ` Mike Snitzer
2024-06-19  5:49 ` [PATCH v5 00/19] nfs/nfsd: add support for localio Christoph Hellwig
2024-06-19  7:10   ` NeilBrown
2024-06-19  7:15     ` Christoph Hellwig
2024-06-19 10:09     ` Jeff Layton
2024-06-19 21:09       ` NeilBrown
2024-06-19 22:28         ` Jeff Layton
2024-06-19 22:46         ` Mike Snitzer
2024-06-20  5:16         ` Christoph Hellwig
2024-06-19 17:57     ` Mike Snitzer
2024-06-19 18:04       ` Chuck Lever III
2024-06-19 18:13         ` Mike Snitzer
2024-06-19 18:22           ` Chuck Lever III
2024-06-20  5:18       ` Christoph Hellwig
2024-06-19 14:02   ` Trond Myklebust

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240618201949.81977-14-snitzer@kernel.org \
    --to=snitzer@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=jlayton@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neilb@suse.de \
    --cc=snitzer@hammerspace.com \
    --cc=trondmy@hammerspace.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.