aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/mon.c
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-09-18 05:37:12 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-10-01 18:27:34 -0400
commite9406db20fecbfcab646bad157b4cfdc7cadddfb (patch)
tree292fcb0062d86eb7170de559fdd211b21dbe40da /fs/lockd/mon.c
parent1dc42e04b75779d321f1d17dca3873004066f667 (diff)
lockd: per-net NSM client creation and destruction helpers introduced
NSM RPC client can be required on NFSv3 umount, when child reaper is dying (and destroying it's mount namespace). It means, that current nsproxy is set to NULL already, but creation of RPC client requires UTS namespace for gaining hostname string. This patch introduces reference counted NFS RPC clients creation and destruction helpers (similar to RPCBIND RPC clients). Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Cc: <stable@vger.kernel.org> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/lockd/mon.c')
-rw-r--r--fs/lockd/mon.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 7ef14b3c5bee..38f240e104ce 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -19,6 +19,8 @@
19 19
20#include <asm/unaligned.h> 20#include <asm/unaligned.h>
21 21
22#include "netns.h"
23
22#define NLMDBG_FACILITY NLMDBG_MONITOR 24#define NLMDBG_FACILITY NLMDBG_MONITOR
23#define NSM_PROGRAM 100024 25#define NSM_PROGRAM 100024
24#define NSM_VERSION 1 26#define NSM_VERSION 1
@@ -70,7 +72,7 @@ static struct rpc_clnt *nsm_create(struct net *net)
70 }; 72 };
71 struct rpc_create_args args = { 73 struct rpc_create_args args = {
72 .net = net, 74 .net = net,
73 .protocol = XPRT_TRANSPORT_UDP, 75 .protocol = XPRT_TRANSPORT_TCP,
74 .address = (struct sockaddr *)&sin, 76 .address = (struct sockaddr *)&sin,
75 .addrsize = sizeof(sin), 77 .addrsize = sizeof(sin),
76 .servername = "rpc.statd", 78 .servername = "rpc.statd",
@@ -83,6 +85,51 @@ static struct rpc_clnt *nsm_create(struct net *net)
83 return rpc_create(&args); 85 return rpc_create(&args);
84} 86}
85 87
88__maybe_unused static struct rpc_clnt *nsm_client_get(struct net *net)
89{
90 static DEFINE_MUTEX(nsm_create_mutex);
91 struct rpc_clnt *clnt;
92 struct lockd_net *ln = net_generic(net, lockd_net_id);
93
94 spin_lock(&ln->nsm_clnt_lock);
95 if (ln->nsm_users) {
96 ln->nsm_users++;
97 clnt = ln->nsm_clnt;
98 spin_unlock(&ln->nsm_clnt_lock);
99 goto out;
100 }
101 spin_unlock(&ln->nsm_clnt_lock);
102
103 mutex_lock(&nsm_create_mutex);
104 clnt = nsm_create(net);
105 if (!IS_ERR(clnt)) {
106 ln->nsm_clnt = clnt;
107 smp_wmb();
108 ln->nsm_users = 1;
109 }
110 mutex_unlock(&nsm_create_mutex);
111out:
112 return clnt;
113}
114
115__maybe_unused static void nsm_client_put(struct net *net)
116{
117 struct lockd_net *ln = net_generic(net, lockd_net_id);
118 struct rpc_clnt *clnt = ln->nsm_clnt;
119 int shutdown = 0;
120
121 spin_lock(&ln->nsm_clnt_lock);
122 if (ln->nsm_users) {
123 if (--ln->nsm_users)
124 ln->nsm_clnt = NULL;
125 shutdown = !ln->nsm_users;
126 }
127 spin_unlock(&ln->nsm_clnt_lock);
128
129 if (shutdown)
130 rpc_shutdown_client(clnt);
131}
132
86static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, 133static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
87 struct net *net) 134 struct net *net)
88{ 135{
@@ -111,7 +158,7 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
111 memset(res, 0, sizeof(*res)); 158 memset(res, 0, sizeof(*res));
112 159
113 msg.rpc_proc = &clnt->cl_procinfo[proc]; 160 msg.rpc_proc = &clnt->cl_procinfo[proc];
114 status = rpc_call_sync(clnt, &msg, 0); 161 status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN);
115 if (status < 0) 162 if (status < 0)
116 dprintk("lockd: NSM upcall RPC failed, status=%d\n", 163 dprintk("lockd: NSM upcall RPC failed, status=%d\n",
117 status); 164 status);