aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-10-02 05:17:44 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-02 10:57:17 -0400
commitbc591ccff27e6a85d3a0d6fcb16cfadcc45267a8 (patch)
tree20692a805b32ce5541f7175192f8ab81975434ec /fs
parent40f10522173c34e56cb9bf2fd37c62f69a427f1b (diff)
[PATCH] knfsd: add a callback for when last rpc thread finishes
nfsd has some cleanup that it wants to do when the last thread exits, and there will shortly be some more. So collect this all into one place and define a callback for an rpc service to call when the service is about to be destroyed. [akpm@osdl.org: cleanups, build fix] Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/lockd/svc.c2
-rw-r--r--fs/nfs/callback.c2
-rw-r--r--fs/nfsd/nfssvc.c40
3 files changed, 20 insertions, 24 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 9a991b52c647..13feba45030e 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -236,7 +236,7 @@ lockd_up(void)
236 "lockd_up: no pid, %d users??\n", nlmsvc_users); 236 "lockd_up: no pid, %d users??\n", nlmsvc_users);
237 237
238 error = -ENOMEM; 238 error = -ENOMEM;
239 serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE); 239 serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
240 if (!serv) { 240 if (!serv) {
241 printk(KERN_WARNING "lockd_up: create service failed\n"); 241 printk(KERN_WARNING "lockd_up: create service failed\n");
242 goto out; 242 goto out;
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index a3ee11364db0..e244cdc7afab 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -116,7 +116,7 @@ int nfs_callback_up(void)
116 goto out; 116 goto out;
117 init_completion(&nfs_callback_info.started); 117 init_completion(&nfs_callback_info.started);
118 init_completion(&nfs_callback_info.stopped); 118 init_completion(&nfs_callback_info.stopped);
119 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE); 119 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
120 ret = -ENOMEM; 120 ret = -ENOMEM;
121 if (!serv) 121 if (!serv)
122 goto out_err; 122 goto out_err;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index ec1decf29bab..c52c99964a4c 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -130,11 +130,25 @@ int nfsd_nrthreads(void)
130 return nfsd_serv->sv_nrthreads; 130 return nfsd_serv->sv_nrthreads;
131} 131}
132 132
133static int killsig; /* signal that was used to kill last nfsd */
134static void nfsd_last_thread(struct svc_serv *serv)
135{
136 /* When last nfsd thread exits we need to do some clean-up */
137 nfsd_serv = NULL;
138 nfsd_racache_shutdown();
139 nfs4_state_shutdown();
140
141 printk(KERN_WARNING "nfsd: last server has exited\n");
142 if (killsig != SIG_NOCLEAN) {
143 printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
144 nfsd_export_flush();
145 }
146}
133int 147int
134nfsd_svc(unsigned short port, int nrservs) 148nfsd_svc(unsigned short port, int nrservs)
135{ 149{
136 int error; 150 int error;
137 int none_left, found_one, i; 151 int found_one, i;
138 struct list_head *victim; 152 struct list_head *victim;
139 153
140 lock_kernel(); 154 lock_kernel();
@@ -197,7 +211,8 @@ nfsd_svc(unsigned short port, int nrservs)
197 211
198 atomic_set(&nfsd_busy, 0); 212 atomic_set(&nfsd_busy, 0);
199 error = -ENOMEM; 213 error = -ENOMEM;
200 nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE); 214 nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE,
215 nfsd_last_thread);
201 if (nfsd_serv == NULL) 216 if (nfsd_serv == NULL)
202 goto out; 217 goto out;
203 error = svc_makesock(nfsd_serv, IPPROTO_UDP, port); 218 error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
@@ -231,13 +246,7 @@ nfsd_svc(unsigned short port, int nrservs)
231 nrservs++; 246 nrservs++;
232 } 247 }
233 failure: 248 failure:
234 none_left = (nfsd_serv->sv_nrthreads == 1);
235 svc_destroy(nfsd_serv); /* Release server */ 249 svc_destroy(nfsd_serv); /* Release server */
236 if (none_left) {
237 nfsd_serv = NULL;
238 nfsd_racache_shutdown();
239 nfs4_state_shutdown();
240 }
241 out: 250 out:
242 unlock_kernel(); 251 unlock_kernel();
243 return error; 252 return error;
@@ -353,7 +362,7 @@ nfsd(struct svc_rqst *rqstp)
353 if (sigismember(&current->pending.signal, signo) && 362 if (sigismember(&current->pending.signal, signo) &&
354 !sigismember(&current->blocked, signo)) 363 !sigismember(&current->blocked, signo))
355 break; 364 break;
356 err = signo; 365 killsig = signo;
357 } 366 }
358 /* Clear signals before calling lockd_down() and svc_exit_thread() */ 367 /* Clear signals before calling lockd_down() and svc_exit_thread() */
359 flush_signals(current); 368 flush_signals(current);
@@ -362,19 +371,6 @@ nfsd(struct svc_rqst *rqstp)
362 371
363 /* Release lockd */ 372 /* Release lockd */
364 lockd_down(); 373 lockd_down();
365
366 /* Check if this is last thread */
367 if (serv->sv_nrthreads==1) {
368
369 printk(KERN_WARNING "nfsd: last server has exited\n");
370 if (err != SIG_NOCLEAN) {
371 printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
372 nfsd_export_flush();
373 }
374 nfsd_serv = NULL;
375 nfsd_racache_shutdown(); /* release read-ahead cache */
376 nfs4_state_shutdown();
377 }
378 list_del(&me.list); 374 list_del(&me.list);
379 nfsdstats.th_cnt --; 375 nfsdstats.th_cnt --;
380 376