|
@@ -130,11 +130,25 @@ int nfsd_nrthreads(void)
|
|
|
return nfsd_serv->sv_nrthreads;
|
|
|
}
|
|
|
|
|
|
+static int killsig; /* signal that was used to kill last nfsd */
|
|
|
+static void nfsd_last_thread(struct svc_serv *serv)
|
|
|
+{
|
|
|
+ /* When last nfsd thread exits we need to do some clean-up */
|
|
|
+ nfsd_serv = NULL;
|
|
|
+ nfsd_racache_shutdown();
|
|
|
+ nfs4_state_shutdown();
|
|
|
+
|
|
|
+ printk(KERN_WARNING "nfsd: last server has exited\n");
|
|
|
+ if (killsig != SIG_NOCLEAN) {
|
|
|
+ printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
|
|
|
+ nfsd_export_flush();
|
|
|
+ }
|
|
|
+}
|
|
|
int
|
|
|
nfsd_svc(unsigned short port, int nrservs)
|
|
|
{
|
|
|
int error;
|
|
|
- int none_left, found_one, i;
|
|
|
+ int found_one, i;
|
|
|
struct list_head *victim;
|
|
|
|
|
|
lock_kernel();
|
|
@@ -197,7 +211,8 @@ nfsd_svc(unsigned short port, int nrservs)
|
|
|
|
|
|
atomic_set(&nfsd_busy, 0);
|
|
|
error = -ENOMEM;
|
|
|
- nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
|
|
|
+ nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE,
|
|
|
+ nfsd_last_thread);
|
|
|
if (nfsd_serv == NULL)
|
|
|
goto out;
|
|
|
error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
|
|
@@ -231,13 +246,7 @@ nfsd_svc(unsigned short port, int nrservs)
|
|
|
nrservs++;
|
|
|
}
|
|
|
failure:
|
|
|
- none_left = (nfsd_serv->sv_nrthreads == 1);
|
|
|
svc_destroy(nfsd_serv); /* Release server */
|
|
|
- if (none_left) {
|
|
|
- nfsd_serv = NULL;
|
|
|
- nfsd_racache_shutdown();
|
|
|
- nfs4_state_shutdown();
|
|
|
- }
|
|
|
out:
|
|
|
unlock_kernel();
|
|
|
return error;
|
|
@@ -353,7 +362,7 @@ nfsd(struct svc_rqst *rqstp)
|
|
|
if (sigismember(¤t->pending.signal, signo) &&
|
|
|
!sigismember(¤t->blocked, signo))
|
|
|
break;
|
|
|
- err = signo;
|
|
|
+ killsig = signo;
|
|
|
}
|
|
|
/* Clear signals before calling lockd_down() and svc_exit_thread() */
|
|
|
flush_signals(current);
|
|
@@ -362,19 +371,6 @@ nfsd(struct svc_rqst *rqstp)
|
|
|
|
|
|
/* Release lockd */
|
|
|
lockd_down();
|
|
|
-
|
|
|
- /* Check if this is last thread */
|
|
|
- if (serv->sv_nrthreads==1) {
|
|
|
-
|
|
|
- printk(KERN_WARNING "nfsd: last server has exited\n");
|
|
|
- if (err != SIG_NOCLEAN) {
|
|
|
- printk(KERN_WARNING "nfsd: unexporting all filesystems\n");
|
|
|
- nfsd_export_flush();
|
|
|
- }
|
|
|
- nfsd_serv = NULL;
|
|
|
- nfsd_racache_shutdown(); /* release read-ahead cache */
|
|
|
- nfs4_state_shutdown();
|
|
|
- }
|
|
|
list_del(&me.list);
|
|
|
nfsdstats.th_cnt --;
|
|
|
|