diff options
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 7be90bc1a7c2..1a85e0ed0b48 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -777,7 +777,6 @@ static void xs_sock_mark_closed(struct rpc_xprt *xprt) | |||
777 | xs_sock_reset_connection_flags(xprt); | 777 | xs_sock_reset_connection_flags(xprt); |
778 | /* Mark transport as closed and wake up all pending tasks */ | 778 | /* Mark transport as closed and wake up all pending tasks */ |
779 | xprt_disconnect_done(xprt); | 779 | xprt_disconnect_done(xprt); |
780 | xprt_force_disconnect(xprt); | ||
781 | } | 780 | } |
782 | 781 | ||
783 | /** | 782 | /** |
@@ -881,8 +880,11 @@ static void xs_xprt_free(struct rpc_xprt *xprt) | |||
881 | */ | 880 | */ |
882 | static void xs_destroy(struct rpc_xprt *xprt) | 881 | static void xs_destroy(struct rpc_xprt *xprt) |
883 | { | 882 | { |
883 | struct sock_xprt *transport = container_of(xprt, | ||
884 | struct sock_xprt, xprt); | ||
884 | dprintk("RPC: xs_destroy xprt %p\n", xprt); | 885 | dprintk("RPC: xs_destroy xprt %p\n", xprt); |
885 | 886 | ||
887 | cancel_delayed_work_sync(&transport->connect_worker); | ||
886 | xs_close(xprt); | 888 | xs_close(xprt); |
887 | xs_xprt_free(xprt); | 889 | xs_xprt_free(xprt); |
888 | module_put(THIS_MODULE); | 890 | module_put(THIS_MODULE); |
@@ -1435,6 +1437,7 @@ out: | |||
1435 | static void xs_tcp_state_change(struct sock *sk) | 1437 | static void xs_tcp_state_change(struct sock *sk) |
1436 | { | 1438 | { |
1437 | struct rpc_xprt *xprt; | 1439 | struct rpc_xprt *xprt; |
1440 | struct sock_xprt *transport; | ||
1438 | 1441 | ||
1439 | read_lock_bh(&sk->sk_callback_lock); | 1442 | read_lock_bh(&sk->sk_callback_lock); |
1440 | if (!(xprt = xprt_from_sock(sk))) | 1443 | if (!(xprt = xprt_from_sock(sk))) |
@@ -1446,13 +1449,12 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1446 | sock_flag(sk, SOCK_ZAPPED), | 1449 | sock_flag(sk, SOCK_ZAPPED), |
1447 | sk->sk_shutdown); | 1450 | sk->sk_shutdown); |
1448 | 1451 | ||
1452 | transport = container_of(xprt, struct sock_xprt, xprt); | ||
1449 | trace_rpc_socket_state_change(xprt, sk->sk_socket); | 1453 | trace_rpc_socket_state_change(xprt, sk->sk_socket); |
1450 | switch (sk->sk_state) { | 1454 | switch (sk->sk_state) { |
1451 | case TCP_ESTABLISHED: | 1455 | case TCP_ESTABLISHED: |
1452 | spin_lock(&xprt->transport_lock); | 1456 | spin_lock(&xprt->transport_lock); |
1453 | if (!xprt_test_and_set_connected(xprt)) { | 1457 | if (!xprt_test_and_set_connected(xprt)) { |
1454 | struct sock_xprt *transport = container_of(xprt, | ||
1455 | struct sock_xprt, xprt); | ||
1456 | 1458 | ||
1457 | /* Reset TCP record info */ | 1459 | /* Reset TCP record info */ |
1458 | transport->tcp_offset = 0; | 1460 | transport->tcp_offset = 0; |
@@ -1461,6 +1463,8 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1461 | transport->tcp_flags = | 1463 | transport->tcp_flags = |
1462 | TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID; | 1464 | TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID; |
1463 | xprt->connect_cookie++; | 1465 | xprt->connect_cookie++; |
1466 | clear_bit(XPRT_SOCK_CONNECTING, &transport->sock_state); | ||
1467 | xprt_clear_connecting(xprt); | ||
1464 | 1468 | ||
1465 | xprt_wake_pending_tasks(xprt, -EAGAIN); | 1469 | xprt_wake_pending_tasks(xprt, -EAGAIN); |
1466 | } | 1470 | } |
@@ -1496,6 +1500,9 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1496 | smp_mb__after_atomic(); | 1500 | smp_mb__after_atomic(); |
1497 | break; | 1501 | break; |
1498 | case TCP_CLOSE: | 1502 | case TCP_CLOSE: |
1503 | if (test_and_clear_bit(XPRT_SOCK_CONNECTING, | ||
1504 | &transport->sock_state)) | ||
1505 | xprt_clear_connecting(xprt); | ||
1499 | xs_sock_mark_closed(xprt); | 1506 | xs_sock_mark_closed(xprt); |
1500 | } | 1507 | } |
1501 | out: | 1508 | out: |
@@ -2179,6 +2186,7 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
2179 | /* Tell the socket layer to start connecting... */ | 2186 | /* Tell the socket layer to start connecting... */ |
2180 | xprt->stat.connect_count++; | 2187 | xprt->stat.connect_count++; |
2181 | xprt->stat.connect_start = jiffies; | 2188 | xprt->stat.connect_start = jiffies; |
2189 | set_bit(XPRT_SOCK_CONNECTING, &transport->sock_state); | ||
2182 | ret = kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); | 2190 | ret = kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); |
2183 | switch (ret) { | 2191 | switch (ret) { |
2184 | case 0: | 2192 | case 0: |
@@ -2240,7 +2248,6 @@ static void xs_tcp_setup_socket(struct work_struct *work) | |||
2240 | case -EINPROGRESS: | 2248 | case -EINPROGRESS: |
2241 | case -EALREADY: | 2249 | case -EALREADY: |
2242 | xprt_unlock_connect(xprt, transport); | 2250 | xprt_unlock_connect(xprt, transport); |
2243 | xprt_clear_connecting(xprt); | ||
2244 | return; | 2251 | return; |
2245 | case -EINVAL: | 2252 | case -EINVAL: |
2246 | /* Happens, for instance, if the user specified a link | 2253 | /* Happens, for instance, if the user specified a link |