aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2012-09-14 17:23:52 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-10-01 18:32:07 -0400
commit1b63a75180c6c65c71655c250a4e6b578ba7d1c0 (patch)
tree85743d02287e488622cf0504281973b455af8387 /net/sunrpc
parent632f0d0503accb8ab749a1165af99d344579c37b (diff)
SUNRPC: Refactor rpc_clone_client()
rpc_clone_client() does most of the same tasks as rpc_new_client(), so there is an opportunity for code re-use. Create a generic helper that makes it easy to clone an RPC client while replacing any of the clnt's parameters. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/clnt.c83
1 files changed, 43 insertions, 40 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index fa48c60aef23..afbeefab6600 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -490,59 +490,62 @@ EXPORT_SYMBOL_GPL(rpc_create);
490 * same transport while varying parameters such as the authentication 490 * same transport while varying parameters such as the authentication
491 * flavour. 491 * flavour.
492 */ 492 */
493struct rpc_clnt * 493static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
494rpc_clone_client(struct rpc_clnt *clnt) 494 struct rpc_clnt *clnt)
495{ 495{
496 struct rpc_clnt *new;
497 struct rpc_xprt *xprt; 496 struct rpc_xprt *xprt;
498 int err = -ENOMEM; 497 struct rpc_clnt *new;
498 int err;
499 499
500 new = kmemdup(clnt, sizeof(*new), GFP_KERNEL); 500 err = -ENOMEM;
501 if (!new)
502 goto out_no_clnt;
503 new->cl_parent = clnt;
504 /* Turn off autobind on clones */
505 new->cl_autobind = 0;
506 INIT_LIST_HEAD(&new->cl_tasks);
507 spin_lock_init(&new->cl_lock);
508 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_timeout->to_initval);
509 new->cl_metrics = rpc_alloc_iostats(clnt);
510 if (new->cl_metrics == NULL)
511 goto out_no_stats;
512 if (clnt->cl_principal) {
513 new->cl_principal = kstrdup(clnt->cl_principal, GFP_KERNEL);
514 if (new->cl_principal == NULL)
515 goto out_no_principal;
516 }
517 rcu_read_lock(); 501 rcu_read_lock();
518 xprt = xprt_get(rcu_dereference(clnt->cl_xprt)); 502 xprt = xprt_get(rcu_dereference(clnt->cl_xprt));
519 rcu_read_unlock(); 503 rcu_read_unlock();
520 if (xprt == NULL) 504 if (xprt == NULL)
521 goto out_no_transport; 505 goto out_err;
522 rcu_assign_pointer(new->cl_xprt, xprt); 506 args->servername = xprt->servername;
523 atomic_set(&new->cl_count, 1); 507
524 err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); 508 new = rpc_new_client(args, xprt);
525 if (err != 0) 509 if (IS_ERR(new)) {
526 goto out_no_path; 510 err = PTR_ERR(new);
527 rpc_clnt_set_nodename(new, utsname()->nodename); 511 goto out_put;
528 if (new->cl_auth) 512 }
529 atomic_inc(&new->cl_auth->au_count); 513
530 atomic_inc(&clnt->cl_count); 514 atomic_inc(&clnt->cl_count);
531 rpc_register_client(new); 515 new->cl_parent = clnt;
532 rpciod_up(); 516
517 /* Turn off autobind on clones */
518 new->cl_autobind = 0;
519 new->cl_softrtry = clnt->cl_softrtry;
520 new->cl_discrtry = clnt->cl_discrtry;
521 new->cl_chatty = clnt->cl_chatty;
533 return new; 522 return new;
534out_no_path: 523
524out_put:
535 xprt_put(xprt); 525 xprt_put(xprt);
536out_no_transport: 526out_err:
537 kfree(new->cl_principal);
538out_no_principal:
539 rpc_free_iostats(new->cl_metrics);
540out_no_stats:
541 kfree(new);
542out_no_clnt:
543 dprintk("RPC: %s: returned error %d\n", __func__, err); 527 dprintk("RPC: %s: returned error %d\n", __func__, err);
544 return ERR_PTR(err); 528 return ERR_PTR(err);
545} 529}
530
531/**
532 * rpc_clone_client - Clone an RPC client structure
533 *
534 * @clnt: RPC client whose parameters are copied
535 *
536 * Returns a fresh RPC client or an ERR_PTR.
537 */
538struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt)
539{
540 struct rpc_create_args args = {
541 .program = clnt->cl_program,
542 .prognumber = clnt->cl_prog,
543 .version = clnt->cl_vers,
544 .authflavor = clnt->cl_auth->au_flavor,
545 .client_name = clnt->cl_principal,
546 };
547 return __rpc_clone_client(&args, clnt);
548}
546EXPORT_SYMBOL_GPL(rpc_clone_client); 549EXPORT_SYMBOL_GPL(rpc_clone_client);
547 550
548/* 551/*