mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-02 08:34:20 +08:00
SUNRPC: Respect RPC call timeouts when retrying transmission
Fix a regression where soft and softconn requests are not timing out
as expected.
Fixes: 89f90fe1ad
("SUNRPC: Allow calls to xprt_transmit() to drain...")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
parent
477687e111
commit
7b3fef8e41
@ -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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 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)
|
|||||||
* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user