From: Trond Myklebust Date: Sat, 19 May 2012 16:12:53 +0000 (-0400) Subject: sunrpc: fix loss of task->tk_status after rpc_delay call in xprt_alloc_slot X-Git-Tag: v3.2.20~82 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=b35e0437787ca030484a278d052d3aada0bb9947;p=karo-tx-linux.git 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 Signed-off-by: Trond Myklebust Signed-off-by: Ben Hutchings --- diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index f0268ea7e711..b2250da4b598 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 c64c0ef519b5..3ac978989dab 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;