diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-03-11 14:38:00 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-03-11 14:38:00 -0400 |
commit | 482f32e65d31cbf88d08306fa5d397cc945c3c26 (patch) | |
tree | e0a8adf7925ecfce413506b68d67a94f6c1b1131 /net/sunrpc | |
parent | c8485e4d634f6df155040293928707f127f0d06d (diff) |
SUNRPC: Handle socket errors correctly
Ensure that we pick up and handle socket errors as they occur.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/xprtsock.c | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 5e8198bede81..879af6f27b4c 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1208,23 +1208,20 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1208 | } | 1208 | } |
1209 | 1209 | ||
1210 | /** | 1210 | /** |
1211 | * xs_tcp_error_report - callback mainly for catching RST events | 1211 | * xs_error_report - callback mainly for catching socket errors |
1212 | * @sk: socket | 1212 | * @sk: socket |
1213 | */ | 1213 | */ |
1214 | static void xs_tcp_error_report(struct sock *sk) | 1214 | static void xs_error_report(struct sock *sk) |
1215 | { | 1215 | { |
1216 | struct rpc_xprt *xprt; | 1216 | struct rpc_xprt *xprt; |
1217 | 1217 | ||
1218 | read_lock(&sk->sk_callback_lock); | 1218 | read_lock(&sk->sk_callback_lock); |
1219 | if (sk->sk_err != ECONNRESET || sk->sk_state != TCP_ESTABLISHED) | ||
1220 | goto out; | ||
1221 | if (!(xprt = xprt_from_sock(sk))) | 1219 | if (!(xprt = xprt_from_sock(sk))) |
1222 | goto out; | 1220 | goto out; |
1223 | dprintk("RPC: %s client %p...\n" | 1221 | dprintk("RPC: %s client %p...\n" |
1224 | "RPC: error %d\n", | 1222 | "RPC: error %d\n", |
1225 | __func__, xprt, sk->sk_err); | 1223 | __func__, xprt, sk->sk_err); |
1226 | 1224 | xprt_wake_pending_tasks(xprt, -EAGAIN); | |
1227 | xprt_force_disconnect(xprt); | ||
1228 | out: | 1225 | out: |
1229 | read_unlock(&sk->sk_callback_lock); | 1226 | read_unlock(&sk->sk_callback_lock); |
1230 | } | 1227 | } |
@@ -1509,6 +1506,7 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
1509 | sk->sk_user_data = xprt; | 1506 | sk->sk_user_data = xprt; |
1510 | sk->sk_data_ready = xs_udp_data_ready; | 1507 | sk->sk_data_ready = xs_udp_data_ready; |
1511 | sk->sk_write_space = xs_udp_write_space; | 1508 | sk->sk_write_space = xs_udp_write_space; |
1509 | sk->sk_error_report = xs_error_report; | ||
1512 | sk->sk_no_check = UDP_CSUM_NORCV; | 1510 | sk->sk_no_check = UDP_CSUM_NORCV; |
1513 | sk->sk_allocation = GFP_ATOMIC; | 1511 | sk->sk_allocation = GFP_ATOMIC; |
1514 | 1512 | ||
@@ -1656,7 +1654,7 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
1656 | sk->sk_data_ready = xs_tcp_data_ready; | 1654 | sk->sk_data_ready = xs_tcp_data_ready; |
1657 | sk->sk_state_change = xs_tcp_state_change; | 1655 | sk->sk_state_change = xs_tcp_state_change; |
1658 | sk->sk_write_space = xs_tcp_write_space; | 1656 | sk->sk_write_space = xs_tcp_write_space; |
1659 | sk->sk_error_report = xs_tcp_error_report; | 1657 | sk->sk_error_report = xs_error_report; |
1660 | sk->sk_allocation = GFP_ATOMIC; | 1658 | sk->sk_allocation = GFP_ATOMIC; |
1661 | 1659 | ||
1662 | /* socket options */ | 1660 | /* socket options */ |