@@ -1959,6 +1959,7 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
1959
1959
struct svc_serv * serv ;
1960
1960
LIST_HEAD (permsocks );
1961
1961
struct nfsd_net * nn ;
1962
+ bool delete = false;
1962
1963
int err , rem ;
1963
1964
1964
1965
mutex_lock (& nfsd_mutex );
@@ -2019,34 +2020,28 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
2019
2020
}
2020
2021
}
2021
2022
2022
- /* For now, no removing old sockets while server is running */
2023
- if (serv -> sv_nrthreads && !list_empty (& permsocks )) {
2023
+ /*
2024
+ * If there are listener transports remaining on the permsocks list,
2025
+ * it means we were asked to remove a listener.
2026
+ */
2027
+ if (!list_empty (& permsocks )) {
2024
2028
list_splice_init (& permsocks , & serv -> sv_permsocks );
2025
- spin_unlock_bh (& serv -> sv_lock );
2026
- err = - EBUSY ;
2027
- goto out_unlock_mtx ;
2029
+ delete = true;
2028
2030
}
2031
+ spin_unlock_bh (& serv -> sv_lock );
2029
2032
2030
- /* Close the remaining sockets on the permsocks list */
2031
- while (!list_empty (& permsocks )) {
2032
- xprt = list_first_entry (& permsocks , struct svc_xprt , xpt_list );
2033
- list_move (& xprt -> xpt_list , & serv -> sv_permsocks );
2034
-
2035
- /*
2036
- * Newly-created sockets are born with the BUSY bit set. Clear
2037
- * it if there are no threads, since nothing can pick it up
2038
- * in that case.
2039
- */
2040
- if (!serv -> sv_nrthreads )
2041
- clear_bit (XPT_BUSY , & xprt -> xpt_flags );
2042
-
2043
- set_bit (XPT_CLOSE , & xprt -> xpt_flags );
2044
- spin_unlock_bh (& serv -> sv_lock );
2045
- svc_xprt_close (xprt );
2046
- spin_lock_bh (& serv -> sv_lock );
2033
+ /* Do not remove listeners while there are active threads. */
2034
+ if (serv -> sv_nrthreads ) {
2035
+ err = - EBUSY ;
2036
+ goto out_unlock_mtx ;
2047
2037
}
2048
2038
2049
- spin_unlock_bh (& serv -> sv_lock );
2039
+ /*
2040
+ * Since we can't delete an arbitrary llist entry, destroy the
2041
+ * remaining listeners and recreate the list.
2042
+ */
2043
+ if (delete )
2044
+ svc_xprt_destroy_all (serv , net );
2050
2045
2051
2046
/* walk list of addrs again, open any that still don't exist */
2052
2047
nlmsg_for_each_attr (attr , info -> nlhdr , GENL_HDRLEN , rem ) {
@@ -2073,6 +2068,9 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
2073
2068
2074
2069
xprt = svc_find_listener (serv , xcl_name , net , sa );
2075
2070
if (xprt ) {
2071
+ if (delete )
2072
+ WARN_ONCE (1 , "Transport type=%s already exists\n" ,
2073
+ xcl_name );
2076
2074
svc_xprt_put (xprt );
2077
2075
continue ;
2078
2076
}
0 commit comments