diff options
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 49a62f0c4b87..fe9306bf10cc 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -800,7 +800,7 @@ static void xs_udp_data_ready(struct sock *sk, int len) | |||
800 | u32 _xid; | 800 | u32 _xid; |
801 | __be32 *xp; | 801 | __be32 *xp; |
802 | 802 | ||
803 | read_lock(&sk->sk_callback_lock); | 803 | read_lock_bh(&sk->sk_callback_lock); |
804 | dprintk("RPC: xs_udp_data_ready...\n"); | 804 | dprintk("RPC: xs_udp_data_ready...\n"); |
805 | if (!(xprt = xprt_from_sock(sk))) | 805 | if (!(xprt = xprt_from_sock(sk))) |
806 | goto out; | 806 | goto out; |
@@ -852,7 +852,7 @@ static void xs_udp_data_ready(struct sock *sk, int len) | |||
852 | dropit: | 852 | dropit: |
853 | skb_free_datagram(sk, skb); | 853 | skb_free_datagram(sk, skb); |
854 | out: | 854 | out: |
855 | read_unlock(&sk->sk_callback_lock); | 855 | read_unlock_bh(&sk->sk_callback_lock); |
856 | } | 856 | } |
857 | 857 | ||
858 | static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc) | 858 | static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc) |
@@ -1229,7 +1229,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) | |||
1229 | 1229 | ||
1230 | dprintk("RPC: xs_tcp_data_ready...\n"); | 1230 | dprintk("RPC: xs_tcp_data_ready...\n"); |
1231 | 1231 | ||
1232 | read_lock(&sk->sk_callback_lock); | 1232 | read_lock_bh(&sk->sk_callback_lock); |
1233 | if (!(xprt = xprt_from_sock(sk))) | 1233 | if (!(xprt = xprt_from_sock(sk))) |
1234 | goto out; | 1234 | goto out; |
1235 | if (xprt->shutdown) | 1235 | if (xprt->shutdown) |
@@ -1248,7 +1248,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) | |||
1248 | read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); | 1248 | read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); |
1249 | } while (read > 0); | 1249 | } while (read > 0); |
1250 | out: | 1250 | out: |
1251 | read_unlock(&sk->sk_callback_lock); | 1251 | read_unlock_bh(&sk->sk_callback_lock); |
1252 | } | 1252 | } |
1253 | 1253 | ||
1254 | /* | 1254 | /* |
@@ -1301,18 +1301,19 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1301 | { | 1301 | { |
1302 | struct rpc_xprt *xprt; | 1302 | struct rpc_xprt *xprt; |
1303 | 1303 | ||
1304 | read_lock(&sk->sk_callback_lock); | 1304 | read_lock_bh(&sk->sk_callback_lock); |
1305 | if (!(xprt = xprt_from_sock(sk))) | 1305 | if (!(xprt = xprt_from_sock(sk))) |
1306 | goto out; | 1306 | goto out; |
1307 | dprintk("RPC: xs_tcp_state_change client %p...\n", xprt); | 1307 | dprintk("RPC: xs_tcp_state_change client %p...\n", xprt); |
1308 | dprintk("RPC: state %x conn %d dead %d zapped %d\n", | 1308 | dprintk("RPC: state %x conn %d dead %d zapped %d sk_shutdown %d\n", |
1309 | sk->sk_state, xprt_connected(xprt), | 1309 | sk->sk_state, xprt_connected(xprt), |
1310 | sock_flag(sk, SOCK_DEAD), | 1310 | sock_flag(sk, SOCK_DEAD), |
1311 | sock_flag(sk, SOCK_ZAPPED)); | 1311 | sock_flag(sk, SOCK_ZAPPED), |
1312 | sk->sk_shutdown); | ||
1312 | 1313 | ||
1313 | switch (sk->sk_state) { | 1314 | switch (sk->sk_state) { |
1314 | case TCP_ESTABLISHED: | 1315 | case TCP_ESTABLISHED: |
1315 | spin_lock_bh(&xprt->transport_lock); | 1316 | spin_lock(&xprt->transport_lock); |
1316 | if (!xprt_test_and_set_connected(xprt)) { | 1317 | if (!xprt_test_and_set_connected(xprt)) { |
1317 | struct sock_xprt *transport = container_of(xprt, | 1318 | struct sock_xprt *transport = container_of(xprt, |
1318 | struct sock_xprt, xprt); | 1319 | struct sock_xprt, xprt); |
@@ -1326,7 +1327,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1326 | 1327 | ||
1327 | xprt_wake_pending_tasks(xprt, -EAGAIN); | 1328 | xprt_wake_pending_tasks(xprt, -EAGAIN); |
1328 | } | 1329 | } |
1329 | spin_unlock_bh(&xprt->transport_lock); | 1330 | spin_unlock(&xprt->transport_lock); |
1330 | break; | 1331 | break; |
1331 | case TCP_FIN_WAIT1: | 1332 | case TCP_FIN_WAIT1: |
1332 | /* The client initiated a shutdown of the socket */ | 1333 | /* The client initiated a shutdown of the socket */ |
@@ -1364,7 +1365,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1364 | xs_sock_mark_closed(xprt); | 1365 | xs_sock_mark_closed(xprt); |
1365 | } | 1366 | } |
1366 | out: | 1367 | out: |
1367 | read_unlock(&sk->sk_callback_lock); | 1368 | read_unlock_bh(&sk->sk_callback_lock); |
1368 | } | 1369 | } |
1369 | 1370 | ||
1370 | /** | 1371 | /** |
@@ -1375,7 +1376,7 @@ static void xs_error_report(struct sock *sk) | |||
1375 | { | 1376 | { |
1376 | struct rpc_xprt *xprt; | 1377 | struct rpc_xprt *xprt; |
1377 | 1378 | ||
1378 | read_lock(&sk->sk_callback_lock); | 1379 | read_lock_bh(&sk->sk_callback_lock); |
1379 | if (!(xprt = xprt_from_sock(sk))) | 1380 | if (!(xprt = xprt_from_sock(sk))) |
1380 | goto out; | 1381 | goto out; |
1381 | dprintk("RPC: %s client %p...\n" | 1382 | dprintk("RPC: %s client %p...\n" |
@@ -1383,7 +1384,7 @@ static void xs_error_report(struct sock *sk) | |||
1383 | __func__, xprt, sk->sk_err); | 1384 | __func__, xprt, sk->sk_err); |
1384 | xprt_wake_pending_tasks(xprt, -EAGAIN); | 1385 | xprt_wake_pending_tasks(xprt, -EAGAIN); |
1385 | out: | 1386 | out: |
1386 | read_unlock(&sk->sk_callback_lock); | 1387 | read_unlock_bh(&sk->sk_callback_lock); |
1387 | } | 1388 | } |
1388 | 1389 | ||
1389 | static void xs_write_space(struct sock *sk) | 1390 | static void xs_write_space(struct sock *sk) |
@@ -1415,13 +1416,13 @@ static void xs_write_space(struct sock *sk) | |||
1415 | */ | 1416 | */ |
1416 | static void xs_udp_write_space(struct sock *sk) | 1417 | static void xs_udp_write_space(struct sock *sk) |
1417 | { | 1418 | { |
1418 | read_lock(&sk->sk_callback_lock); | 1419 | read_lock_bh(&sk->sk_callback_lock); |
1419 | 1420 | ||
1420 | /* from net/core/sock.c:sock_def_write_space */ | 1421 | /* from net/core/sock.c:sock_def_write_space */ |
1421 | if (sock_writeable(sk)) | 1422 | if (sock_writeable(sk)) |
1422 | xs_write_space(sk); | 1423 | xs_write_space(sk); |
1423 | 1424 | ||
1424 | read_unlock(&sk->sk_callback_lock); | 1425 | read_unlock_bh(&sk->sk_callback_lock); |
1425 | } | 1426 | } |
1426 | 1427 | ||
1427 | /** | 1428 | /** |
@@ -1436,13 +1437,13 @@ static void xs_udp_write_space(struct sock *sk) | |||
1436 | */ | 1437 | */ |
1437 | static void xs_tcp_write_space(struct sock *sk) | 1438 | static void xs_tcp_write_space(struct sock *sk) |
1438 | { | 1439 | { |
1439 | read_lock(&sk->sk_callback_lock); | 1440 | read_lock_bh(&sk->sk_callback_lock); |
1440 | 1441 | ||
1441 | /* from net/core/stream.c:sk_stream_write_space */ | 1442 | /* from net/core/stream.c:sk_stream_write_space */ |
1442 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) | 1443 | if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) |
1443 | xs_write_space(sk); | 1444 | xs_write_space(sk); |
1444 | 1445 | ||
1445 | read_unlock(&sk->sk_callback_lock); | 1446 | read_unlock_bh(&sk->sk_callback_lock); |
1446 | } | 1447 | } |
1447 | 1448 | ||
1448 | static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) | 1449 | static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) |
@@ -1779,10 +1780,25 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt, struct sock_xprt *tra | |||
1779 | { | 1780 | { |
1780 | unsigned int state = transport->inet->sk_state; | 1781 | unsigned int state = transport->inet->sk_state; |
1781 | 1782 | ||
1782 | if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED) | 1783 | if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED) { |
1783 | return; | 1784 | /* we don't need to abort the connection if the socket |
1784 | if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT)) | 1785 | * hasn't undergone a shutdown |
1785 | return; | 1786 | */ |
1787 | if (transport->inet->sk_shutdown == 0) | ||
1788 | return; | ||
1789 | dprintk("RPC: %s: TCP_CLOSEd and sk_shutdown set to %d\n", | ||
1790 | __func__, transport->inet->sk_shutdown); | ||
1791 | } | ||
1792 | if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT)) { | ||
1793 | /* we don't need to abort the connection if the socket | ||
1794 | * hasn't undergone a shutdown | ||
1795 | */ | ||
1796 | if (transport->inet->sk_shutdown == 0) | ||
1797 | return; | ||
1798 | dprintk("RPC: %s: ESTABLISHED/SYN_SENT " | ||
1799 | "sk_shutdown set to %d\n", | ||
1800 | __func__, transport->inet->sk_shutdown); | ||
1801 | } | ||
1786 | xs_abort_connection(xprt, transport); | 1802 | xs_abort_connection(xprt, transport); |
1787 | } | 1803 | } |
1788 | 1804 | ||