Commit abbcf28f authored by Trond Myklebust's avatar Trond Myklebust

SUNRPC: Yet more RPC cleanups

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent abd3e641
...@@ -233,6 +233,7 @@ struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent); ...@@ -233,6 +233,7 @@ struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent);
void rpc_init_task(struct rpc_task *, struct rpc_clnt *, void rpc_init_task(struct rpc_task *, struct rpc_clnt *,
rpc_action exitfunc, int flags); rpc_action exitfunc, int flags);
void rpc_release_task(struct rpc_task *); void rpc_release_task(struct rpc_task *);
void rpc_exit_task(struct rpc_task *);
void rpc_killall_tasks(struct rpc_clnt *); void rpc_killall_tasks(struct rpc_clnt *);
int rpc_execute(struct rpc_task *); int rpc_execute(struct rpc_task *);
void rpc_run_child(struct rpc_task *parent, struct rpc_task *child, void rpc_run_child(struct rpc_task *parent, struct rpc_task *child,
...@@ -259,7 +260,7 @@ void rpc_destroy_mempool(void); ...@@ -259,7 +260,7 @@ void rpc_destroy_mempool(void);
static inline void rpc_exit(struct rpc_task *task, int status) static inline void rpc_exit(struct rpc_task *task, int status)
{ {
task->tk_status = status; task->tk_status = status;
task->tk_action = NULL; task->tk_action = rpc_exit_task;
} }
#ifdef RPC_DEBUG #ifdef RPC_DEBUG
......
...@@ -511,7 +511,7 @@ rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags) ...@@ -511,7 +511,7 @@ rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags)
if (task->tk_status == 0) if (task->tk_status == 0)
task->tk_action = call_start; task->tk_action = call_start;
else else
task->tk_action = NULL; task->tk_action = rpc_exit_task;
} }
void void
...@@ -892,7 +892,7 @@ call_transmit(struct rpc_task *task) ...@@ -892,7 +892,7 @@ call_transmit(struct rpc_task *task)
if (task->tk_status < 0) if (task->tk_status < 0)
return; return;
if (!task->tk_msg.rpc_proc->p_decode) { if (!task->tk_msg.rpc_proc->p_decode) {
task->tk_action = NULL; task->tk_action = rpc_exit_task;
rpc_wake_up_task(task); rpc_wake_up_task(task);
} }
return; return;
...@@ -1039,13 +1039,14 @@ call_decode(struct rpc_task *task) ...@@ -1039,13 +1039,14 @@ call_decode(struct rpc_task *task)
sizeof(req->rq_rcv_buf)) != 0); sizeof(req->rq_rcv_buf)) != 0);
/* Verify the RPC header */ /* Verify the RPC header */
if (!(p = call_verify(task))) { p = call_verify(task);
if (task->tk_action == NULL) if (IS_ERR(p)) {
return; if (p == ERR_PTR(-EAGAIN))
goto out_retry; goto out_retry;
return;
} }
task->tk_action = NULL; task->tk_action = rpc_exit_task;
if (decode) if (decode)
task->tk_status = rpcauth_unwrap_resp(task, decode, req, p, task->tk_status = rpcauth_unwrap_resp(task, decode, req, p,
...@@ -1138,7 +1139,7 @@ call_verify(struct rpc_task *task) ...@@ -1138,7 +1139,7 @@ call_verify(struct rpc_task *task)
if ((n = ntohl(*p++)) != RPC_REPLY) { if ((n = ntohl(*p++)) != RPC_REPLY) {
printk(KERN_WARNING "call_verify: not an RPC reply: %x\n", n); printk(KERN_WARNING "call_verify: not an RPC reply: %x\n", n);
goto out_retry; goto out_garbage;
} }
if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) { if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
if (--len < 0) if (--len < 0)
...@@ -1168,7 +1169,7 @@ call_verify(struct rpc_task *task) ...@@ -1168,7 +1169,7 @@ call_verify(struct rpc_task *task)
task->tk_pid); task->tk_pid);
rpcauth_invalcred(task); rpcauth_invalcred(task);
task->tk_action = call_refresh; task->tk_action = call_refresh;
return NULL; goto out_retry;
case RPC_AUTH_BADCRED: case RPC_AUTH_BADCRED:
case RPC_AUTH_BADVERF: case RPC_AUTH_BADVERF:
/* possibly garbled cred/verf? */ /* possibly garbled cred/verf? */
...@@ -1178,7 +1179,7 @@ call_verify(struct rpc_task *task) ...@@ -1178,7 +1179,7 @@ call_verify(struct rpc_task *task)
dprintk("RPC: %4d call_verify: retry garbled creds\n", dprintk("RPC: %4d call_verify: retry garbled creds\n",
task->tk_pid); task->tk_pid);
task->tk_action = call_bind; task->tk_action = call_bind;
return NULL; goto out_retry;
case RPC_AUTH_TOOWEAK: case RPC_AUTH_TOOWEAK:
printk(KERN_NOTICE "call_verify: server requires stronger " printk(KERN_NOTICE "call_verify: server requires stronger "
"authentication.\n"); "authentication.\n");
...@@ -1193,7 +1194,7 @@ call_verify(struct rpc_task *task) ...@@ -1193,7 +1194,7 @@ call_verify(struct rpc_task *task)
} }
if (!(p = rpcauth_checkverf(task, p))) { if (!(p = rpcauth_checkverf(task, p))) {
printk(KERN_WARNING "call_verify: auth check failed\n"); printk(KERN_WARNING "call_verify: auth check failed\n");
goto out_retry; /* bad verifier, retry */ goto out_garbage; /* bad verifier, retry */
} }
len = p - (u32 *)iov->iov_base - 1; len = p - (u32 *)iov->iov_base - 1;
if (len < 0) if (len < 0)
...@@ -1230,23 +1231,24 @@ call_verify(struct rpc_task *task) ...@@ -1230,23 +1231,24 @@ call_verify(struct rpc_task *task)
/* Also retry */ /* Also retry */
} }
out_retry: out_garbage:
task->tk_client->cl_stats->rpcgarbage++; task->tk_client->cl_stats->rpcgarbage++;
if (task->tk_garb_retry) { if (task->tk_garb_retry) {
task->tk_garb_retry--; task->tk_garb_retry--;
dprintk("RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid); dprintk("RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid);
task->tk_action = call_bind; task->tk_action = call_bind;
return NULL; out_retry:
return ERR_PTR(-EAGAIN);
} }
printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__); printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__);
out_eio: out_eio:
error = -EIO; error = -EIO;
out_err: out_err:
rpc_exit(task, error); rpc_exit(task, error);
return NULL; return ERR_PTR(error);
out_overflow: out_overflow:
printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__); printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__);
goto out_retry; goto out_garbage;
} }
static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj) static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj)
......
...@@ -90,8 +90,7 @@ rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt) ...@@ -90,8 +90,7 @@ rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt)
map->pm_binding = 0; map->pm_binding = 0;
rpc_wake_up(&map->pm_bindwait); rpc_wake_up(&map->pm_bindwait);
spin_unlock(&pmap_lock); spin_unlock(&pmap_lock);
task->tk_status = -EIO; rpc_exit(task, -EIO);
task->tk_action = NULL;
} }
#ifdef CONFIG_ROOT_NFS #ifdef CONFIG_ROOT_NFS
...@@ -138,11 +137,10 @@ pmap_getport_done(struct rpc_task *task) ...@@ -138,11 +137,10 @@ pmap_getport_done(struct rpc_task *task)
task->tk_pid, task->tk_status, clnt->cl_port); task->tk_pid, task->tk_status, clnt->cl_port);
if (task->tk_status < 0) { if (task->tk_status < 0) {
/* Make the calling task exit with an error */ /* Make the calling task exit with an error */
task->tk_action = NULL; task->tk_action = rpc_exit_task;
} else if (clnt->cl_port == 0) { } else if (clnt->cl_port == 0) {
/* Program not registered */ /* Program not registered */
task->tk_status = -EACCES; rpc_exit(task, -EACCES);
task->tk_action = NULL;
} else { } else {
/* byte-swap port number first */ /* byte-swap port number first */
clnt->cl_port = htons(clnt->cl_port); clnt->cl_port = htons(clnt->cl_port);
......
...@@ -555,28 +555,22 @@ __rpc_atrun(struct rpc_task *task) ...@@ -555,28 +555,22 @@ __rpc_atrun(struct rpc_task *task)
} }
/* /*
* Helper that calls task->tk_exit if it exists and then returns * Helper that calls task->tk_exit if it exists
* true if we should exit __rpc_execute.
*/ */
static inline int __rpc_do_exit(struct rpc_task *task) void rpc_exit_task(struct rpc_task *task)
{ {
task->tk_action = NULL;
if (task->tk_exit != NULL) { if (task->tk_exit != NULL) {
lock_kernel();
task->tk_exit(task); task->tk_exit(task);
unlock_kernel();
/* If tk_action is non-null, we should restart the call */
if (task->tk_action != NULL) { if (task->tk_action != NULL) {
if (!RPC_ASSASSINATED(task)) { WARN_ON(RPC_ASSASSINATED(task));
/* Release RPC slot and buffer memory */ /* Always release the RPC slot and buffer memory */
xprt_release(task); xprt_release(task);
rpc_free(task); rpc_free(task);
return 0;
}
printk(KERN_ERR "RPC: dead task tried to walk away.\n");
} }
} }
return 1;
} }
EXPORT_SYMBOL(rpc_exit_task);
static int rpc_wait_bit_interruptible(void *word) static int rpc_wait_bit_interruptible(void *word)
{ {
...@@ -631,12 +625,11 @@ static int __rpc_execute(struct rpc_task *task) ...@@ -631,12 +625,11 @@ static int __rpc_execute(struct rpc_task *task)
* by someone else. * by someone else.
*/ */
if (!RPC_IS_QUEUED(task)) { if (!RPC_IS_QUEUED(task)) {
if (task->tk_action != NULL) { if (task->tk_action == NULL)
lock_kernel();
task->tk_action(task);
unlock_kernel();
} else if (__rpc_do_exit(task))
break; break;
lock_kernel();
task->tk_action(task);
unlock_kernel();
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment