aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfssvc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfssvc.c')
-rw-r--r--fs/nfsd/nfssvc.c40
1 files changed, 18 insertions, 22 deletions
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