public inbox for linux-nfs@vger.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>,
	Anna Schumaker <anna@kernel.org>,
	Trond Myklebust <trondmy@hammerspace.com>,
	NeilBrown <neilb@suse.de>,
	snitzer@hammerspace.com
Subject: [PATCH v11 03/20] nfs_common: add NFS LOCALIO auxiliary protocol enablement
Date: Tue,  2 Jul 2024 12:28:14 -0400	[thread overview]
Message-ID: <20240702162831.91604-4-snitzer@kernel.org> (raw)
In-Reply-To: <20240702162831.91604-1-snitzer@kernel.org>

Localio is used by nfsd to add access to a global nfsd_uuids list in
nfs_common that is used to register and then identify local nfsd
instances.

nfsd_uuids is protected by nfsd_mutex or RCU read lock.  List is
composed of nfsd_uuid_t instances that are managed as nfsd creates
them (per network namespace).

nfsd_uuid_is_local() will be used to search all local nfsd for the
client specified nfsd uuid.

This commit also adds all the nfs_client members required to implement
the entire localio feature (which depends on the LOCALIO protocol).

Signed-off-by: Mike Snitzer <snitzer@kernel.org>
---
 fs/nfs/client.c            |  8 +++++
 fs/nfs_common/Makefile     |  3 ++
 fs/nfs_common/nfslocalio.c | 74 ++++++++++++++++++++++++++++++++++++++
 fs/nfsd/netns.h            |  4 +++
 fs/nfsd/nfssvc.c           | 12 ++++++-
 include/linux/nfs_fs_sb.h  |  9 +++++
 include/linux/nfslocalio.h | 40 +++++++++++++++++++++
 7 files changed, 149 insertions(+), 1 deletion(-)
 create mode 100644 fs/nfs_common/nfslocalio.c
 create mode 100644 include/linux/nfslocalio.h

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index de77848ae654..bcdf8d42cbc7 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -178,6 +178,14 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
 	clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1;
 	clp->cl_net = get_net(cl_init->net);
 
+#if IS_ENABLED(CONFIG_NFS_LOCALIO)
+	seqlock_init(&clp->cl_boot_lock);
+	ktime_get_real_ts64(&clp->cl_nfssvc_boot);
+	clp->cl_rpcclient_localio = ERR_PTR(-EINVAL);
+	clp->nfsd_open_local_fh = NULL;
+	clp->cl_nfssvc_net = NULL;
+#endif /* CONFIG_NFS_LOCALIO */
+
 	clp->cl_principal = "*";
 	clp->cl_xprtsec = cl_init->xprtsec;
 	return clp;
diff --git a/fs/nfs_common/Makefile b/fs/nfs_common/Makefile
index 119c75ab9fd0..d81623b76aba 100644
--- a/fs/nfs_common/Makefile
+++ b/fs/nfs_common/Makefile
@@ -6,5 +6,8 @@
 obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o
 nfs_acl-objs := nfsacl.o
 
+obj-$(CONFIG_NFS_COMMON_LOCALIO_SUPPORT) += nfs_localio.o
+nfs_localio-objs := nfslocalio.o
+
 obj-$(CONFIG_GRACE_PERIOD) += grace.o
 obj-$(CONFIG_NFS_V4_2_SSC_HELPER) += nfs_ssc.o
diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c
new file mode 100644
index 000000000000..a234aa92950f
--- /dev/null
+++ b/fs/nfs_common/nfslocalio.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Mike Snitzer <snitzer@hammerspace.com>
+ */
+
+#include <linux/module.h>
+#include <linux/rculist.h>
+#include <linux/nfslocalio.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("NFS localio protocol bypass support");
+
+/*
+ * Global list of nfsd_uuid_t instances, add/remove
+ * is protected by fs/nfsd/nfssvc.c:nfsd_mutex.
+ * 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,
+				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)) {
+			*netp = nfsd_uuid->net;
+			return &nfsd_uuid->uuid;
+		}
+
+	return &uuid_null;
+}
+
+bool nfsd_uuid_is_local(const uuid_t *uuid, struct net **netp)
+{
+	bool is_local;
+	const uuid_t *nfsd_uuid;
+
+	rcu_read_lock();
+	nfsd_uuid = nfsd_uuid_lookup(uuid, netp);
+	is_local = !uuid_is_null(nfsd_uuid);
+	rcu_read_unlock();
+
+	return is_local;
+}
+EXPORT_SYMBOL_GPL(nfsd_uuid_is_local);
+
+/*
+ * The nfs localio code needs to call into nfsd to do the filehandle -> struct path
+ * mapping, but cannot be statically linked, because that will make the nfs module
+ * depend on the nfsd module.
+ *
+ * Instead, do dynamic linking to the nfsd module (via nfs_common module). The
+ * nfs_common module will only hold a reference on nfsd when localio is in use.
+ * This allows some sanity checking, like giving up on localio if nfsd isn't loaded.
+ */
+
+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);
+
+nfs_to_nfsd_open_t get_nfsd_open_local_fh(void)
+{
+	return symbol_request(nfsd_open_local_fh);
+}
+EXPORT_SYMBOL_GPL(get_nfsd_open_local_fh);
+
+void put_nfsd_open_local_fh(void)
+{
+	symbol_put(nfsd_open_local_fh);
+}
+EXPORT_SYMBOL_GPL(put_nfsd_open_local_fh);
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index 14ec15656320..0c5a1d97e4ac 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -15,6 +15,7 @@
 #include <linux/percpu_counter.h>
 #include <linux/siphash.h>
 #include <linux/sunrpc/stats.h>
+#include <linux/nfslocalio.h>
 
 /* Hash tables for nfs4_clientid state */
 #define CLIENT_HASH_BITS                 4
@@ -213,6 +214,9 @@ struct nfsd_net {
 	/* last time an admin-revoke happened for NFSv4.0 */
 	time64_t		nfs40_last_revoke;
 
+#if IS_ENABLED(CONFIG_NFSD_LOCALIO)
+	nfsd_uuid_t		nfsd_uuid;
+#endif
 };
 
 /* Simple check to find out if a given net was properly initialized */
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 0bc8eaa5e009..402d436cbd24 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -19,6 +19,7 @@
 #include <linux/sunrpc/svc_xprt.h>
 #include <linux/lockd/bind.h>
 #include <linux/nfsacl.h>
+#include <linux/nfslocalio.h>
 #include <linux/seq_file.h>
 #include <linux/inetdevice.h>
 #include <net/addrconf.h>
@@ -427,6 +428,10 @@ static int nfsd_startup_net(struct net *net, const struct cred *cred)
 
 #ifdef CONFIG_NFSD_V4_2_INTER_SSC
 	nfsd4_ssc_init_umount_work(nn);
+#endif
+#if IS_ENABLED(CONFIG_NFSD_LOCALIO)
+	INIT_LIST_HEAD(&nn->nfsd_uuid.list);
+	list_add_tail_rcu(&nn->nfsd_uuid.list, &nfsd_uuids);
 #endif
 	nn->nfsd_net_up = true;
 	return 0;
@@ -456,6 +461,9 @@ static void nfsd_shutdown_net(struct net *net)
 		lockd_down(net);
 		nn->lockd_up = false;
 	}
+#if IS_ENABLED(CONFIG_NFSD_LOCALIO)
+	list_del_rcu(&nn->nfsd_uuid.list);
+#endif
 	nn->nfsd_net_up = false;
 	nfsd_shutdown_generic();
 }
