]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/nfsd/nfssvc.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus
[karo-tx-linux.git] / fs / nfsd / nfssvc.c
index a631ea61f76aeae97e47b2b0e9b5856ee2876ea4..e2c43464f23764405fef5e525e3829777be1a1a7 100644 (file)
@@ -180,14 +180,56 @@ int nfsd_nrthreads(void)
        return rv;
 }
 
+static int nfsd_init_socks(int port)
+{
+       int error;
+       if (!list_empty(&nfsd_serv->sv_permsocks))
+               return 0;
+
+       error = svc_create_xprt(nfsd_serv, "udp", PF_INET, port,
+                                       SVC_SOCK_DEFAULTS);
+       if (error < 0)
+               return error;
+
+       error = svc_create_xprt(nfsd_serv, "tcp", PF_INET, port,
+                                       SVC_SOCK_DEFAULTS);
+       if (error < 0)
+               return error;
+
+       return 0;
+}
+
 static bool nfsd_up = false;
 
 static int nfsd_startup(unsigned short port, int nrservs)
 {
        int ret;
 
+       if (nfsd_up)
+               return 0;
+       /*
+        * Readahead param cache - will no-op if it already exists.
+        * (Note therefore results will be suboptimal if number of
+        * threads is modified after nfsd start.)
+        */
+       ret = nfsd_racache_init(2*nrservs);
+       if (ret)
+               return ret;
+       ret = nfsd_init_socks(port);
+       if (ret)
+               goto out_racache;
+       ret = lockd_up();
+       if (ret)
+               goto out_racache;
        ret = nfs4_state_start();
+       if (ret)
+               goto out_lockd;
        nfsd_up = true;
+       return 0;
+out_lockd:
+       lockd_down();
+out_racache:
+       nfsd_racache_shutdown();
        return ret;
 }
 
@@ -202,17 +244,15 @@ static void nfsd_shutdown(void)
        if (!nfsd_up)
                return;
        nfs4_state_shutdown();
+       lockd_down();
+       nfsd_racache_shutdown();
        nfsd_up = false;
 }
 
 static void nfsd_last_thread(struct svc_serv *serv)
 {
        /* When last nfsd thread exits we need to do some clean-up */
-       struct svc_xprt *xprt;
-       list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list)
-               lockd_down();
        nfsd_serv = NULL;
-       nfsd_racache_shutdown();
        nfsd_shutdown();
 
        printk(KERN_WARNING "nfsd: last server has exited, flushing export "
@@ -288,6 +328,7 @@ int nfsd_create_serv(void)
                       nfsd_max_blksize >= 8*1024*2)
                        nfsd_max_blksize /= 2;
        }
+       nfsd_reset_versions();
 
        nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
                                      nfsd_last_thread, nfsd, THIS_MODULE);
@@ -299,33 +340,6 @@ int nfsd_create_serv(void)
        return err;
 }
 
-static int nfsd_init_socks(int port)
-{
-       int error;
-       if (!list_empty(&nfsd_serv->sv_permsocks))
-               return 0;
-
-       error = svc_create_xprt(nfsd_serv, "udp", PF_INET, port,
-                                       SVC_SOCK_DEFAULTS);
-       if (error < 0)
-               return error;
-
-       error = lockd_up();
-       if (error < 0)
-               return error;
-
-       error = svc_create_xprt(nfsd_serv, "tcp", PF_INET, port,
-                                       SVC_SOCK_DEFAULTS);
-       if (error < 0)
-               return error;
-
-       error = lockd_up();
-       if (error < 0)
-               return error;
-
-       return 0;
-}
-
 int nfsd_nrpools(void)
 {
        if (nfsd_serv == NULL)
@@ -400,11 +414,16 @@ int nfsd_set_nrthreads(int n, int *nthreads)
        return err;
 }
 
+/*
+ * Adjust the number of threads and return the new number of threads.
+ * This is also the function that starts the server if necessary, if
+ * this is the first time nrservs is nonzero.
+ */
 int
 nfsd_svc(unsigned short port, int nrservs)
 {
        int     error;
-       bool    first_thread;
+       bool    nfsd_up_before;
 
        mutex_lock(&nfsd_mutex);
        dprintk("nfsd: creating service\n");
@@ -416,40 +435,28 @@ nfsd_svc(unsigned short port, int nrservs)
        if (nrservs == 0 && nfsd_serv == NULL)
                goto out;
 
-       /* Readahead param cache - will no-op if it already exists */
-       error = nfsd_racache_init(2*nrservs);
-       if (error<0)
+       error = nfsd_create_serv();
+       if (error)
                goto out;
 
-       first_thread = (nfsd_serv->sv_nrthreads == 0) && (nrservs != 0);
+       nfsd_up_before = nfsd_up;
 
-       if (first_thread) {
-               error = nfsd_startup(port, nrservs);
-               if (error)
-                       goto out;
-       }
-
-       nfsd_reset_versions();
-
-       error = nfsd_create_serv();
-       if (error)
-               goto out_shutdown;
-       error = nfsd_init_socks(port);
+       error = nfsd_startup(port, nrservs);
        if (error)
                goto out_destroy;
-
        error = svc_set_num_threads(nfsd_serv, NULL, nrservs);
-       if (error == 0)
-               /* We are holding a reference to nfsd_serv which
-                * we don't want to count in the return value,
-                * so subtract 1
-                */
-               error = nfsd_serv->sv_nrthreads - 1;
-out_destroy:
-       svc_destroy(nfsd_serv);         /* Release server */
+       if (error)
+               goto out_shutdown;
+       /* We are holding a reference to nfsd_serv which
+        * we don't want to count in the return value,
+        * so subtract 1
+        */
+       error = nfsd_serv->sv_nrthreads - 1;
 out_shutdown:
-       if (error < 0 && first_thread)
+       if (error < 0 && !nfsd_up_before)
                nfsd_shutdown();
+out_destroy:
+       svc_destroy(nfsd_serv);         /* Release server */
 out:
        mutex_unlock(&nfsd_mutex);
        return error;