All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chuck Lever <cel@kernel.org>
To: NeilBrown <neil@brown.name>, Jeff Layton <jlayton@kernel.org>,
	Olga Kornievskaia <okorniev@redhat.com>,
	Dai Ngo <dai.ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: <linux-nfs@vger.kernel.org>
Subject: [PATCH 2/4] NFSD: Hoist nfs42_ssc_open() into fs/nfs_common/nfs_ssc.c
Date: Tue, 21 Jul 2026 12:23:04 -0400	[thread overview]
Message-ID: <20260721162306.894558-3-cel@kernel.org> (raw)
In-Reply-To: <20260721162306.894558-1-cel@kernel.org>

Refactor: The infrastructure and details for calling the client's
ssc_open method can be hidden in nfs_ssc.c. This reduces the SSC
footprint in fs/nfsd/nfs4proc.c, a step toward removing that
file's dependency on <linux/nfs_fs.h>, which indirectly includes
<uapi/linux/nfs.h>.

The open and close functions are named "nfsd42_" since they are
meant to be invoked only by NFSD.

Cc: Olga Kornievskaia <okorniev@redhat.com>
Cc: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Chuck Lever <cel@kernel.org>
---
 fs/nfs_common/nfs_ssc.c | 56 +++++++++++++++++++++++++++++++++++++++--
 fs/nfsd/nfs4proc.c      | 17 +++----------
 include/linux/nfs_ssc.h | 23 +++++++----------
 3 files changed, 66 insertions(+), 30 deletions(-)

diff --git a/fs/nfs_common/nfs_ssc.c b/fs/nfs_common/nfs_ssc.c
index 8d8b7344ab4f..a8e79ec68701 100644
--- a/fs/nfs_common/nfs_ssc.c
+++ b/fs/nfs_common/nfs_ssc.c
@@ -12,9 +12,61 @@
 #include <linux/nfs_ssc.h>
 #include "../nfs/nfs4_fs.h"
 
+struct nfs_ssc_client_ops_tbl {
+	const struct nfs4_ssc_client_ops *ssc_nfs4_ops;
+};
 
-struct nfs_ssc_client_ops_tbl nfs_ssc_client_tbl;
-EXPORT_SYMBOL_GPL(nfs_ssc_client_tbl);
+static struct nfs_ssc_client_ops_tbl nfs_ssc_client_tbl __read_mostly;
+
+/**
+ * nfsd42_ssc_open - Open a file to be used for server-to-server copy
+ * @ss_mnt: active mount point on which the source file resides
+ * @src_fh: file handle of the source file to be copied
+ * @stateid: stateid to use for COPY operation
+ *
+ * Caller must close the returned file using nfsd42_ssc_close().
+ *
+ * Return: an open file, or an ERR_PTR on error
+ */
+struct file *nfsd42_ssc_open(struct vfsmount *ss_mnt, struct nfs_fh *src_fh,
+			     nfs4_stateid *stateid)
+{
+	/*
+	 * Built under CONFIG_NFS_V4_2_SSC_HELPER, which the NFS client
+	 * enables on its own. The dispatch below is live only when the
+	 * server also sets CONFIG_NFSD_V4_2_INTER_SSC; without it the
+	 * source file cannot be opened, so callers get -EIO.
+	 */
+#if IS_ENABLED(CONFIG_NFSD_V4_2_INTER_SSC)
+	const struct nfs4_ssc_client_ops *ops = nfs_ssc_client_tbl.ssc_nfs4_ops;
+
+	if (ops)
+		return ops->sco_open(ss_mnt, src_fh, stateid);
+#endif
+
+	return ERR_PTR(-EIO);
+}
+EXPORT_SYMBOL_GPL(nfsd42_ssc_open);
+
+/**
+ * nfsd42_ssc_close - Close a file opened with nfsd42_ssc_open()
+ * @filp: struct file to be closed
+ *
+ * The real cleanup happens unconditionally in nfsd4_cleanup_inter_ssc().
+ * The vfsmount is pinned until this function is called, preventing
+ * the client from unregistering its SSC ops.
+ */
+void nfsd42_ssc_close(struct file *filp)
+{
+	/* Live only under CONFIG_NFSD_V4_2_INTER_SSC; see nfsd42_ssc_open(). */
+#if IS_ENABLED(CONFIG_NFSD_V4_2_INTER_SSC)
+	const struct nfs4_ssc_client_ops *ops = nfs_ssc_client_tbl.ssc_nfs4_ops;
+
+	if (ops)
+		ops->sco_close(filp);
+#endif
+}
+EXPORT_SYMBOL_GPL(nfsd42_ssc_close);
 
 #ifdef CONFIG_NFS_V4_2
 /**
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 83715ba38b6a..dbea2da7b1ea 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1692,11 +1692,6 @@ void nfsd4_cancel_copy_by_sb(struct net *net, struct super_block *sb)
 
 #ifdef CONFIG_NFSD_V4_2_INTER_SSC
 
-extern struct file *nfs42_ssc_open(struct vfsmount *ss_mnt,
-				   struct nfs_fh *src_fh,
-				   nfs4_stateid *stateid);
-extern void nfs42_ssc_close(struct file *filep);
-
 #define NFSD42_INTERSSC_MOUNTOPS "vers=4.2,addr=%s,sec=sys"
 
 /*
@@ -1919,7 +1914,7 @@ nfsd4_cleanup_inter_ssc(struct nfsd4_ssc_umount_item *nsui, struct file *filp,
 	struct nfsd_net *nn = net_generic(dst->nf_net, nfsd_net_id);
 	long timeout = msecs_to_jiffies(nfsd4_ssc_umount_timeout);
 
-	nfs42_ssc_close(filp);
+	nfsd42_ssc_close(filp);
 	fput(filp);
 
 	spin_lock(&nn->nfsd_ssc_lock);
@@ -1951,12 +1946,6 @@ nfsd4_cleanup_inter_ssc(struct nfsd4_ssc_umount_item *nsui, struct file *filp,
 {
 }
 
-static struct file *nfs42_ssc_open(struct vfsmount *ss_mnt,
-				   struct nfs_fh *src_fh,
-				   nfs4_stateid *stateid)
-{
-	return NULL;
-}
 #endif /* CONFIG_NFSD_V4_2_INTER_SSC */
 
 static __be32
@@ -2179,8 +2168,8 @@ static int nfsd4_do_async_copy(void *data)
 	if (nfsd4_ssc_is_inter(copy)) {
 		struct file *filp;
 
-		filp = nfs42_ssc_open(copy->ss_nsui->nsui_vfsmount,
-				      &copy->c_fh, &copy->stateid);
+		filp = nfsd42_ssc_open(copy->ss_nsui->nsui_vfsmount,
+				       &copy->c_fh, &copy->stateid);
 		if (IS_ERR(filp)) {
 			switch (PTR_ERR(filp)) {
 			case -EBADF:
diff --git a/include/linux/nfs_ssc.h b/include/linux/nfs_ssc.h
index ba236dba8975..fc0d5d48dec2 100644
--- a/include/linux/nfs_ssc.h
+++ b/include/linux/nfs_ssc.h
@@ -10,8 +10,6 @@
 #include <linux/nfs_fs.h>
 #include <linux/sunrpc/svc.h>
 
-extern struct nfs_ssc_client_ops_tbl nfs_ssc_client_tbl;
-
 /*
  * NFS_V4
  */
@@ -21,29 +19,26 @@ struct nfs4_ssc_client_ops {
 	void (*sco_close)(struct file *filep);
 };
 
-struct nfs_ssc_client_ops_tbl {
-	const struct nfs4_ssc_client_ops *ssc_nfs4_ops;
-};
-
 extern void nfs42_ssc_register_ops(void);
 extern void nfs42_ssc_unregister_ops(void);
 
 extern void nfs42_ssc_register(const struct nfs4_ssc_client_ops *ops);
 extern void nfs42_ssc_unregister(const struct nfs4_ssc_client_ops *ops);
 
-#ifdef CONFIG_NFSD_V4_2_INTER_SSC
-static inline struct file *nfs42_ssc_open(struct vfsmount *ss_mnt,
-		struct nfs_fh *src_fh, nfs4_stateid *stateid)
+#if IS_ENABLED(CONFIG_NFS_V4_2_SSC_HELPER)
+struct file *nfsd42_ssc_open(struct vfsmount *ss_mnt, struct nfs_fh *src_fh,
+			     nfs4_stateid *stateid);
+void nfsd42_ssc_close(struct file *filp);
+#else
+static inline struct file *nfsd42_ssc_open(struct vfsmount *ss_mnt,
+					   struct nfs_fh *src_fh,
+					   nfs4_stateid *stateid)
 {
-	if (nfs_ssc_client_tbl.ssc_nfs4_ops)
-		return (*nfs_ssc_client_tbl.ssc_nfs4_ops->sco_open)(ss_mnt, src_fh, stateid);
 	return ERR_PTR(-EIO);
 }
 
-static inline void nfs42_ssc_close(struct file *filep)
+static inline void nfsd42_ssc_close(struct file *filp)
 {
-	if (nfs_ssc_client_tbl.ssc_nfs4_ops)
-		(*nfs_ssc_client_tbl.ssc_nfs4_ops->sco_close)(filep);
 }
 #endif
 
-- 
2.54.0


  parent reply	other threads:[~2026-07-21 16:23 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-21 16:23 [PATCH 0/4] Confine the inter-server copy interface to fs/nfs_common Chuck Lever
2026-07-21 16:23 ` [PATCH 1/4] nfs_common: Remove unused nfs_ssc_client_ops infrastructure Chuck Lever
2026-07-21 16:23 ` Chuck Lever [this message]
2026-07-21 16:23 ` [PATCH 3/4] nfs_common: Synchronize access to the SSC client ops table Chuck Lever
2026-07-21 16:23 ` [PATCH 4/4] NFSD: Split linux/nfs_ssc.h Chuck Lever

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=20260721162306.894558-3-cel@kernel.org \
    --to=cel@kernel.org \
    --cc=dai.ngo@oracle.com \
    --cc=jlayton@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=neil@brown.name \
    --cc=okorniev@redhat.com \
    --cc=tom@talpey.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.