summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-03-04 17:29:33 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-03-25 12:04:10 -0400
commit3ed5e2a2c394df4e03a680842c2d07a8680f133b (patch)
tree83050928d116f2079147f6de8c77860a4ec76f27
parent1166fde6a923c30f4351515b6a9a1efc513e7d00 (diff)
downloadlinux-3ed5e2a2c394df4e03a680842c2d07a8680f133b.tar.bz2
SUNRPC: Report network/connection errors correctly for SOFTCONN rpc tasks
In the case of a SOFTCONN rpc task, we really want to ensure that it reports errors like ENETUNREACH back to the caller. Currently, only some of these errors are being reported back (connect errors are not), and they are being converted by the RPC layer into EIO. Reported-by: Jan Engelhardt <jengelh@inai.de> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--net/sunrpc/clnt.c24
-rw-r--r--net/sunrpc/xprtsock.c8
2 files changed, 18 insertions, 14 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index dcc446e7fbf6..b95a0a2d5eea 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1644,22 +1644,26 @@ call_connect_status(struct rpc_task *task)
dprint_status(task);
- task->tk_status = 0;
- if (status >= 0 || status == -EAGAIN) {
- clnt->cl_stats->netreconn++;
- task->tk_action = call_transmit;
- return;
- }
-
trace_rpc_connect_status(task, status);
switch (status) {
/* if soft mounted, test if we've timed out */
case -ETIMEDOUT:
task->tk_action = call_timeout;
- break;
- default:
- rpc_exit(task, -EIO);
+ return;
+ case -ECONNREFUSED:
+ case -ECONNRESET:
+ case -ENETUNREACH:
+ if (RPC_IS_SOFTCONN(task))
+ break;
+ /* retry with existing socket, after a delay */
+ case 0:
+ case -EAGAIN:
+ task->tk_status = 0;
+ clnt->cl_stats->netreconn++;
+ task->tk_action = call_transmit;
+ return;
}
+ rpc_exit(task, status);
}
/*
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index c1d8476b7692..3081620cb02c 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2202,10 +2202,6 @@ static void xs_tcp_setup_socket(struct work_struct *work)
*/
xs_tcp_force_close(xprt);
break;
- case -ECONNREFUSED:
- case -ECONNRESET:
- case -ENETUNREACH:
- /* retry with existing socket, after a delay */
case 0:
case -EINPROGRESS:
case -EALREADY:
@@ -2216,6 +2212,10 @@ static void xs_tcp_setup_socket(struct work_struct *work)
/* Happens, for instance, if the user specified a link
* local IPv6 address without a scope-id.
*/
+ case -ECONNREFUSED:
+ case -ECONNRESET:
+ case -ENETUNREACH:
+ /* retry with existing socket, after a delay */
goto out;
}
out_eagain: