aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/clnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r--net/sunrpc/clnt.c71
1 files changed, 44 insertions, 27 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 5a750b9c3640..f0339ae9bf37 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -157,20 +157,15 @@ static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb,
157} 157}
158 158
159static int 159static int
160rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name) 160rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name,
161 struct super_block *pipefs_sb)
161{ 162{
162 struct net *net = rpc_net_ns(clnt);
163 struct super_block *pipefs_sb;
164 struct dentry *dentry; 163 struct dentry *dentry;
165 164
166 clnt->cl_dentry = NULL; 165 clnt->cl_dentry = NULL;
167 if (dir_name == NULL) 166 if (dir_name == NULL)
168 return 0; 167 return 0;
169 pipefs_sb = rpc_get_sb_net(net);
170 if (!pipefs_sb)
171 return 0;
172 dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name); 168 dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name);
173 rpc_put_sb_net(net);
174 if (IS_ERR(dentry)) 169 if (IS_ERR(dentry))
175 return PTR_ERR(dentry); 170 return PTR_ERR(dentry);
176 clnt->cl_dentry = dentry; 171 clnt->cl_dentry = dentry;
@@ -182,6 +177,8 @@ static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event
182 if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) || 177 if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
183 ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry)) 178 ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
184 return 1; 179 return 1;
180 if ((event == RPC_PIPEFS_MOUNT) && atomic_read(&clnt->cl_count) == 0)
181 return 1;
185 return 0; 182 return 0;
186} 183}
187 184
@@ -241,8 +238,6 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
241 continue; 238 continue;
242 if (rpc_clnt_skip_event(clnt, event)) 239 if (rpc_clnt_skip_event(clnt, event))
243 continue; 240 continue;
244 if (atomic_inc_not_zero(&clnt->cl_count) == 0)
245 continue;
246 spin_unlock(&sn->rpc_client_lock); 241 spin_unlock(&sn->rpc_client_lock);
247 return clnt; 242 return clnt;
248 } 243 }
@@ -259,7 +254,6 @@ static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
259 254
260 while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) { 255 while ((clnt = rpc_get_client_for_event(sb->s_fs_info, event))) {
261 error = __rpc_pipefs_event(clnt, event, sb); 256 error = __rpc_pipefs_event(clnt, event, sb);
262 rpc_release_client(clnt);
263 if (error) 257 if (error)
264 break; 258 break;
265 } 259 }
@@ -289,12 +283,46 @@ static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename)
289 memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen); 283 memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen);
290} 284}
291 285
286static int rpc_client_register(const struct rpc_create_args *args,
287 struct rpc_clnt *clnt)
288{
289 const struct rpc_program *program = args->program;
290 struct rpc_auth *auth;
291 struct net *net = rpc_net_ns(clnt);
292 struct super_block *pipefs_sb;
293 int err = 0;
294
295 pipefs_sb = rpc_get_sb_net(net);
296 if (pipefs_sb) {
297 err = rpc_setup_pipedir(clnt, program->pipe_dir_name, pipefs_sb);
298 if (err)
299 goto out;
300 }
301
302 auth = rpcauth_create(args->authflavor, clnt);
303 if (IS_ERR(auth)) {
304 dprintk("RPC: Couldn't create auth handle (flavor %u)\n",
305 args->authflavor);
306 err = PTR_ERR(auth);
307 goto err_auth;
308 }
309
310 rpc_register_client(clnt);
311out:
312 if (pipefs_sb)
313 rpc_put_sb_net(net);
314 return err;
315
316err_auth:
317 __rpc_clnt_remove_pipedir(clnt);
318 goto out;
319}
320
292static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) 321static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
293{ 322{
294 const struct rpc_program *program = args->program; 323 const struct rpc_program *program = args->program;
295 const struct rpc_version *version; 324 const struct rpc_version *version;
296 struct rpc_clnt *clnt = NULL; 325 struct rpc_clnt *clnt = NULL;
297 struct rpc_auth *auth;
298 int err; 326 int err;
299 327
300 /* sanity check the name before trying to print it */ 328 /* sanity check the name before trying to print it */
@@ -354,25 +382,14 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
354 382
355 atomic_set(&clnt->cl_count, 1); 383 atomic_set(&clnt->cl_count, 1);
356 384
357 err = rpc_setup_pipedir(clnt, program->pipe_dir_name);
358 if (err < 0)
359 goto out_no_path;
360
361 auth = rpcauth_create(args->authflavor, clnt);
362 if (IS_ERR(auth)) {
363 dprintk("RPC: Couldn't create auth handle (flavor %u)\n",
364 args->authflavor);
365 err = PTR_ERR(auth);
366 goto out_no_auth;
367 }
368
369 /* save the nodename */ 385 /* save the nodename */
370 rpc_clnt_set_nodename(clnt, utsname()->nodename); 386 rpc_clnt_set_nodename(clnt, utsname()->nodename);
371 rpc_register_client(clnt); 387
388 err = rpc_client_register(args, clnt);
389 if (err)
390 goto out_no_path;
372 return clnt; 391 return clnt;
373 392
374out_no_auth:
375 rpc_clnt_remove_pipedir(clnt);
376out_no_path: 393out_no_path:
377 kfree(clnt->cl_principal); 394 kfree(clnt->cl_principal);
378out_no_principal: 395out_no_principal:
@@ -637,8 +654,8 @@ rpc_free_client(struct rpc_clnt *clnt)
637 rcu_dereference(clnt->cl_xprt)->servername); 654 rcu_dereference(clnt->cl_xprt)->servername);
638 if (clnt->cl_parent != clnt) 655 if (clnt->cl_parent != clnt)
639 rpc_release_client(clnt->cl_parent); 656 rpc_release_client(clnt->cl_parent);
640 rpc_unregister_client(clnt);
641 rpc_clnt_remove_pipedir(clnt); 657 rpc_clnt_remove_pipedir(clnt);
658 rpc_unregister_client(clnt);
642 rpc_free_iostats(clnt->cl_metrics); 659 rpc_free_iostats(clnt->cl_metrics);
643 kfree(clnt->cl_principal); 660 kfree(clnt->cl_principal);
644 clnt->cl_metrics = NULL; 661 clnt->cl_metrics = NULL;