Skip to content

Commit

Permalink
NFSv4: Ensure the callback daemon flushes signals
Browse files Browse the repository at this point in the history
If the callback daemon is signalled, but is unable to exit because it still
has users, then we need to flush signals. If not, then svc_recv() can
never sleep, and so we hang.
If we flush signals, then we also have to be prepared to resend them when
we want the thread to exit.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Mar 20, 2006
1 parent 5428154 commit 1dd761e
Showing 1 changed file with 13 additions and 6 deletions.
19 changes: 13 additions & 6 deletions fs/nfs/callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)

complete(&nfs_callback_info.started);

while (nfs_callback_info.users != 0 || !signalled()) {
for(;;) {
if (signalled()) {
if (nfs_callback_info.users == 0)
break;
flush_signals(current);
}
/*
* Listen for a request on the socket
*/
Expand Down Expand Up @@ -135,11 +140,13 @@ int nfs_callback_down(void)

lock_kernel();
down(&nfs_callback_sema);
if (--nfs_callback_info.users || nfs_callback_info.pid == 0)
goto out;
kill_proc(nfs_callback_info.pid, SIGKILL, 1);
wait_for_completion(&nfs_callback_info.stopped);
out:
nfs_callback_info.users--;
do {
if (nfs_callback_info.users != 0 || nfs_callback_info.pid == 0)
break;
if (kill_proc(nfs_callback_info.pid, SIGKILL, 1) < 0)
break;
} while (wait_for_completion_timeout(&nfs_callback_info.stopped, 5*HZ) == 0);
up(&nfs_callback_sema);
unlock_kernel();
return ret;
Expand Down

0 comments on commit 1dd761e

Please sign in to comment.