]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
SUNRPC: Deal with the lack of a SYN_SENT sk->sk_state_change callback...
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Sat, 19 Mar 2011 00:21:23 +0000 (20:21 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 23 Jun 2011 22:28:38 +0000 (15:28 -0700)
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

index 60d1653ddefda69fb6d6f416b2e302405062d9f3..3351a313b0f6dd698175d048b81ce3050332faf1 100644 (file)
@@ -1366,7 +1366,6 @@ static void xs_tcp_state_change(struct sock *sk)
        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(struct rpc_xprt *xprt, struct sock_xprt *tra
 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(struct rpc_xprt *xprt, struct socket *sock)
        }
 
        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;
 }
 
 /**