aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/svc.c
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-01-31 15:08:05 +0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-02-15 00:19:47 -0500
commitbb2224df5ffe4f864f5b696199b17db1ce77bc0a (patch)
tree1aa476668966b94ea5f5e399ea15f3aede936f47 /fs/lockd/svc.c
parentLockd: pernet usage counter introduced (diff)
downloadlinux-dev-bb2224df5ffe4f864f5b696199b17db1ce77bc0a.tar.xz
linux-dev-bb2224df5ffe4f864f5b696199b17db1ce77bc0a.zip
Lockd: per-net up and down routines introduced
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>
Diffstat (limited to 'fs/lockd/svc.c')
-rw-r--r--fs/lockd/svc.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 73c9ebf09301..90dec426bfd8 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -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);