mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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
 | 
			
		||||
 * flavour.
 | 
			
		||||
 */
 | 
			
		||||
struct rpc_clnt *
 | 
			
		||||
rpc_clone_client(struct rpc_clnt *clnt)
 | 
			
		||||
static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
 | 
			
		||||
					   struct rpc_clnt *clnt)
 | 
			
		||||
{
 | 
			
		||||
	struct rpc_clnt *new;
 | 
			
		||||
	struct rpc_xprt *xprt;
 | 
			
		||||
	int err = -ENOMEM;
 | 
			
		||||
	struct rpc_clnt *new;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	new = kmemdup(clnt, sizeof(*new), GFP_KERNEL);
 | 
			
		||||
	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;
 | 
			
		||||
	}
 | 
			
		||||
	err = -ENOMEM;
 | 
			
		||||
	rcu_read_lock();
 | 
			
		||||
	xprt = xprt_get(rcu_dereference(clnt->cl_xprt));
 | 
			
		||||
	rcu_read_unlock();
 | 
			
		||||
	if (xprt == NULL)
 | 
			
		||||
		goto out_no_transport;
 | 
			
		||||
	rcu_assign_pointer(new->cl_xprt, xprt);
 | 
			
		||||
	atomic_set(&new->cl_count, 1);
 | 
			
		||||
	err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
 | 
			
		||||
	if (err != 0)
 | 
			
		||||
		goto out_no_path;
 | 
			
		||||
	rpc_clnt_set_nodename(new, utsname()->nodename);
 | 
			
		||||
	if (new->cl_auth)
 | 
			
		||||
		atomic_inc(&new->cl_auth->au_count);
 | 
			
		||||
		goto out_err;
 | 
			
		||||
	args->servername = xprt->servername;
 | 
			
		||||
 | 
			
		||||
	new = rpc_new_client(args, xprt);
 | 
			
		||||
	if (IS_ERR(new)) {
 | 
			
		||||
		err = PTR_ERR(new);
 | 
			
		||||
		goto out_put;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	atomic_inc(&clnt->cl_count);
 | 
			
		||||
	rpc_register_client(new);
 | 
			
		||||
	rpciod_up();
 | 
			
		||||
	new->cl_parent = clnt;
 | 
			
		||||
 | 
			
		||||
	/* 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;
 | 
			
		||||
out_no_path:
 | 
			
		||||
 | 
			
		||||
out_put:
 | 
			
		||||
	xprt_put(xprt);
 | 
			
		||||
out_no_transport:
 | 
			
		||||
	kfree(new->cl_principal);
 | 
			
		||||
out_no_principal:
 | 
			
		||||
	rpc_free_iostats(new->cl_metrics);
 | 
			
		||||
out_no_stats:
 | 
			
		||||
	kfree(new);
 | 
			
		||||
out_no_clnt:
 | 
			
		||||
out_err:
 | 
			
		||||
	dprintk("RPC:       %s: returned error %d\n", __func__, 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);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue