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>
This commit is contained in:
		
					parent
					
						
							
								632f0d0503
							
						
					
				
			
			
				commit
				
					
						1b63a75180
					
				
			
		
					 1 changed files with 43 additions and 40 deletions
				
			
		|  | @ -490,59 +490,62 @@ EXPORT_SYMBOL_GPL(rpc_create); | ||||||
|  * same transport while varying parameters such as the authentication |  * same transport while varying parameters such as the authentication | ||||||
|  * flavour. |  * flavour. | ||||||
|  */ |  */ | ||||||
| struct rpc_clnt * | static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, | ||||||
| rpc_clone_client(struct rpc_clnt *clnt) | 					   struct rpc_clnt *clnt) | ||||||
| { | { | ||||||
| 	struct rpc_clnt *new; |  | ||||||
| 	struct rpc_xprt *xprt; | 	struct rpc_xprt *xprt; | ||||||
| 	int err = -ENOMEM; | 	struct rpc_clnt *new; | ||||||
|  | 	int err; | ||||||
| 
 | 
 | ||||||
| 	new = kmemdup(clnt, sizeof(*new), GFP_KERNEL); | 	err = -ENOMEM; | ||||||
| 	if (!new) |  | ||||||
| 		goto out_no_clnt; |  | ||||||
| 	new->cl_parent = clnt; |  | ||||||
| 	/* Turn off autobind on clones */ |  | ||||||
| 	new->cl_autobind = 0; |  | ||||||
| 	INIT_LIST_HEAD(&new->cl_tasks); |  | ||||||
| 	spin_lock_init(&new->cl_lock); |  | ||||||
| 	rpc_init_rtt(&new->cl_rtt_default, clnt->cl_timeout->to_initval); |  | ||||||
| 	new->cl_metrics = rpc_alloc_iostats(clnt); |  | ||||||
| 	if (new->cl_metrics == NULL) |  | ||||||
| 		goto out_no_stats; |  | ||||||
| 	if (clnt->cl_principal) { |  | ||||||
| 		new->cl_principal = kstrdup(clnt->cl_principal, GFP_KERNEL); |  | ||||||
| 		if (new->cl_principal == NULL) |  | ||||||
| 			goto out_no_principal; |  | ||||||
| 	} |  | ||||||
| 	rcu_read_lock(); | 	rcu_read_lock(); | ||||||
| 	xprt = xprt_get(rcu_dereference(clnt->cl_xprt)); | 	xprt = xprt_get(rcu_dereference(clnt->cl_xprt)); | ||||||
| 	rcu_read_unlock(); | 	rcu_read_unlock(); | ||||||
| 	if (xprt == NULL) | 	if (xprt == NULL) | ||||||
| 		goto out_no_transport; | 		goto out_err; | ||||||
| 	rcu_assign_pointer(new->cl_xprt, xprt); | 	args->servername = xprt->servername; | ||||||
| 	atomic_set(&new->cl_count, 1); | 
 | ||||||
| 	err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); | 	new = rpc_new_client(args, xprt); | ||||||
| 	if (err != 0) | 	if (IS_ERR(new)) { | ||||||
| 		goto out_no_path; | 		err = PTR_ERR(new); | ||||||
| 	rpc_clnt_set_nodename(new, utsname()->nodename); | 		goto out_put; | ||||||
| 	if (new->cl_auth) | 	} | ||||||
| 		atomic_inc(&new->cl_auth->au_count); | 
 | ||||||
| 	atomic_inc(&clnt->cl_count); | 	atomic_inc(&clnt->cl_count); | ||||||
| 	rpc_register_client(new); | 	new->cl_parent = clnt; | ||||||
| 	rpciod_up(); | 
 | ||||||
|  | 	/* Turn off autobind on clones */ | ||||||
|  | 	new->cl_autobind = 0; | ||||||
|  | 	new->cl_softrtry = clnt->cl_softrtry; | ||||||
|  | 	new->cl_discrtry = clnt->cl_discrtry; | ||||||
|  | 	new->cl_chatty = clnt->cl_chatty; | ||||||
| 	return new; | 	return new; | ||||||
| out_no_path: | 
 | ||||||
|  | out_put: | ||||||
| 	xprt_put(xprt); | 	xprt_put(xprt); | ||||||
| out_no_transport: | out_err: | ||||||
| 	kfree(new->cl_principal); |  | ||||||
| out_no_principal: |  | ||||||
| 	rpc_free_iostats(new->cl_metrics); |  | ||||||
| out_no_stats: |  | ||||||
| 	kfree(new); |  | ||||||
| out_no_clnt: |  | ||||||
| 	dprintk("RPC:       %s: returned error %d\n", __func__, err); | 	dprintk("RPC:       %s: returned error %d\n", __func__, err); | ||||||
| 	return ERR_PTR(err); | 	return ERR_PTR(err); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * rpc_clone_client - Clone an RPC client structure | ||||||
|  |  * | ||||||
|  |  * @clnt: RPC client whose parameters are copied | ||||||
|  |  * | ||||||
|  |  * Returns a fresh RPC client or an ERR_PTR. | ||||||
|  |  */ | ||||||
|  | struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt) | ||||||
|  | { | ||||||
|  | 	struct rpc_create_args args = { | ||||||
|  | 		.program	= clnt->cl_program, | ||||||
|  | 		.prognumber	= clnt->cl_prog, | ||||||
|  | 		.version	= clnt->cl_vers, | ||||||
|  | 		.authflavor	= clnt->cl_auth->au_flavor, | ||||||
|  | 		.client_name	= clnt->cl_principal, | ||||||
|  | 	}; | ||||||
|  | 	return __rpc_clone_client(&args, clnt); | ||||||
|  | } | ||||||
| EXPORT_SYMBOL_GPL(rpc_clone_client); | EXPORT_SYMBOL_GPL(rpc_clone_client); | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Chuck Lever
				Chuck Lever