diff options
author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2019-08-15 17:26:17 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-09-06 10:23:47 +0200 |
commit | 839e96131567369c509d4c8955686ed6558b88f7 (patch) | |
tree | f1c85867c4972bb0ee5ffae96470ce9c26c092d5 | |
parent | 90ff6dd4ced610dac6c32dbeaa3899aead7b2908 (diff) | |
download | linux-stable-839e96131567369c509d4c8955686ed6558b88f7.tar.gz linux-stable-839e96131567369c509d4c8955686ed6558b88f7.tar.bz2 linux-stable-839e96131567369c509d4c8955686ed6558b88f7.zip |
SUNRPC: Don't handle errors if the bind/connect succeeded
commit bd736ed3e2d1088d9b4050f727342e1e619c3841 upstream.
Don't handle errors in call_bind_status()/call_connect_status()
if it turns out that a previous call caused it to succeed.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Cc: stable@vger.kernel.org # v5.1+
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | net/sunrpc/clnt.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 9e1743b364ec..a680d28c231e 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1893,6 +1893,7 @@ call_bind(struct rpc_task *task) static void call_bind_status(struct rpc_task *task) { + struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; int status = -EIO; if (rpc_task_transmitted(task)) { @@ -1900,14 +1901,15 @@ call_bind_status(struct rpc_task *task) return; } - if (task->tk_status >= 0) { - dprint_status(task); + dprint_status(task); + trace_rpc_bind_status(task); + if (task->tk_status >= 0) + goto out_next; + if (xprt_bound(xprt)) { task->tk_status = 0; - task->tk_action = call_connect; - return; + goto out_next; } - trace_rpc_bind_status(task); switch (task->tk_status) { case -ENOMEM: dprintk("RPC: %5u rpcbind out of memory\n", task->tk_pid); @@ -1966,7 +1968,9 @@ call_bind_status(struct rpc_task *task) rpc_call_rpcerror(task, status); return; - +out_next: + task->tk_action = call_connect; + return; retry_timeout: task->tk_status = 0; task->tk_action = call_bind; @@ -2013,6 +2017,7 @@ call_connect(struct rpc_task *task) static void call_connect_status(struct rpc_task *task) { + struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt; struct rpc_clnt *clnt = task->tk_client; int status = task->tk_status; @@ -2022,8 +2027,17 @@ call_connect_status(struct rpc_task *task) } dprint_status(task); - trace_rpc_connect_status(task); + + if (task->tk_status == 0) { + clnt->cl_stats->netreconn++; + goto out_next; + } + if (xprt_connected(xprt)) { + task->tk_status = 0; + goto out_next; + } + task->tk_status = 0; switch (status) { case -ECONNREFUSED: @@ -2054,13 +2068,12 @@ call_connect_status(struct rpc_task *task) case -EAGAIN: case -ETIMEDOUT: goto out_retry; - case 0: - clnt->cl_stats->netreconn++; - task->tk_action = call_transmit; - return; } rpc_call_rpcerror(task, status); return; +out_next: + task->tk_action = call_transmit; + return; out_retry: /* Check for timeouts before looping back to call_bind */ task->tk_action = call_bind; |