Linux NFS development
 help / color / mirror / Atom feed
* [PATCH v1 0/2] rpcbind unregistration clean-ups
@ 2025-08-20 14:27 Chuck Lever
  2025-08-20 14:27 ` [PATCH v1 1/2] NFS: Remove rpcbind cleanup for NFSv4.0 callback Chuck Lever
  2025-08-20 14:27 ` [PATCH v1 2/2] SUNRPC: Move the svc_rpcb_cleanup() call sites Chuck Lever
  0 siblings, 2 replies; 4+ messages in thread
From: Chuck Lever @ 2025-08-20 14:27 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

From: Chuck Lever <chuck.lever@oracle.com>

Following on Olga's fix, here are two possible clean-ups I found
during code review.

Chuck Lever (2):
  NFS: Remove rpcbind cleanup for NFSv4.0 callback
  SUNRPC: Move the svc_rpcb_cleanup() call sites

 fs/lockd/svc.c                  |  6 ++----
 fs/nfs/callback.c               | 10 ++++------
 fs/nfsd/nfsctl.c                |  2 +-
 fs/nfsd/nfssvc.c                |  7 ++-----
 include/linux/sunrpc/svc_xprt.h |  3 ++-
 net/sunrpc/svc.c                |  1 -
 net/sunrpc/svc_xprt.c           |  7 ++++++-
 7 files changed, 17 insertions(+), 19 deletions(-)

-- 
2.50.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v1 1/2] NFS: Remove rpcbind cleanup for NFSv4.0 callback
  2025-08-20 14:27 [PATCH v1 0/2] rpcbind unregistration clean-ups Chuck Lever
@ 2025-08-20 14:27 ` Chuck Lever
  2025-08-20 14:27 ` [PATCH v1 2/2] SUNRPC: Move the svc_rpcb_cleanup() call sites Chuck Lever
  1 sibling, 0 replies; 4+ messages in thread
From: Chuck Lever @ 2025-08-20 14:27 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

From: Chuck Lever <chuck.lever@oracle.com>

The NFS client's NFSv4.0 callback listeners are created with
SVC_SOCK_ANONYMOUS, therefore svc_setup_socket() does not register
them with the client's rpcbind service.

And, note that nfs_callback_down_net() does not call
svc_rpcb_cleanup() at all when shutting down the callback server.

Even if svc_setup_socket() were to attempt to register or unregister
these sockets, the callback service has vs_hidden set, which shunts
the rpcbind upcalls.

