Skip to content

Commit 03e51d3

Browse files
author
Trond Myklebust
committed
SUNRPC: Check whether the task was transmitted before rebind/reconnect
Before initiating transport actions that require putting the task to sleep, such as rebinding or reconnecting, we should check whether or not the task was already transmitted. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
1 parent 6b5f590 commit 03e51d3

File tree

1 file changed

+40
-4
lines changed

1 file changed

+40
-4
lines changed

net/sunrpc/clnt.c

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,24 @@ call_encode(struct rpc_task *task)
18111811
task->tk_action = call_connect;
18121812
}
18131813

1814+
/*
1815+
* Helpers to check if the task was already transmitted, and
1816+
* to take action when that is the case.
1817+
*/
1818+
static bool
1819+
rpc_task_transmitted(struct rpc_task *task)
1820+
{
1821+
return !test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate);
1822+
}
1823+
1824+
static void
1825+
rpc_task_handle_transmitted(struct rpc_task *task)
1826+
{
1827+
xprt_end_transmit(task);
1828+
task->tk_action = call_transmit_status;
1829+
call_transmit_status(task);
1830+
}
1831+
18141832
/*
18151833
* 4. Get the server port number if not yet set
18161834
*/
@@ -1819,6 +1837,11 @@ call_bind(struct rpc_task *task)
18191837
{
18201838
struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt;
18211839

1840+
if (rpc_task_transmitted(task)) {
1841+
rpc_task_handle_transmitted(task);
1842+
return;
1843+
}
1844+
18221845
dprint_status(task);
18231846

18241847
task->tk_action = call_connect;
@@ -1837,6 +1860,11 @@ call_bind_status(struct rpc_task *task)
18371860
{
18381861
int status = -EIO;
18391862

1863+
if (rpc_task_transmitted(task)) {
1864+
rpc_task_handle_transmitted(task);
1865+
return;
1866+
}
1867+
18401868
if (task->tk_status >= 0) {
18411869
dprint_status(task);
18421870
task->tk_status = 0;
@@ -1916,6 +1944,11 @@ call_connect(struct rpc_task *task)
19161944
{
19171945
struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt;
19181946

1947+
if (rpc_task_transmitted(task)) {
1948+
rpc_task_handle_transmitted(task);
1949+
return;
1950+
}
1951+
19191952
dprintk("RPC: %5u call_connect xprt %p %s connected\n",
19201953
task->tk_pid, xprt,
19211954
(xprt_connected(xprt) ? "is" : "is not"));
@@ -1942,10 +1975,8 @@ call_connect_status(struct rpc_task *task)
19421975
struct rpc_clnt *clnt = task->tk_client;
19431976
int status = task->tk_status;
19441977

1945-
/* Check if the task was already transmitted */
1946-
if (!test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) {
1947-
xprt_end_transmit(task);
1948-
task->tk_action = call_transmit_status;
1978+
if (rpc_task_transmitted(task)) {
1979+
rpc_task_handle_transmitted(task);
19491980
return;
19501981
}
19511982

@@ -2001,6 +2032,11 @@ call_connect_status(struct rpc_task *task)
20012032
static void
20022033
call_transmit(struct rpc_task *task)
20032034
{
2035+
if (rpc_task_transmitted(task)) {
2036+
rpc_task_handle_transmitted(task);
2037+
return;
2038+
}
2039+
20042040
dprint_status(task);
20052041

20062042
task->tk_action = call_transmit_status;

0 commit comments

Comments
 (0)