@@ -808,7 +816,9 @@ nfsd_svc(int n, int *nthreads, struct net *net, const struct cred *cred, const c
 
 	strscpy(nn->nfsd_name, scope ? scope : utsname()->nodename,
 		sizeof(nn->nfsd_name));
-
+#if IS_ENABLED(CONFIG_NFSD_LOCALIO)
+	uuid_gen(&nn->nfsd_uuid.uuid);
+#endif
 	error = nfsd_create_serv(net);
 	if (error)
 		goto out;
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 92de074e63b9..e58e706a6503 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -8,6 +8,7 @@
 #include <linux/wait.h>
 #include <linux/nfs_xdr.h>
 #include <linux/sunrpc/xprt.h>
+#include <linux/nfslocalio.h>
 
 #include <linux/atomic.h>
 #include <linux/refcount.h>
@@ -125,6 +126,14 @@ struct nfs_client {
 	struct net		*cl_net;
 	struct list_head	pending_cb_stateids;
 	struct rcu_head		rcu;
+
+#if IS_ENABLED(CONFIG_NFS_LOCALIO)
+	struct timespec64	cl_nfssvc_boot;
+	seqlock_t		cl_boot_lock;
+	struct rpc_clnt *	cl_rpcclient_localio;
+	struct net *	        cl_nfssvc_net;
+	nfs_to_nfsd_open_t	nfsd_open_local_fh;
+#endif /* CONFIG_NFS_LOCALIO */
 };
 
 /*
diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h
new file mode 100644
index 000000000000..22443d2089eb
--- /dev/null
+++ b/include/linux/nfslocalio.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2024 Mike Snitzer <snitzer@hammerspace.com>
+ */
+#ifndef __LINUX_NFSLOCALIO_H
+#define __LINUX_NFSLOCALIO_H
+
+#include <linux/list.h>
+#include <linux/uuid.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/nfs.h>
+#include <net/net_namespace.h>
+
+/*
+ * Global list of nfsd_uuid_t instances, add/remove
+ * is protected by fs/nfsd/nfssvc.c:nfsd_mutex.
+ */
+extern struct list_head nfsd_uuids;
+
+/*
+ * Each nfsd instance has an nfsd_uuid_t that is accessible through the
+ * global nfsd_uuids list. Useful to allow a client to negotiate if localio
+ * possible with its server.
+ */
+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, struct net **netp);
+
+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);
+
+#endif  /* __LINUX_NFSLOCALIO_H */
-- 
2.44.0


  parent reply	other threads:[~2024-07-02 16:28 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-02 16:28 [PATCH v11 00/20] nfs/nfsd: add support for localio Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 01/20] SUNRPC: add rpcauth_map_to_svc_cred_local Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 02/20] nfs: factor out {encode,decode}_opaque_fixed to nfs_xdr.h Mike Snitzer
