@@ -1917,6 +1917,7 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
19171917 struct svc_serv * serv ;
19181918 LIST_HEAD (permsocks );
19191919 struct nfsd_net * nn ;
1920+ bool delete = false;
19201921 int err , rem ;
19211922
19221923 mutex_lock (& nfsd_mutex );
@@ -1977,34 +1978,28 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
19771978 }
19781979 }
19791980
1980- /* For now, no removing old sockets while server is running */
1981- if (serv -> sv_nrthreads && !list_empty (& permsocks )) {
1981+ /*
1982+ * If there are listener transports remaining on the permsocks list,
1983+ * it means we were asked to remove a listener.
1984+ */
1985+ if (!list_empty (& permsocks )) {
19821986 list_splice_init (& permsocks , & serv -> sv_permsocks );
1983- spin_unlock_bh (& serv -> sv_lock );
1984- err = - EBUSY ;
1985- goto out_unlock_mtx ;
1987+ delete = true;
19861988 }
1989+ spin_unlock_bh (& serv -> sv_lock );
19871990
1988- /* Close the remaining sockets on the permsocks list */
1989- while (!list_empty (& permsocks )) {
1990- xprt = list_first_entry (& permsocks , struct svc_xprt , xpt_list );
1991- list_move (& xprt -> xpt_list , & serv -> sv_permsocks );
1992-
1993- /*
1994- * Newly-created sockets are born with the BUSY bit set. Clear
1995- * it if there are no threads, since nothing can pick it up
1996- * in that case.
1997- */
1998- if (!serv -> sv_nrthreads )
1999- clear_bit (XPT_BUSY , & xprt -> xpt_flags );
2000-
2001- set_bit (XPT_CLOSE , & xprt -> xpt_flags );
2002- spin_unlock_bh (& serv -> sv_lock );
2003- svc_xprt_close (xprt );
2004- spin_lock_bh (& serv -> sv_lock );
1991+ /* Do not remove listeners while there are active threads. */
1992+ if (serv -> sv_nrthreads ) {
1993+ err = - EBUSY ;
1994+ goto out_unlock_mtx ;
20051995 }
20061996
2007- spin_unlock_bh (& serv -> sv_lock );
1997+ /*
1998+ * Since we can't delete an arbitrary llist entry, destroy the
1999+ * remaining listeners and recreate the list.
2000+ */
2001+ if (delete )
2002+ svc_xprt_destroy_all (serv , net );
20082003
20092004 /* walk list of addrs again, open any that still don't exist */
20102005 nlmsg_for_each_attr (attr , info -> nlhdr , GENL_HDRLEN , rem ) {
@@ -2031,6 +2026,9 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
20312026
20322027 xprt = svc_find_listener (serv , xcl_name , net , sa );
20332028 if (xprt ) {
2029+ if (delete )
2030+ WARN_ONCE (1 , "Transport type=%s already exists\n" ,
2031+ xcl_name );
20342032 svc_xprt_put (xprt );
20352033 continue ;
20362034 }
0 commit comments