Skip to content

Commit

Permalink
SUNRPC: Deal with the lack of a SYN_SENT sk->sk_state_change callback...
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed May 27, 2011
1 parent 61c4f2c commit fe19a96
Showing 1 changed file with 13 additions and 3 deletions.
16 changes: 13 additions & 3 deletions net/sunrpc/xprtsock.c
Expand Up @@ -1344,7 +1344,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:
/*
Expand Down Expand Up @@ -1758,6 +1757,7 @@ static void xs_tcp_reuse_connection(struct sock_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);
int ret = -ENOTCONN;

if (!transport->inet) {
struct sock *sk = sock->sk;
Expand Down Expand Up @@ -1789,12 +1789,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;
}

/**
Expand Down

0 comments on commit fe19a96

Please sign in to comment.