Lockd: per-net up and down routines introduced
authorStanislav Kinsbursky <skinsbursky@parallels.com>
Tue, 31 Jan 2012 11:08:05 +0000 (15:08 +0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 15 Feb 2012 05:19:47 +0000 (00:19 -0500)
This patch introduces per-net Lockd initialization and destruction routines.
The logic is the same as in global Lockd up and down routines. Probably the
solution is not the best one. But at least it looks clear.
So per-net "up" routine are called only in case of lockd is running already. If
per-net resources are not allocated yet, then service is being registered with
local portmapper and lockd sockets created.
Per-net "down" routine is called on every lockd_down() call in case of global
users counter is not zero.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/lockd/svc.c
include/linux/sunrpc/svc.h
net/sunrpc/svc.c

index 73c9ebf09301f67d449ba78ed4b79176ff59e663..90dec426bfd889d1d02659accf856b03b0a1f2f6 100644 (file)
@@ -251,6 +251,45 @@ out_err:
        return err;
 }
 
+static int lockd_up_net(struct net *net)
+{
+       struct lockd_net *ln = net_generic(net, lockd_net_id);
+       struct svc_serv *serv = nlmsvc_rqst->rq_server;
+       int error;
+
+       if (ln->nlmsvc_users)
+               return 0;
+
+       error = svc_rpcb_setup(serv, net);
+       if (error)
+               goto err_rpcb;
+
+       error = make_socks(serv, net);
+       if (error < 0)
+               goto err_socks;
+       return 0;
+
+err_socks:
+       svc_rpcb_cleanup(serv, net);
+err_rpcb:
+       return error;
+}
+
+static void lockd_down_net(struct net *net)
+{
+       struct lockd_net *ln = net_generic(net, lockd_net_id);
+       struct svc_serv *serv = nlmsvc_rqst->rq_server;
+
+       if (ln->nlmsvc_users) {
+               if (--ln->nlmsvc_users == 0)
+                       svc_shutdown_net(serv, net);
+       } else {
+               printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n",
+                               nlmsvc_task, net);
+               BUG();
+       }
+}
+
 /*
  * Bring up the lockd process if it's not already up.
  */
@@ -264,8 +303,10 @@ int lockd_up(void)
        /*
         * Check whether we're already up and running.
         */
-       if (nlmsvc_rqst)
+       if (nlmsvc_rqst) {
+               error = lockd_up_net(net);
                goto out;
+       }
 
        /*
         * Sanity check: if there's no pid,
@@ -339,8 +380,10 @@ lockd_down(void)
 {
        mutex_lock(&nlmsvc_mutex);
        if (nlmsvc_users) {
-               if (--nlmsvc_users)
+               if (--nlmsvc_users) {
+                       lockd_down_net(current->nsproxy->net_ns);
                        goto out;
+               }
        } else {
                printk(KERN_ERR "lockd_down: no users! task=%p\n",
                        nlmsvc_task);
index 7b65495aa4ef4497108ba8f479c9ec6c25310143..51b29ac45a8e7b26583df0217ab37a0d939ad6da 100644 (file)
@@ -414,6 +414,7 @@ struct svc_procedure {
 /*
  * Function prototypes.
  */
+int svc_rpcb_setup(struct svc_serv *serv, struct net *net);
 void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net);
 struct svc_serv *svc_create(struct svc_program *, unsigned int,
                            void (*shutdown)(struct svc_serv *, struct net *net));
@@ -426,6 +427,7 @@ struct svc_serv *  svc_create_pooled(struct svc_program *, unsigned int,
 int               svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
 int               svc_pool_stats_open(struct svc_serv *serv, struct file *file);
 void              svc_destroy(struct svc_serv *);
+void              svc_shutdown_net(struct svc_serv *, struct net *);
 int               svc_process(struct svc_rqst *);
 int               bc_svc_process(struct svc_serv *, struct rpc_rqst *,
                        struct svc_rqst *);
index 78abac48985b69a1d877837e71bbc00bab9a6c58..4153846984ac72be3a0f97b1ede45799128be863 100644 (file)
@@ -369,7 +369,7 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
        return &serv->sv_pools[pidx % serv->sv_nrpools];
 }
 
-static int svc_rpcb_setup(struct svc_serv *serv, struct net *net)
+int svc_rpcb_setup(struct svc_serv *serv, struct net *net)
 {
        int err;
 
@@ -381,6 +381,7 @@ static int svc_rpcb_setup(struct svc_serv *serv, struct net *net)
        svc_unregister(serv, net);
        return 0;
 }
+EXPORT_SYMBOL_GPL(svc_rpcb_setup);
 
 void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net)
 {