diff options
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r-- | net/sunrpc/clnt.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 836f15c0c4a3..5abab094441f 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -1032,27 +1032,20 @@ call_connect_status(struct rpc_task *task) | |||
1032 | dprint_status(task); | 1032 | dprint_status(task); |
1033 | 1033 | ||
1034 | task->tk_status = 0; | 1034 | task->tk_status = 0; |
1035 | if (status >= 0) { | 1035 | if (status >= 0 || status == -EAGAIN) { |
1036 | clnt->cl_stats->netreconn++; | 1036 | clnt->cl_stats->netreconn++; |
1037 | task->tk_action = call_transmit; | 1037 | task->tk_action = call_transmit; |
1038 | return; | 1038 | return; |
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | /* Something failed: remote service port may have changed */ | ||
1042 | rpc_force_rebind(clnt); | ||
1043 | |||
1044 | switch (status) { | 1041 | switch (status) { |
1045 | case -ENOTCONN: | ||
1046 | case -EAGAIN: | ||
1047 | task->tk_action = call_bind; | ||
1048 | if (!RPC_IS_SOFT(task)) | ||
1049 | return; | ||
1050 | /* if soft mounted, test if we've timed out */ | 1042 | /* if soft mounted, test if we've timed out */ |
1051 | case -ETIMEDOUT: | 1043 | case -ETIMEDOUT: |
1052 | task->tk_action = call_timeout; | 1044 | task->tk_action = call_timeout; |
1053 | return; | 1045 | break; |
1046 | default: | ||
1047 | rpc_exit(task, -EIO); | ||
1054 | } | 1048 | } |
1055 | rpc_exit(task, -EIO); | ||
1056 | } | 1049 | } |
1057 | 1050 | ||
1058 | /* | 1051 | /* |
@@ -1105,14 +1098,26 @@ static void | |||
1105 | call_transmit_status(struct rpc_task *task) | 1098 | call_transmit_status(struct rpc_task *task) |
1106 | { | 1099 | { |
1107 | task->tk_action = call_status; | 1100 | task->tk_action = call_status; |
1108 | /* | 1101 | switch (task->tk_status) { |
1109 | * Special case: if we've been waiting on the socket's write_space() | 1102 | case -EAGAIN: |
1110 | * callback, then don't call xprt_end_transmit(). | 1103 | break; |
1111 | */ | 1104 | default: |
1112 | if (task->tk_status == -EAGAIN) | 1105 | xprt_end_transmit(task); |
1113 | return; | 1106 | /* |
1114 | xprt_end_transmit(task); | 1107 | * Special cases: if we've been waiting on the |
1115 | rpc_task_force_reencode(task); | 1108 | * socket's write_space() callback, or if the |
1109 | * socket just returned a connection error, | ||
1110 | * then hold onto the transport lock. | ||
1111 | */ | ||
1112 | case -ECONNREFUSED: | ||
1113 | case -ECONNRESET: | ||
1114 | case -ENOTCONN: | ||
1115 | case -EHOSTDOWN: | ||
1116 | case -EHOSTUNREACH: | ||
1117 | case -ENETUNREACH: | ||
1118 | case -EPIPE: | ||
1119 | rpc_task_force_reencode(task); | ||
1120 | } | ||
1116 | } | 1121 | } |
1117 | 1122 | ||
1118 | /* | 1123 | /* |
@@ -1152,9 +1157,12 @@ call_status(struct rpc_task *task) | |||
1152 | xprt_conditional_disconnect(task->tk_xprt, | 1157 | xprt_conditional_disconnect(task->tk_xprt, |
1153 | req->rq_connect_cookie); | 1158 | req->rq_connect_cookie); |
1154 | break; | 1159 | break; |
1160 | case -ECONNRESET: | ||
1155 | case -ECONNREFUSED: | 1161 | case -ECONNREFUSED: |
1156 | case -ENOTCONN: | ||
1157 | rpc_force_rebind(clnt); | 1162 | rpc_force_rebind(clnt); |
1163 | rpc_delay(task, 3*HZ); | ||
1164 | case -EPIPE: | ||
1165 | case -ENOTCONN: | ||
1158 | task->tk_action = call_bind; | 1166 | task->tk_action = call_bind; |
1159 | break; | 1167 | break; |
1160 | case -EAGAIN: | 1168 | case -EAGAIN: |