aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/lockd/mon.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index e0bc36e74ceb..e4fb3ba5a58a 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -7,7 +7,6 @@
7 */ 7 */
8 8
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/utsname.h>
11#include <linux/kernel.h> 10#include <linux/kernel.h>
12#include <linux/ktime.h> 11#include <linux/ktime.h>
13#include <linux/slab.h> 12#include <linux/slab.h>
@@ -86,7 +85,7 @@ static struct rpc_clnt *nsm_create(struct net *net)
86 return rpc_create(&args); 85 return rpc_create(&args);
87} 86}
88 87
89__maybe_unused static struct rpc_clnt *nsm_client_get(struct net *net) 88static struct rpc_clnt *nsm_client_get(struct net *net)
90{ 89{
91 static DEFINE_MUTEX(nsm_create_mutex); 90 static DEFINE_MUTEX(nsm_create_mutex);
92 struct rpc_clnt *clnt; 91 struct rpc_clnt *clnt;
@@ -113,7 +112,7 @@ out:
113 return clnt; 112 return clnt;
114} 113}
115 114
116__maybe_unused static void nsm_client_put(struct net *net) 115static void nsm_client_put(struct net *net)
117{ 116{
118 struct lockd_net *ln = net_generic(net, lockd_net_id); 117 struct lockd_net *ln = net_generic(net, lockd_net_id);
119 struct rpc_clnt *clnt = ln->nsm_clnt; 118 struct rpc_clnt *clnt = ln->nsm_clnt;
@@ -132,9 +131,8 @@ __maybe_unused static void nsm_client_put(struct net *net)
132} 131}
133 132
134static 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,
135 struct net *net) 134 struct rpc_clnt *clnt)
136{ 135{
137 struct rpc_clnt *clnt;
138 int status; 136 int status;
139 struct nsm_args args = { 137 struct nsm_args args = {
140 .priv = &nsm->sm_priv, 138 .priv = &nsm->sm_priv,
@@ -142,20 +140,14 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
142 .vers = 3, 140 .vers = 3,
143 .proc = NLMPROC_NSM_NOTIFY, 141 .proc = NLMPROC_NSM_NOTIFY,
144 .mon_name = nsm->sm_mon_name, 142 .mon_name = nsm->sm_mon_name,
145 .nodename = utsname()->nodename, 143 .nodename = clnt->cl_nodename,
146 }; 144 };
147 struct rpc_message msg = { 145 struct rpc_message msg = {
148 .rpc_argp = &args, 146 .rpc_argp = &args,
149 .rpc_resp = res, 147 .rpc_resp = res,
150 }; 148 };
151 149
152 clnt = nsm_create(net); 150 BUG_ON(clnt == NULL);
153 if (IS_ERR(clnt)) {
154 status = PTR_ERR(clnt);
155 dprintk("lockd: failed to create NSM upcall transport, "
156 "status=%d\n", status);
157 goto out;
158 }
159 151
160 memset(res, 0, sizeof(*res)); 152 memset(res, 0, sizeof(*res));
161 153
@@ -166,8 +158,6 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
166 status); 158 status);
167 else 159 else
168 status = 0; 160 status = 0;
169 rpc_shutdown_client(clnt);
170 out:
171 return status; 161 return status;
172} 162}
173 163
@@ -187,6 +177,7 @@ int nsm_monitor(const struct nlm_host *host)
187 struct nsm_handle *nsm = host->h_nsmhandle; 177 struct nsm_handle *nsm = host->h_nsmhandle;
188 struct nsm_res res; 178 struct nsm_res res;
189 int status; 179 int status;
180 struct rpc_clnt *clnt;
190 181
191 dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name); 182 dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name);
192 183
@@ -199,7 +190,15 @@ int nsm_monitor(const struct nlm_host *host)
199 */ 190 */
200 nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf; 191 nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
201 192
202 status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host->net); 193 clnt = nsm_client_get(host->net);
194 if (IS_ERR(clnt)) {
195 status = PTR_ERR(clnt);
196 dprintk("lockd: failed to create NSM upcall transport, "
197 "status=%d, net=%p\n", status, host->net);
198 return status;
199 }
200
201 status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, clnt);
203 if (unlikely(res.status != 0)) 202 if (unlikely(res.status != 0))
204 status = -EIO; 203 status = -EIO;
205 if (unlikely(status < 0)) { 204 if (unlikely(status < 0)) {
@@ -231,9 +230,11 @@ void nsm_unmonitor(const struct nlm_host *host)
231 230
232 if (atomic_read(&nsm->sm_count) == 1 231 if (atomic_read(&nsm->sm_count) == 1
233 && nsm->sm_monitored && !nsm->sm_sticky) { 232 && nsm->sm_monitored && !nsm->sm_sticky) {
233 struct lockd_net *ln = net_generic(host->net, lockd_net_id);
234
234 dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name); 235 dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name);
235 236
236 status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host->net); 237 status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, ln->nsm_clnt);
237 if (res.status != 0) 238 if (res.status != 0)
238 status = -EIO; 239 status = -EIO;
239 if (status < 0) 240 if (status < 0)
@@ -241,6 +242,8 @@ void nsm_unmonitor(const struct nlm_host *host)
241 nsm->sm_name); 242 nsm->sm_name);
242 else 243 else
243 nsm->sm_monitored = 0; 244 nsm->sm_monitored = 0;
245
246 nsm_client_put(host->net);
244 } 247 }
245} 248}
246 249