@@ -1917,6 +1917,7 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
1917
1917
struct svc_serv * serv ;
1918
1918
LIST_HEAD (permsocks );
1919
1919
struct nfsd_net * nn ;
1920
+ bool delete = false;
1920
1921
int err , rem ;
1921
1922
1922
1923
mutex_lock (& nfsd_mutex );
@@ -1977,34 +1978,28 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
1977
1978
}
1978
1979
}
1979
1980
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 )) {
1982
1986
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;
1986
1988
}
1989
+ spin_unlock_bh (& serv -> sv_lock );
1987
1990
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 ;
2005
1995
}
2006
1996
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 );
2008
2003
2009
2004
/* walk list of addrs again, open any that still don't exist */
2010
2005
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)
2031
2026
2032
2027
xprt = svc_find_listener (serv , xcl_name , net , sa );
2033
2028
if (xprt ) {
2029
+ if (delete )
2030
+ WARN_ONCE (1 , "Transport type=%s already exists\n" ,
2031
+ xcl_name );
2034
2032
svc_xprt_put (xprt );
2035
2033
continue ;
2036
2034
}
0 commit comments