2024-07-02 16:28 ` Mike Snitzer [this message]
2024-07-02 16:28 ` [PATCH v11 04/20] nfsd: add "localio" support Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 05/20] nfsd: add Kconfig options to allow localio to be enabled Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 06/20] nfsd: manage netns reference in nfsd_open_local_fh Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 07/20] nfsd: use percpu_ref to interlock nfsd_destroy_serv and nfsd_open_local_fh Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 08/20] nfsd: implement server support for NFS_LOCALIO_PROGRAM Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 09/20] SUNRPC: replace program list with program array Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 10/20] nfs: pass nfs_client to nfs_initiate_pgio Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 11/20] nfs: pass descriptor thru nfs_initiate_pgio path Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 12/20] nfs: pass struct file to nfs_init_pgio and nfs_init_commit Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 13/20] nfs: add "localio" support Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 14/20] nfs: fix nfs_localio_vfs_getattr() to properly support v4 Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 15/20] nfs: enable localio for non-pNFS I/O Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 16/20] pnfs/flexfiles: enable localio for flexfiles I/O Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 17/20] SUNRPC: remove call_allocate() BUG_ON if p_arglen=0 to allow RPC with void arg Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 18/20] nfs/localio: use dedicated workqueues for filesystem read and write Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 19/20] nfs: implement client support for NFS_LOCALIO_PROGRAM Mike Snitzer
2024-07-02 16:28 ` [PATCH v11 20/20] nfs: add Documentation/filesystems/nfs/localio.rst Mike Snitzer
2024-07-02 18:06 ` [PATCH v11 00/20] nfs/nfsd: add support for localio Chuck Lever III
2024-07-02 18:32   ` Mike Snitzer
2024-07-02 20:10     ` Chuck Lever III
2024-07-03  0:57       ` Mike Snitzer
2024-07-03  0:52     ` NeilBrown
2024-07-03  1:13       ` Mike Snitzer
2024-07-03  5:04   ` Christoph Hellwig
2024-07-03  8:52     ` Mike Snitzer
2024-07-03 14:16       ` Christoph Hellwig
2024-07-03 15:11         ` Mike Snitzer
2024-07-03 15:18           ` Christoph Hellwig
2024-07-03 15:24             ` Chuck Lever III
2024-07-03 15:29               ` Christoph Hellwig
2024-07-03 15:36               ` Mike Snitzer
2024-07-03 17:06                 ` Jeff Layton
2024-07-04  6:00                   ` Christoph Hellwig
2024-07-04 18:31                     ` Mike Snitzer
2024-07-05  5:18                       ` Christoph Hellwig
2024-07-05 13:35                         ` Chuck Lever III
2024-07-05 13:39                           ` Christoph Hellwig
2024-07-05 14:15                           ` Mike Snitzer
2024-07-05 14:18                             ` Christoph Hellwig
2024-07-05 14:36                               ` Mike Snitzer
2024-07-05 14:59                                 ` Chuck Lever III
2024-07-06  3:58                                   ` Mike Snitzer
2024-07-06  5:52                                     ` NeilBrown
2024-07-06 13:05                                       ` "why NFSv3?" [was: Re: [PATCH v11 00/20] nfs/nfsd: add support for localio] Mike Snitzer
2024-07-06  5:58                                     ` [PATCH v11 00/20] nfs/nfsd: add support for localio Christoph Hellwig
2024-07-06 13:12                                       ` Mike Snitzer
2024-07-08  9:46                                         ` Christoph Hellwig
2024-07-08 12:55                                           ` Mike Snitzer
2024-07-06 16:58                                     ` Chuck Lever III
2024-07-07  0:42                                       ` Mike Snitzer
2024-07-05 18:59                                 ` Jeff Layton
2024-07-05 22:08                         ` NeilBrown
2024-07-06  6:02                           ` Christoph Hellwig
2024-07-06  6:37                             ` NeilBrown
2024-07-06  6:42                               ` Christoph Hellwig
2024-07-06 17:15                                 ` Chuck Lever III
2024-07-08  4:10                                   ` NeilBrown
2024-07-08 14:41                                     ` Chuck Lever III
2024-07-08  9:40                                   ` Christoph Hellwig
2024-07-08  4:03                                 ` NeilBrown
2024-07-08  9:37                                   ` Christoph Hellwig
2024-07-10  0:10                                     ` NeilBrown
2024-07-03 17:19                 ` Chuck Lever III
2024-07-03 19:04                   ` Mike Snitzer
2024-07-04  5:55                     ` Christoph Hellwig
2024-07-03 21:35                   ` NeilBrown
2024-07-04  6:01                 ` Christoph Hellwig
2024-07-04 10:13                   ` Jeff Layton
2024-07-03 15:26       ` Chuck Lever III
2024-07-03 15:37         ` Mike Snitzer
2024-07-03 15:16 ` Christoph Hellwig
2024-07-03 15:28   ` Mike Snitzer
2024-07-04  5:49     ` Christoph Hellwig

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=20240702162831.91604-4-snitzer@kernel.org \
    --to=snitzer@kernel.org \
    --cc=anna@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox