Commit 7b3fef8e authored by Trond Myklebust's avatar Trond Myklebust

SUNRPC: Respect RPC call timeouts when retrying transmission

Fix a regression where soft and softconn requests are not timing out
as expected.

Fixes: 89f90fe1 ("SUNRPC: Allow calls to xprt_transmit() to drain...")
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 477687e1
...@@ -79,6 +79,7 @@ static int rpc_encode_header(struct rpc_task *task, ...@@ -79,6 +79,7 @@ static int rpc_encode_header(struct rpc_task *task,
static int rpc_decode_header(struct rpc_task *task, static int rpc_decode_header(struct rpc_task *task,
struct xdr_stream *xdr); struct xdr_stream *xdr);
static int rpc_ping(struct rpc_clnt *clnt); static int rpc_ping(struct rpc_clnt *clnt);
static void rpc_check_timeout(struct rpc_task *task);
static void rpc_register_client(struct rpc_clnt *clnt) static void rpc_register_client(struct rpc_clnt *clnt)
{ {
...@@ -1962,8 +1963,7 @@ call_connect_status(struct rpc_task *task) ...@@ -1962,8 +1963,7 @@ call_connect_status(struct rpc_task *task)
break; break;
if (clnt->cl_autobind) { if (clnt->cl_autobind) {
rpc_force_rebind(clnt); rpc_force_rebind(clnt);
task->tk_action = call_bind; goto out_retry;
return;
} }
/* fall through */ /* fall through */
case -ECONNRESET: case -ECONNRESET:
...@@ -1983,16 +1983,19 @@ call_connect_status(struct rpc_task *task) ...@@ -1983,16 +1983,19 @@ call_connect_status(struct rpc_task *task)
/* fall through */ /* fall through */
case -ENOTCONN: case -ENOTCONN:
case -EAGAIN: case -EAGAIN:
/* Check for timeouts before looping back to call_bind */
case -ETIMEDOUT: case -ETIMEDOUT:
task->tk_action = call_timeout; goto out_retry;
return;
case 0: case 0:
clnt->cl_stats->netreconn++; clnt->cl_stats->netreconn++;
task->tk_action = call_transmit; task->tk_action = call_transmit;
return; return;
} }
rpc_exit(task, status); rpc_exit(task, status);
return;
out_retry:
/* Check for timeouts before looping back to call_bind */
task->tk_action = call_bind;
rpc_check_timeout(task);
} }
/* /*
...@@ -2069,7 +2072,7 @@ call_transmit_status(struct rpc_task *task) ...@@ -2069,7 +2072,7 @@ call_transmit_status(struct rpc_task *task)
trace_xprt_ping(task->tk_xprt, trace_xprt_ping(task->tk_xprt,
task->tk_status); task->tk_status);
rpc_exit(task, task->tk_status); rpc_exit(task, task->tk_status);
break; return;
} }
/* fall through */ /* fall through */
case -ECONNRESET: case -ECONNRESET:
...@@ -2081,6 +2084,7 @@ call_transmit_status(struct rpc_task *task) ...@@ -2081,6 +2084,7 @@ call_transmit_status(struct rpc_task *task)
task->tk_status = 0; task->tk_status = 0;
break; break;
} }
rpc_check_timeout(task);
} }
#if defined(CONFIG_SUNRPC_BACKCHANNEL) #if defined(CONFIG_SUNRPC_BACKCHANNEL)
...@@ -2217,7 +2221,7 @@ call_status(struct rpc_task *task) ...@@ -2217,7 +2221,7 @@ call_status(struct rpc_task *task)
case -EPIPE: case -EPIPE:
case -ENOTCONN: case -ENOTCONN:
case -EAGAIN: case -EAGAIN:
task->tk_action = call_encode; task->tk_action = call_timeout;
break; break;
case -EIO: case -EIO:
/* shutdown or soft timeout */ /* shutdown or soft timeout */
...@@ -2231,20 +2235,13 @@ call_status(struct rpc_task *task) ...@@ -2231,20 +2235,13 @@ call_status(struct rpc_task *task)
} }
} }
/*
* 6a. Handle RPC timeout
* We do not release the request slot, so we keep using the
* same XID for all retransmits.
*/
static void static void
call_timeout(struct rpc_task *task) rpc_check_timeout(struct rpc_task *task)
{ {
struct rpc_clnt *clnt = task->tk_client; struct rpc_clnt *clnt = task->tk_client;
if (xprt_adjust_timeout(task->tk_rqstp) == 0) { if (xprt_adjust_timeout(task->tk_rqstp) == 0)
dprintk("RPC: %5u call_timeout (minor)\n", task->tk_pid); return;
goto retry;
}
dprintk("RPC: %5u call_timeout (major)\n", task->tk_pid); dprintk("RPC: %5u call_timeout (major)\n", task->tk_pid);
task->tk_timeouts++; task->tk_timeouts++;
...@@ -2280,10 +2277,19 @@ call_timeout(struct rpc_task *task) ...@@ -2280,10 +2277,19 @@ call_timeout(struct rpc_task *task)
* event? RFC2203 requires the server to drop all such requests. * event? RFC2203 requires the server to drop all such requests.
*/ */
rpcauth_invalcred(task); rpcauth_invalcred(task);
}
retry: /*
* 6a. Handle RPC timeout
* We do not release the request slot, so we keep using the
* same XID for all retransmits.
*/
static void
call_timeout(struct rpc_task *task)
{
task->tk_action = call_encode; task->tk_action = call_encode;
task->tk_status = 0; task->tk_status = 0;
rpc_check_timeout(task);
} }
/* /*
......
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