On Mon, 2025-08-18 at 14:25 -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. > > Fixes: d093c9089260 ("nfsd: fix management of listener transports") > Signed-off-by: Olga Kornievskaia <okorniev@xxxxxxxxxx> > --- > net/sunrpc/svc_xprt.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c > index 8b1837228799..223737fac95d 100644 > --- a/net/sunrpc/svc_xprt.c > +++ b/net/sunrpc/svc_xprt.c > @@ -1014,6 +1014,23 @@ 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. > + * Only TCP and RDMA sockets are marked as LISTENER sockets, so > + * check for UDP separately. > + */ > + if ((test_bit(XPT_LISTENER, &xprt->xpt_flags) && > + xprt->xpt_class->xcl_ident != XPRT_TRANSPORT_RDMA) || > + xprt->xpt_class->xcl_ident == XPRT_TRANSPORT_UDP) { > + 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; > This looks good to me. Doing it this way may be preferable if we ever get around to allowing the removal of listeners while the server is running. Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx>