diff options
Diffstat (limited to 'net/sunrpc/clnt.c')
| -rw-r--r-- | net/sunrpc/clnt.c | 44 | 
1 files changed, 40 insertions, 4 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index af0174d7ce5a..e2c6eca0271b 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -76,6 +76,7 @@ static int	rpc_encode_header(struct rpc_task *task,  static int	rpc_decode_header(struct rpc_task *task,  				  struct xdr_stream *xdr);  static int	rpc_ping(struct rpc_clnt *clnt); +static int	rpc_ping_noreply(struct rpc_clnt *clnt);  static void	rpc_check_timeout(struct rpc_task *task);  static void rpc_register_client(struct rpc_clnt *clnt) @@ -483,6 +484,12 @@ static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,  			rpc_shutdown_client(clnt);  			return ERR_PTR(err);  		} +	} else if (args->flags & RPC_CLNT_CREATE_CONNECTED) { +		int err = rpc_ping_noreply(clnt); +		if (err != 0) { +			rpc_shutdown_client(clnt); +			return ERR_PTR(err); +		}  	}  	clnt->cl_softrtry = 1; @@ -1065,10 +1072,13 @@ rpc_task_get_next_xprt(struct rpc_clnt *clnt)  static  void rpc_task_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)  { -	if (task->tk_xprt && -			!(test_bit(XPRT_OFFLINE, &task->tk_xprt->state) && -                        (task->tk_flags & RPC_TASK_MOVEABLE))) -		return; +	if (task->tk_xprt) { +		if (!(test_bit(XPRT_OFFLINE, &task->tk_xprt->state) && +		      (task->tk_flags & RPC_TASK_MOVEABLE))) +			return; +		xprt_release(task); +		xprt_put(task->tk_xprt); +	}  	if (task->tk_flags & RPC_TASK_NO_ROUND_ROBIN)  		task->tk_xprt = rpc_task_get_first_xprt(clnt);  	else @@ -2706,6 +2716,10 @@ static const struct rpc_procinfo rpcproc_null = {  	.p_decode = rpcproc_decode_null,  }; +static const struct rpc_procinfo rpcproc_null_noreply = { +	.p_encode = rpcproc_encode_null, +}; +  static void  rpc_null_call_prepare(struct rpc_task *task, void *data)  { @@ -2759,6 +2773,28 @@ static int rpc_ping(struct rpc_clnt *clnt)  	return status;  } +static int rpc_ping_noreply(struct rpc_clnt *clnt) +{ +	struct rpc_message msg = { +		.rpc_proc = &rpcproc_null_noreply, +	}; +	struct rpc_task_setup task_setup_data = { +		.rpc_client = clnt, +		.rpc_message = &msg, +		.callback_ops = &rpc_null_ops, +		.flags = RPC_TASK_SOFT | RPC_TASK_SOFTCONN | RPC_TASK_NULLCREDS, +	}; +	struct rpc_task	*task; +	int status; + +	task = rpc_run_task(&task_setup_data); +	if (IS_ERR(task)) +		return PTR_ERR(task); +	status = task->tk_status; +	rpc_put_task(task); +	return status; +} +  struct rpc_cb_add_xprt_calldata {  	struct rpc_xprt_switch *xps;  	struct rpc_xprt *xprt;  | 
