Linux NFS development
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox