]> git.itanic.dy.fi Git - linux-stable/commitdiff
SUNRPC: Don't disconnect if a connection is still in progress.
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 11 Mar 2009 18:37:58 +0000 (14:37 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 30 Jul 2009 23:06:09 +0000 (16:06 -0700)
commit 40d2549db5f515e415894def98b49db7d4c56714 upstream.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
net/sunrpc/xprtsock.c

index de39617cdb40af36b7b4b9bf1f657aa1ee853790..8f9295da9b34e9b141c94967a6fe7c8c24c76ba6 100644 (file)
@@ -1560,10 +1560,9 @@ static void xs_udp_connect_worker6(struct work_struct *work)
  * We need to preserve the port number so the reply cache on the server can
  * find our cached RPC replies when we get around to reconnecting.
  */
-static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
+static void xs_abort_connection(struct rpc_xprt *xprt, struct sock_xprt *transport)
 {
        int result;
-       struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
        struct sockaddr any;
 
        dprintk("RPC:       disconnecting xprt %p to reuse port\n", xprt);
@@ -1580,6 +1579,17 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
                                result);
 }
 
+static void xs_tcp_reuse_connection(struct rpc_xprt *xprt, struct sock_xprt *transport)
+{
+       unsigned int state = transport->inet->sk_state;
+
+       if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED)
+               return;
+       if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT))
+               return;
+       xs_abort_connection(xprt, transport);
+}
+
 static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
 {
        struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
@@ -1650,7 +1660,7 @@ static void xs_tcp_connect_worker4(struct work_struct *work)
                }
        } else
                /* "close" the socket, preserving the local port */
-               xs_tcp_reuse_connection(xprt);
+               xs_tcp_reuse_connection(xprt, transport);
 
        dprintk("RPC:       worker connecting xprt %p to address: %s\n",
                        xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
@@ -1710,7 +1720,7 @@ static void xs_tcp_connect_worker6(struct work_struct *work)
                }
        } else
                /* "close" the socket, preserving the local port */
-               xs_tcp_reuse_connection(xprt);
+               xs_tcp_reuse_connection(xprt, transport);
 
        dprintk("RPC:       worker connecting xprt %p to address: %s\n",
                        xprt, xprt->address_strings[RPC_DISPLAY_ALL]);