The svc_rpcb_cleanup() error flow was introduced by
commit c946556b8749 ("NFS: move per-net callback thread
initialization to nfs_callback_up_net()"). It doesn't appear in the
code that was relocated by that commit.

Therefore, there is no need to call svc_rpcb_cleanup() when listener
creation fails during callback server start-up.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/nfs/callback.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 86bdc7d23fb9..511f80878809 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -153,7 +153,7 @@ static int nfs_callback_up_net(int minorversion, struct svc_serv *serv,
 	ret = svc_bind(serv, net);
 	if (ret < 0) {
 		printk(KERN_WARNING "NFS: bind callback service failed\n");
-		goto err_bind;
+		goto err;
 	}
 
 	ret = 0;
@@ -166,13 +166,11 @@ static int nfs_callback_up_net(int minorversion, struct svc_serv *serv,
 
 	if (ret < 0) {
 		printk(KERN_ERR "NFS: callback service start failed\n");
-		goto err_socks;
+		goto err;
 	}
 	return 0;
 
-err_socks:
-	svc_rpcb_cleanup(serv, net);
-err_bind:
+err:
 	nn->cb_users[minorversion]--;
 	dprintk("NFS: Couldn't create callback socket: err = %d; "
 			"net = %x\n", ret, net->ns.inum);
-- 
2.50.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v1 2/2] SUNRPC: Move the svc_rpcb_cleanup() call sites
  2025-08-20 14:27 [PATCH v1 0/2] rpcbind unregistration clean-ups Chuck Lever
  2025-08-20 14:27 ` [PATCH v1 1/2] NFS: Remove rpcbind cleanup for NFSv4.0 callback Chuck Lever
@ 2025-08-20 14:27 ` Chuck Lever
  2025-08-20 15:53   ` Olga Kornievskaia
  1 sibling, 1 reply; 4+ messages in thread
From: Chuck Lever @ 2025-08-20 14:27 UTC (permalink / raw)
  To: linux-nfs; +Cc: Chuck Lever

From: Chuck Lever <chuck.lever@oracle.com>

Clean up: because svc_rpcb_cleanup() and svc_xprt_destroy_all()
are always invoked in pairs, we can deduplicate code by moving
the svc_rpcb_cleanup() call sites into svc_xprt_destroy_all().

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 fs/lockd/svc.c                  | 6 ++----
 fs/nfs/callback.c               | 2 +-
 fs/nfsd/nfsctl.c                | 2 +-
 fs/nfsd/nfssvc.c                | 7 ++-----
 include/linux/sunrpc/svc_xprt.h | 3 ++-
 net/sunrpc/svc.c                | 1 -
 net/sunrpc/svc_xprt.c           | 7 ++++++-
 7 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index e80262a51884..d68afa196535 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -216,8 +216,7 @@ static int make_socks(struct svc_serv *serv, struct net *net,
 	if (warned++ == 0)
 		printk(KERN_WARNING
 			"lockd_up: makesock failed, error=%d\n", err);
-	svc_xprt_destroy_all(serv, net);
-	svc_rpcb_cleanup(serv, net);
+	svc_xprt_destroy_all(serv, net, true);
 	return err;
 }
 
@@ -255,8 +254,7 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net)
 			nlm_shutdown_hosts_net(net);
 			cancel_delayed_work_sync(&ln->grace_period_end);
 			locks_end_grace(&ln->lockd_manager);
-			svc_xprt_destroy_all(serv, net);
-			svc_rpcb_cleanup(serv, net);
+			svc_xprt_destroy_all(serv, net, true);
 		}
 	} else {
 		pr_err("%s: no users! net=%x\n",
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 511f80878809..c8b837006bb2 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -136,7 +136,7 @@ static void nfs_callback_down_net(u32 minorversion, struct svc_serv *serv, struc
 		return;
 
 	dprintk("NFS: destroy per-net callback data; net=%x\n", net->ns.inum);
-	svc_xprt_destroy_all(serv, net);
+	svc_xprt_destroy_all(serv, net, false);
 }
 
 static int nfs_callback_up_net(int minorversion, struct svc_serv *serv,
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index bc6b776fc657..63d52edcad72 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -1993,7 +1993,7 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
 	 * remaining listeners and recreate the list.
 	 */
 	if (delete)
-		svc_xprt_destroy_all(serv, net);
+		svc_xprt_destroy_all(serv, net, false);
 
 	/* walk list of addrs again, open any that still don't exist */
 	nlmsg_for_each_attr_type(attr, NFSD_A_SERVER_SOCK_ADDR, info->nlhdr,
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 82b0111ac469..7057ddd7a0a8 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -535,16 +535,13 @@ void nfsd_destroy_serv(struct net *net)
 #endif
 	}
 
-	svc_xprt_destroy_all(serv, net);
-
 	/*
 	 * write_ports can create the server without actually starting
-	 * any threads--if we get shut down before any threads are
+	 * any threads.  If we get shut down before any threads are
 	 * started, then nfsd_destroy_serv will be run before any of this
 	 * other initialization has been done except the rpcb information.
 	 */
-	svc_rpcb_cleanup(serv, net);
-
+	svc_xprt_destroy_all(serv, net, true);
 	nfsd_shutdown_net(net);
 	svc_destroy(&serv);
 }
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index 369a89aea186..fde60d4e2cd5 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -165,7 +165,8 @@ int	svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
 			struct net *net, const int family,
 			const unsigned short port, int flags,
 			const struct cred *cred);
-void	svc_xprt_destroy_all(struct svc_serv *serv, struct net *net);
+void	svc_xprt_destroy_all(struct svc_serv *serv, struct net *net,
+			     bool unregister);
 void	svc_xprt_received(struct svc_xprt *xprt);
 void	svc_xprt_enqueue(struct svc_xprt *xprt);
 void	svc_xprt_put(struct svc_xprt *xprt);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index b1fab3a69544..9c7245d811eb 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -436,7 +436,6 @@ void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net)
 	svc_unregister(serv, net);
 	rpcb_put_local(net);
 }
-EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
 
 static int svc_uses_rpcbind(struct svc_serv *serv)
 {
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 8b1837228799..049ab53088e9 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -1102,6 +1102,7 @@ static void svc_clean_up_xprts(struct svc_serv *serv, struct net *net)
  * svc_xprt_destroy_all - Destroy transports associated with @serv
  * @serv: RPC service to be shut down
  * @net: target network namespace
+ * @unregister: true if it is OK to unregister the destroyed xprts
  *
  * Server threads may still be running (especially in the case where the
  * service is still running in other network namespaces).
@@ -1114,7 +1115,8 @@ static void svc_clean_up_xprts(struct svc_serv *serv, struct net *net)
  * threads, we may need to wait a little while and then check again to
  * see if they're done.
  */
-void svc_xprt_destroy_all(struct svc_serv *serv, struct net *net)
+void svc_xprt_destroy_all(struct svc_serv *serv, struct net *net,
+			  bool unregister)
 {
 	int delay = 0;
 
@@ -1124,6 +1126,9 @@ void svc_xprt_destroy_all(struct svc_serv *serv, struct net *net)
 		svc_clean_up_xprts(serv, net);
 		msleep(delay++);
 	}
+
+	if (unregister)
+		svc_rpcb_cleanup(serv, net);
 }
 EXPORT_SYMBOL_GPL(svc_xprt_destroy_all);
 
-- 
2.50.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v1 2/2] SUNRPC: Move the svc_rpcb_cleanup() call sites
  2025-08-20 14:27 ` [PATCH v1 2/2] SUNRPC: Move the svc_rpcb_cleanup() call sites Chuck Lever
@ 2025-08-20 15:53   ` Olga Kornievskaia
  0 siblings, 0 replies; 4+ messages in thread
From: Olga Kornievskaia @ 2025-08-20 15:53 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs, Chuck Lever

On Wed, Aug 20, 2025 at 10:32 AM Chuck Lever <cel@kernel.org> wrote:
>
> From: Chuck Lever <chuck.lever@oracle.com>
>
> Clean up: because svc_rpcb_cleanup() and svc_xprt_destroy_all()
> are always invoked in pairs, we can deduplicate code by moving
> the svc_rpcb_cleanup() call sites into svc_xprt_destroy_all().

Tested-by: Olga Kornievskaia <okorniev@redhat.com>

> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
>  fs/lockd/svc.c                  | 6 ++----
>  fs/nfs/callback.c               | 2 +-
>  fs/nfsd/nfsctl.c                | 2 +-
>  fs/nfsd/nfssvc.c                | 7 ++-----
>  include/linux/sunrpc/svc_xprt.h | 3 ++-
>  net/sunrpc/svc.c                | 1 -
>  net/sunrpc/svc_xprt.c           | 7 ++++++-
>  7 files changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
> index e80262a51884..d68afa196535 100644
> --- a/fs/lockd/svc.c
> +++ b/fs/lockd/svc.c
> @@ -216,8 +216,7 @@ static int make_socks(struct svc_serv *serv, struct net *net,
>         if (warned++ == 0)
>                 printk(KERN_WARNING
>                         "lockd_up: makesock failed, error=%d\n", err);
> -       svc_xprt_destroy_all(serv, net);
> -       svc_rpcb_cleanup(serv, net);
> +       svc_xprt_destroy_all(serv, net, true);
>         return err;
>  }
>
> @@ -255,8 +254,7 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net)
>                         nlm_shutdown_hosts_net(net);
>                         cancel_delayed_work_sync(&ln->grace_period_end);
>                         locks_end_grace(&ln->lockd_manager);
> -                       svc_xprt_destroy_all(serv, net);
> -                       svc_rpcb_cleanup(serv, net);
> +                       svc_xprt_destroy_all(serv, net, true);
>                 }
>         } else {
>                 pr_err("%s: no users! net=%x\n",
> diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
> index 511f80878809..c8b837006bb2 100644
> --- a/fs/nfs/callback.c
> +++ b/fs/nfs/callback.c
> @@ -136,7 +136,7 @@ static void nfs_callback_down_net(u32 minorversion, struct svc_serv *serv, struc
>                 return;
>
>         dprintk("NFS: destroy per-net callback data; net=%x\n", net->ns.inum);
> -       svc_xprt_destroy_all(serv, net);
> +       svc_xprt_destroy_all(serv, net, false);
>  }
>
>  static int nfs_callback_up_net(int minorversion, struct svc_serv *serv,
> diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
> index bc6b776fc657..63d52edcad72 100644
> --- a/fs/nfsd/nfsctl.c
> +++ b/fs/nfsd/nfsctl.c
> @@ -1993,7 +1993,7 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
>          * remaining listeners and recreate the list.
>          */
>         if (delete)
> -               svc_xprt_destroy_all(serv, net);
> +               svc_xprt_destroy_all(serv, net, false);
>
>         /* walk list of addrs again, open any that still don't exist */
>         nlmsg_for_each_attr_type(attr, NFSD_A_SERVER_SOCK_ADDR, info->nlhdr,
> diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
> index 82b0111ac469..7057ddd7a0a8 100644
> --- a/fs/nfsd/nfssvc.c
> +++ b/fs/nfsd/nfssvc.c
> @@ -535,16 +535,13 @@ void nfsd_destroy_serv(struct net *net)
>  #endif
>         }
>
> -       svc_xprt_destroy_all(serv, net);
> -
>         /*
>          * write_ports can create the server without actually starting
> -        * any threads--if we get shut down before any threads are
> +        * any threads.  If we get shut down before any threads are
>          * started, then nfsd_destroy_serv will be run before any of this
>          * other initialization has been done except the rpcb information.
>          */
> -       svc_rpcb_cleanup(serv, net);
> -
> +       svc_xprt_destroy_all(serv, net, true);
>         nfsd_shutdown_net(net);
>         svc_destroy(&serv);
>  }
> diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
> index 369a89aea186..fde60d4e2cd5 100644
> --- a/include/linux/sunrpc/svc_xprt.h
> +++ b/include/linux/sunrpc/svc_xprt.h
> @@ -165,7 +165,8 @@ int svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
>                         struct net *net, const int family,
>                         const unsigned short port, int flags,
>                         const struct cred *cred);
> -void   svc_xprt_destroy_all(struct svc_serv *serv, struct net *net);
> +void   svc_xprt_destroy_all(struct svc_serv *serv, struct net *net,
> +                            bool unregister);
>  void   svc_xprt_received(struct svc_xprt *xprt);
>  void   svc_xprt_enqueue(struct svc_xprt *xprt);
>  void   svc_xprt_put(struct svc_xprt *xprt);
> diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
> index b1fab3a69544..9c7245d811eb 100644
> --- a/net/sunrpc/svc.c
> +++ b/net/sunrpc/svc.c
> @@ -436,7 +436,6 @@ void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net)
>         svc_unregister(serv, net);
>         rpcb_put_local(net);
>  }
> -EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
>
>  static int svc_uses_rpcbind(struct svc_serv *serv)
>  {
> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
> index 8b1837228799..049ab53088e9 100644
> --- a/net/sunrpc/svc_xprt.c
> +++ b/net/sunrpc/svc_xprt.c
> @@ -1102,6 +1102,7 @@ static void svc_clean_up_xprts(struct svc_serv *serv, struct net *net)
>   * svc_xprt_destroy_all - Destroy transports associated with @serv
>   * @serv: RPC service to be shut down
>   * @net: target network namespace
> + * @unregister: true if it is OK to unregister the destroyed xprts
>   *
>   * Server threads may still be running (especially in the case where the
>   * service is still running in other network namespaces).
> @@ -1114,7 +1115,8 @@ static void svc_clean_up_xprts(struct svc_serv *serv, struct net *net)
>   * threads, we may need to wait a little while and then check again to
>   * see if they're done.
>   */
> -void svc_xprt_destroy_all(struct svc_serv *serv, struct net *net)
> +void svc_xprt_destroy_all(struct svc_serv *serv, struct net *net,
> +                         bool unregister)
>  {
>         int delay = 0;
>
> @@ -1124,6 +1126,9 @@ void svc_xprt_destroy_all(struct svc_serv *serv, struct net *net)
>                 svc_clean_up_xprts(serv, net);
>                 msleep(delay++);
>         }
> +
> +       if (unregister)
> +               svc_rpcb_cleanup(serv, net);
>  }
>  EXPORT_SYMBOL_GPL(svc_xprt_destroy_all);
>
> --
> 2.50.0
>
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-08-20 15:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-20 14:27 [PATCH v1 0/2] rpcbind unregistration clean-ups Chuck Lever
2025-08-20 14:27 ` [PATCH v1 1/2] NFS: Remove rpcbind cleanup for NFSv4.0 callback Chuck Lever
2025-08-20 14:27 ` [PATCH v1 2/2] SUNRPC: Move the svc_rpcb_cleanup() call sites Chuck Lever
2025-08-20 15:53   ` Olga Kornievskaia

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox