diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-05-19 12:12:53 -0400 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2012-06-10 14:41:32 +0100 |
commit | b35e0437787ca030484a278d052d3aada0bb9947 (patch) | |
tree | a45910983f27a3d0f7649635a7287a12bc416c98 /net/sunrpc | |
parent | 90f560e0729cc5483324673cb13522b8abcd8ca5 (diff) |
sunrpc: fix loss of task->tk_status after rpc_delay call in xprt_alloc_slot
commit 1afeaf5c29aa07db25760d2fbed5c08a3aec3498 upstream.
xprt_alloc_slot will call rpc_delay() to make the task wait a bit before
retrying when it gets back an -ENOMEM error from xprt_dynamic_alloc_slot.
The problem is that rpc_delay will clear the task->tk_status, causing
call_reserveresult to abort the task.
The solution is simply to let call_reserveresult handle the ENOMEM error
directly.
Reported-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/clnt.c | 2 | ||||
-rw-r--r-- | net/sunrpc/xprt.c | 5 |
2 files changed, 5 insertions, 2 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index f0268ea7e71..b2250da4b59 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -959,6 +959,8 @@ call_reserveresult(struct rpc_task *task) } switch (status) { + case -ENOMEM: + rpc_delay(task, HZ >> 2); case -EAGAIN: /* woken up; retry */ task->tk_action = call_reserve; return; diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index c64c0ef519b..3ac978989da 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -977,15 +977,16 @@ static void xprt_alloc_slot(struct rpc_task *task) goto out_init_req; switch (PTR_ERR(req)) { case -ENOMEM: - rpc_delay(task, HZ >> 2); dprintk("RPC: dynamic allocation of request slot " "failed! Retrying\n"); + task->tk_status = -ENOMEM; break; case -EAGAIN: rpc_sleep_on(&xprt->backlog, task, NULL); dprintk("RPC: waiting for request slot\n"); + default: + task->tk_status = -EAGAIN; } - task->tk_status = -EAGAIN; return; out_init_req: task->tk_status = 0; |