| From fe19a96b10032035a35779f42ad59e35d6dd8ffd Mon Sep 17 00:00:00 2001 |
| From: Trond Myklebust <Trond.Myklebust@netapp.com> |
| Date: Fri, 18 Mar 2011 20:21:23 -0400 |
| Subject: SUNRPC: Deal with the lack of a SYN_SENT sk->sk_state_change |
| callback... |
| |
| From: Trond Myklebust <Trond.Myklebust@netapp.com> |
| |
| commit fe19a96b10032035a35779f42ad59e35d6dd8ffd upstream. |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| net/sunrpc/xprtsock.c | 16 +++++++++++++--- |
| 1 file changed, 13 insertions(+), 3 deletions(-) |
| |
| --- a/net/sunrpc/xprtsock.c |
| +++ b/net/sunrpc/xprtsock.c |
| @@ -1366,7 +1366,6 @@ static void xs_tcp_state_change(struct s |
| case TCP_CLOSE_WAIT: |
| /* The server initiated a shutdown of the socket */ |
| xprt_force_disconnect(xprt); |
| - case TCP_SYN_SENT: |
| xprt->connect_cookie++; |
| case TCP_CLOSING: |
| /* |
| @@ -1813,6 +1812,7 @@ static void xs_tcp_reuse_connection(stru |
| static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
| { |
| struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
| + int ret = -ENOTCONN; |
| |
| if (!transport->inet) { |
| struct sock *sk = sock->sk; |
| @@ -1844,12 +1844,22 @@ static int xs_tcp_finish_connecting(stru |
| } |
| |
| if (!xprt_bound(xprt)) |
| - return -ENOTCONN; |
| + goto out; |
| |
| /* Tell the socket layer to start connecting... */ |
| xprt->stat.connect_count++; |
| xprt->stat.connect_start = jiffies; |
| - return kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); |
| + ret = kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK); |
| + switch (ret) { |
| + case 0: |
| + case -EINPROGRESS: |
| + /* SYN_SENT! */ |
| + xprt->connect_cookie++; |
| + if (xprt->reestablish_timeout < XS_TCP_INIT_REEST_TO) |
| + xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; |
| + } |
| +out: |
| + return ret; |
| } |
| |
| /** |