aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:49 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:49 -0500
commit1dd761e9070aa2e543df3db41bd75ed4b8f2fab9 (patch)
tree7709d032855e0e821f3ff4ce9efc3bdb82bf4d2d /fs/nfs
parent5428154827c2bf7cfdc9dab60db1e0eaa57c027a (diff)
NFSv4: Ensure the callback daemon flushes signals
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>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/callback.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 2c042f8d70b5..99d2cfbce863 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -55,7 +55,12 @@ static void nfs_callback_svc(struct svc_rqst *rqstp)
55 55
56 complete(&nfs_callback_info.started); 56 complete(&nfs_callback_info.started);
57 57
58 while (nfs_callback_info.users != 0 || !signalled()) { 58 for(;;) {
59 if (signalled()) {
60 if (nfs_callback_info.users == 0)
61 break;
62 flush_signals(current);
63 }
59 /* 64 /*
60 * Listen for a request on the socket 65 * Listen for a request on the socket
61 */ 66 */
@@ -135,11 +140,13 @@ int nfs_callback_down(void)
135 140
136 lock_kernel(); 141 lock_kernel();
137 down(&nfs_callback_sema); 142 down(&nfs_callback_sema);
138 if (--nfs_callback_info.users || nfs_callback_info.pid == 0) 143 nfs_callback_info.users--;
139 goto out; 144 do {
140 kill_proc(nfs_callback_info.pid, SIGKILL, 1); 145 if (nfs_callback_info.users != 0 || nfs_callback_info.pid == 0)
141 wait_for_completion(&nfs_callback_info.stopped); 146 break;
142out: 147 if (kill_proc(nfs_callback_info.pid, SIGKILL, 1) < 0)
148 break;
149 } while (wait_for_completion_timeout(&nfs_callback_info.stopped, 5*HZ) == 0);
143 up(&nfs_callback_sema); 150 up(&nfs_callback_sema);
144 unlock_kernel(); 151 unlock_kernel();
145 return ret; 152 return ret;