[PATCH] knfsd: fix recently introduced problem with shutting down a busy NFS server

When the last thread of nfsd exits, it shuts down all related sockets.  It
currently uses svc_close_socket to do this, but that only is immediately
effective if the socket is not SK_BUSY.

If the socket is busy - i.e.  if a request has arrived that has not yet been
processes - svc_close_socket is not effective and the shutdown process spins.

So create a new svc_force_close_socket which removes the SK_BUSY flag is set
and then calls svc_close_socket.

Also change some open-codes loops in svc_destroy to use
list_for_each_entry_safe.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
NeilBrown
2007-03-06 01:42:22 -08:00
committed by Linus Torvalds
parent 5a05ed73e1
commit cda1fd4abd
3 changed files with 25 additions and 14 deletions

View File

@@ -367,6 +367,7 @@ void
svc_destroy(struct svc_serv *serv)
{
struct svc_sock *svsk;
struct svc_sock *tmp;
dprintk("svc: svc_destroy(%s, %d)\n",
serv->sv_program->pg_name,
@@ -382,21 +383,17 @@ svc_destroy(struct svc_serv *serv)
del_timer_sync(&serv->sv_temptimer);
while (!list_empty(&serv->sv_tempsocks)) {
svsk = list_entry(serv->sv_tempsocks.next,
struct svc_sock,
sk_list);
svc_close_socket(svsk);
}
list_for_each_entry_safe(svsk, tmp, &serv->sv_tempsocks, sk_list)
svc_force_close_socket(svsk);
if (serv->sv_shutdown)
serv->sv_shutdown(serv);
while (!list_empty(&serv->sv_permsocks)) {
svsk = list_entry(serv->sv_permsocks.next,
struct svc_sock,
sk_list);
svc_close_socket(svsk);
}
list_for_each_entry_safe(svsk, tmp, &serv->sv_permsocks, sk_list)
svc_force_close_socket(svsk);
BUG_ON(!list_empty(&serv->sv_permsocks));
BUG_ON(!list_empty(&serv->sv_tempsocks));
cache_clean_deferred(serv);