"lockd_up: no pid, %d users??\n", nlmsvc_users);
 
        error = -ENOMEM;
-       serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE);
+       serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
        if (!serv) {
                printk(KERN_WARNING "lockd_up: create service failed\n");
                goto out;
 
                goto out;
        init_completion(&nfs_callback_info.started);
        init_completion(&nfs_callback_info.stopped);
-       serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE);
+       serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
        ret = -ENOMEM;
        if (!serv)
                goto out_err;
 
                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();
 
                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);
                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;
                        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);
 
        /* 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 --;
 
 
        int                     sv_tmpcnt;      /* count of temporary sockets */
 
        char *                  sv_name;        /* service name */
+
+       void                    (*sv_shutdown)(struct svc_serv *serv);
+                                               /* Callback to use when last thread
+                                                * exits.
+                                                */
 };
 
 /*
 /*
  * Function prototypes.
  */
-struct svc_serv *  svc_create(struct svc_program *, unsigned int);
+struct svc_serv *  svc_create(struct svc_program *, unsigned int,
+                             void (*shutdown)(struct svc_serv*));
 int               svc_create_thread(svc_thread_fn, struct svc_serv *);
 void              svc_exit_thread(struct svc_rqst *);
 void              svc_destroy(struct svc_serv *);
 
  * Create an RPC service
  */
 struct svc_serv *
-svc_create(struct svc_program *prog, unsigned int bufsize)
+svc_create(struct svc_program *prog, unsigned int bufsize,
+          void (*shutdown)(struct svc_serv *serv))
 {
        struct svc_serv *serv;
        int vers;
        serv->sv_nrthreads = 1;
        serv->sv_stats     = prog->pg_stats;
        serv->sv_bufsz     = bufsize? bufsize : 4096;
+       serv->sv_shutdown  = shutdown;
        xdrsize = 0;
        while (prog) {
                prog->pg_lovers = prog->pg_nvers-1;
                                  sk_list);
                svc_delete_socket(svsk);
        }
+       if (serv->sv_shutdown)
+               serv->sv_shutdown(serv);
+
        while (!list_empty(&serv->sv_permsocks)) {
                svsk = list_entry(serv->sv_permsocks.next,
                                  struct svc_sock,