Re: [PATCH v2 1/1] nfsd: unregister with rpcbind when deleting a transport

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2025-08-19 at 14:04 -0400, Olga Kornievskaia wrote:
> When a listener is added, a part of creation of transport also registers
> program/port with rpcbind. However, when the listener is removed,
> while transport goes away, rpcbind still has the entry for that
> port/type.
> 
> When deleting the transport, unregister with rpcbind when appropriate.
> 
> ---v2 created a new xpt_flag XPT_RPCB_UNREG to mark TCP and UDP
> transport and at xprt destroy send rpcbind unregister if flag set.
> 
> Suggested-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
> Fixes: d093c9089260 ("nfsd: fix management of listener transports")
> Signed-off-by: Olga Kornievskaia <okorniev@xxxxxxxxxx>
> ---
>  include/linux/sunrpc/svc_xprt.h |  3 +++
>  net/sunrpc/svc_xprt.c           | 13 +++++++++++++
>  net/sunrpc/svcsock.c            |  2 ++
>  3 files changed, 18 insertions(+)
> 
> diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
> index 369a89aea186..2b886f7eb295 100644
> --- a/include/linux/sunrpc/svc_xprt.h
> +++ b/include/linux/sunrpc/svc_xprt.h
> @@ -104,6 +104,9 @@ enum {
>  				 * it has access to.  It is NOT counted
>  				 * in ->sv_tmpcnt.
>  				 */
> +	XPT_RPCB_UNREG,		/* transport that needs unregistering
> +				 * with rpcbind (TCP, UDP) on destroy
> +				 */
>  };
>  
>  /*
> diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
> index 8b1837228799..b800d704d807 100644
> --- a/net/sunrpc/svc_xprt.c
> +++ b/net/sunrpc/svc_xprt.c
> @@ -1014,6 +1014,19 @@ static void svc_delete_xprt(struct svc_xprt *xprt)
>  	struct svc_serv	*serv = xprt->xpt_server;
>  	struct svc_deferred_req *dr;
>  
> +	/* unregister with rpcbind for when transport type is TCP or UDP.
> +	 */
> +	if (test_bit(XPT_RPCB_UNREG, &xprt->xpt_flags)) {
> +		struct svc_sock *svsk = container_of(xprt, struct svc_sock,
> +						     sk_xprt);
> +		struct socket *sock = svsk->sk_sock;
> +
> +		if (svc_register(serv, xprt->xpt_net, sock->sk->sk_family,
> +				 sock->sk->sk_protocol, 0) < 0)
> +			pr_warn("failed to unregister %s with rpcbind\n",
> +				xprt->xpt_class->xcl_name);
> +	}
> +
>  	if (test_and_set_bit(XPT_DEAD, &xprt->xpt_flags))
>  		return;
>  
> diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
> index c0d5a27ba674..7b90abc5cf0e 100644
> --- a/net/sunrpc/svcsock.c
> +++ b/net/sunrpc/svcsock.c
> @@ -836,6 +836,7 @@ static void svc_udp_init(struct svc_sock *svsk, struct svc_serv *serv)
>  	/* data might have come in before data_ready set up */
>  	set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
>  	set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
> +	set_bit(XPT_RPCB_UNREG, &svsk->sk_xprt.xpt_flags);
>  
>  	/* make sure we get destination address info */
>  	switch (svsk->sk_sk->sk_family) {
> @@ -1350,6 +1351,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
>  	if (sk->sk_state == TCP_LISTEN) {
>  		strcpy(svsk->sk_xprt.xpt_remotebuf, "listener");
>  		set_bit(XPT_LISTENER, &svsk->sk_xprt.xpt_flags);
> +		set_bit(XPT_RPCB_UNREG, &svsk->sk_xprt.xpt_flags);
>  		sk->sk_data_ready = svc_tcp_listen_data_ready;
>  		set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
>  	} else {

The new flag does seem like a cleaner approach than v1.

Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx>





[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux