diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-03-11 14:37:58 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-03-11 14:37:58 -0400 |
commit | 40d2549db5f515e415894def98b49db7d4c56714 (patch) | |
tree | 6c301c61cd3a9215bf39deee53623e1fd97a895f /net/sunrpc/xprtsock.c | |
parent | 670f94573104b4a25525d3fcdcd6496c678df172 (diff) |
SUNRPC: Don't disconnect if a connection is still in progress.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index cb4bd93b9211..9d1898f6ee87 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1613,10 +1613,9 @@ out: | |||
1613 | * We need to preserve the port number so the reply cache on the server can | 1613 | * We need to preserve the port number so the reply cache on the server can |
1614 | * find our cached RPC replies when we get around to reconnecting. | 1614 | * find our cached RPC replies when we get around to reconnecting. |
1615 | */ | 1615 | */ |
1616 | static void xs_tcp_reuse_connection(struct rpc_xprt *xprt) | 1616 | static void xs_abort_connection(struct rpc_xprt *xprt, struct sock_xprt *transport) |
1617 | { | 1617 | { |
1618 | int result; | 1618 | int result; |
1619 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | ||
1620 | struct sockaddr any; | 1619 | struct sockaddr any; |
1621 | 1620 | ||
1622 | dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt); | 1621 | dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt); |
@@ -1633,6 +1632,17 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt) | |||
1633 | result); | 1632 | result); |
1634 | } | 1633 | } |
1635 | 1634 | ||
1635 | static void xs_tcp_reuse_connection(struct rpc_xprt *xprt, struct sock_xprt *transport) | ||
1636 | { | ||
1637 | unsigned int state = transport->inet->sk_state; | ||
1638 | |||
1639 | if (state == TCP_CLOSE && transport->sock->state == SS_UNCONNECTED) | ||
1640 | return; | ||
1641 | if ((1 << state) & (TCPF_ESTABLISHED|TCPF_SYN_SENT)) | ||
1642 | return; | ||
1643 | xs_abort_connection(xprt, transport); | ||
1644 | } | ||
1645 | |||
1636 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 1646 | static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
1637 | { | 1647 | { |
1638 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); | 1648 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -1706,7 +1716,7 @@ static void xs_tcp_connect_worker4(struct work_struct *work) | |||
1706 | } | 1716 | } |
1707 | } else | 1717 | } else |
1708 | /* "close" the socket, preserving the local port */ | 1718 | /* "close" the socket, preserving the local port */ |
1709 | xs_tcp_reuse_connection(xprt); | 1719 | xs_tcp_reuse_connection(xprt, transport); |
1710 | 1720 | ||
1711 | dprintk("RPC: worker connecting xprt %p to address: %s\n", | 1721 | dprintk("RPC: worker connecting xprt %p to address: %s\n", |
1712 | xprt, xprt->address_strings[RPC_DISPLAY_ALL]); | 1722 | xprt, xprt->address_strings[RPC_DISPLAY_ALL]); |
@@ -1766,7 +1776,7 @@ static void xs_tcp_connect_worker6(struct work_struct *work) | |||
1766 | } | 1776 | } |
1767 | } else | 1777 | } else |
1768 | /* "close" the socket, preserving the local port */ | 1778 | /* "close" the socket, preserving the local port */ |
1769 | xs_tcp_reuse_connection(xprt); | 1779 | xs_tcp_reuse_connection(xprt, transport); |
1770 | 1780 | ||
1771 | dprintk("RPC: worker connecting xprt %p to address: %s\n", | 1781 | dprintk("RPC: worker connecting xprt %p to address: %s\n", |
1772 | xprt, xprt->address_strings[RPC_DISPLAY_ALL]); | 1782 | xprt, xprt->address_strings[RPC_DISPLAY_ALL]); |