From: Trond Myklebust Date: Sun, 21 Dec 2008 13:18:01 -0500 SUNRPC: Defer the call to rpcauth_bindcred() When we introduce filesyste migration, we're going to have to be able to block RPC new calls while we're replumbing the rpc_clnt. When we release them, the credential cache may have been changed too, so we shouldn't bind the creds until right when the RPC call is starting. Signed-off-by: Trond Myklebust --- net/sunrpc/clnt.c | 30 ++++++++++++++++++++++++++---- 1 files changed, 26 insertions(+), 4 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 5e74fa5..dbe8952 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -56,6 +56,7 @@ static DECLARE_WAIT_QUEUE_HEAD(destroy_wait); static void call_start(struct rpc_task *task); +static void call_restart(struct rpc_task *task); static void call_reserve(struct rpc_task *task); static void call_reserveresult(struct rpc_task *task); static void call_allocate(struct rpc_task *task); @@ -568,8 +569,8 @@ rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg) task->tk_msg.rpc_proc = msg->rpc_proc; task->tk_msg.rpc_argp = msg->rpc_argp; task->tk_msg.rpc_resp = msg->rpc_resp; - /* Bind the user cred */ - task->tk_status = rpcauth_bindcred(task, msg->rpc_cred, task->tk_flags); + if (msg->rpc_cred != NULL) + task->tk_msg.rpc_cred = get_rpccred(msg->rpc_cred); } } @@ -769,7 +770,7 @@ rpc_restart_call(struct rpc_task *task) if (RPC_ASSASSINATED(task)) return; - task->tk_action = call_start; + task->tk_action = call_restart; } EXPORT_SYMBOL_GPL(rpc_restart_call); @@ -795,7 +796,7 @@ static const char *rpc_proc_name(const struct rpc_task *task) * this state is visited exactly once for each RPC. */ static void -call_start(struct rpc_task *task) +call_do_start(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; @@ -810,6 +811,27 @@ call_start(struct rpc_task *task) task->tk_action = call_reserve; } +static void +call_start(struct rpc_task *task) +{ + int status = task->tk_status; + + /* Bind the user cred */ + if (status == 0) + status = rpcauth_bindcred(task, task->tk_msg.rpc_cred, task->tk_flags); + if (status != 0) { + rpc_exit(task, status); + return; + } + call_do_start(task); +} + +static void +call_restart(struct rpc_task *task) +{ + call_do_start(task); +} + /* * 1. Reserve an RPC call slot */