diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-03-18 20:21:23 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-05-27 17:42:00 -0400 |
commit | fe19a96b10032035a35779f42ad59e35d6dd8ffd (patch) | |
tree | 12277ec0de8e30806f3fd4287da9cc6433d69615 /net | |
parent | 61c4f2c81c61f73549928dfd9f3e8f26aa36a8cf (diff) |
SUNRPC: Deal with the lack of a SYN_SENT sk->sk_state_change callback...
The TCP connection state code depends on the state_change() callback
being called when the SYN_SENT state is set. However the networking layer
doesn't actually call us back in that case.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/xprtsock.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index bf005d3c65ef..f34f5ab341a3 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1344,7 +1344,6 @@ static void xs_tcp_state_change(struct sock *sk) | |||
1344 | case TCP_CLOSE_WAIT: | 1344 | case TCP_CLOSE_WAIT: |
1345 | /* The server initiated a shutdown of the socket */ | 1345 | /* The server initiated a shutdown of the socket */ |
1346 | xprt_force_disconnect(xprt); | 1346 | xprt_force_disconnect(xprt); |
1347 | case TCP_SYN_SENT: | ||
1348 | xprt->connect_cookie++; | 1347 | xprt->connect_cookie++; |
1349 | case TCP_CLOSING: | 1348 | case TCP_CLOSING: |
1350 | /* | 1349 | /* |
@@ -1758,6 +1757,7 @@ static void xs_tcp_reuse_connection(struct sock_xprt *transport) | |||
1758 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 1757 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
1759 | { | 1758 | { |
1760 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 1759 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
1760 | int ret = -ENOTCONN; | ||
1761 | 1761 | ||
1762 | if (!transport->inet) { | 1762 | if (!transport->inet) { |
1763 | struct sock *sk = sock->sk; | 1763 | struct sock *sk = sock->sk; |
@@ -1789,12 +1789,22 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
1789 | } | 1789 | } |
1790 | 1790 | ||
1791 | if (!xprt_bound(xprt)) | 1791 | if (!xprt_bound(xprt)) |
1792 | return -ENOTCONN; | 1792 | goto out; |
1793 | 1793 | ||
1794 | /* Tell the socket layer to start connecting... */ | 1794 | /* Tell the socket layer to start connecting... */ |
1795 | xprt->stat.connect_count++; | 1795 | xprt->stat.connect_count++; |
1796 | xprt->stat.connect_start = jiffies; | 1796 | xprt->stat.connect_start = jiffies; |
1797 | return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); | 1797 | ret = kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); |
1798 | switch (ret) { | ||
1799 | case 0: | ||
1800 | case -EINPROGRESS: | ||
1801 | /* SYN_SENT! */ | ||
1802 | xprt->connect_cookie++; | ||
1803 | if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) | ||
1804 | xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; | ||
1805 | } | ||
1806 | out: | ||
1807 | return ret; | ||
1798 | } | 1808 | } |
1799 | 1809 | ||
1800 | /** | 1810 | /** |