diff options
Diffstat (limited to 'fs/nfsd/nfssvc.c')
-rw-r--r-- | fs/nfsd/nfssvc.c | 40 |
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 | ||
133 | static int killsig; /* signal that was used to kill last nfsd */ | ||
134 | static 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 | } | ||
133 | int | 147 | int |
134 | nfsd_svc(unsigned short port, int nrservs) | 148 | nfsd_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(¤t->pending.signal, signo) && | 362 | if (sigismember(¤t->pending.signal, signo) && |
354 | !sigismember(¤t->blocked, signo)) | 363 | !sigismember(¤t->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 | ||