@@ -1951,6 +1951,7 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
19511951 struct svc_serv * serv ;
19521952 LIST_HEAD (permsocks );
19531953 struct nfsd_net * nn ;
1954+ bool delete = false;
19541955 int err , rem ;
19551956
19561957 mutex_lock (& nfsd_mutex );
@@ -2011,34 +2012,28 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
20112012 }
20122013 }
20132014
2014- /* For now, no removing old sockets while server is running */
2015- if (serv -> sv_nrthreads && !list_empty (& permsocks )) {
2015+ /*
2016+ * If there are listener transports remaining on the permsocks list,
2017+ * it means we were asked to remove a listener.
2018+ */
2019+ if (!list_empty (& permsocks )) {
20162020 list_splice_init (& permsocks , & serv -> sv_permsocks );
2017- spin_unlock_bh (& serv -> sv_lock );
2018- err = - EBUSY ;
2019- goto out_unlock_mtx ;
2021+ delete = true;
20202022 }
2023+ spin_unlock_bh (& serv -> sv_lock );
20212024
2022- /* Close the remaining sockets on the permsocks list */
2023- while (!list_empty (& permsocks )) {
2024- xprt = list_first_entry (& permsocks , struct svc_xprt , xpt_list );
2025- list_move (& xprt -> xpt_list , & serv -> sv_permsocks );
2026-
2027- /*
2028- * Newly-created sockets are born with the BUSY bit set. Clear
2029- * it if there are no threads, since nothing can pick it up
2030- * in that case.
2031- */
2032- if (!serv -> sv_nrthreads )
2033- clear_bit (XPT_BUSY , & xprt -> xpt_flags );
2034-
2035- set_bit (XPT_CLOSE , & xprt -> xpt_flags );
2036- spin_unlock_bh (& serv -> sv_lock );
2037- svc_xprt_close (xprt );
2038- spin_lock_bh (& serv -> sv_lock );
2025+ /* Do not remove listeners while there are active threads. */
2026+ if (serv -> sv_nrthreads ) {
2027+ err = - EBUSY ;
2028+ goto out_unlock_mtx ;
20392029 }
20402030
2041- spin_unlock_bh (& serv -> sv_lock );
2031+ /*
2032+ * Since we can't delete an arbitrary llist entry, destroy the
2033+ * remaining listeners and recreate the list.
2034+ */
2035+ if (delete )
2036+ svc_xprt_destroy_all (serv , net );
20422037
20432038 /* walk list of addrs again, open any that still don't exist */
20442039 nlmsg_for_each_attr (attr , info -> nlhdr , GENL_HDRLEN , rem ) {
@@ -2065,6 +2060,9 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
20652060
20662061 xprt = svc_find_listener (serv , xcl_name , net , sa );
20672062 if (xprt ) {
2063+ if (delete )
2064+ WARN_ONCE (1 , "Transport type=%s already exists\n" ,
2065+ xcl_name );
20682066 svc_xprt_put (xprt );
20692067 continue ;
20702068 }
0 commit comments