|
@@ -1438,6 +1438,7 @@ out:
|
|
|
static void xs_tcp_state_change(struct sock *sk)
|
|
|
{
|
|
|
struct rpc_xprt *xprt;
|
|
|
+ struct sock_xprt *transport;
|
|
|
|
|
|
read_lock_bh(&sk->sk_callback_lock);
|
|
|
if (!(xprt = xprt_from_sock(sk)))
|
|
@@ -1449,13 +1450,12 @@ static void xs_tcp_state_change(struct sock *sk)
|
|
|
sock_flag(sk, SOCK_ZAPPED),
|
|
|
sk->sk_shutdown);
|
|
|
|
|
|
+ transport = container_of(xprt, struct sock_xprt, xprt);
|
|
|
trace_rpc_socket_state_change(xprt, sk->sk_socket);
|
|
|
switch (sk->sk_state) {
|
|
|
case TCP_ESTABLISHED:
|
|
|
spin_lock(&xprt->transport_lock);
|
|
|
if (!xprt_test_and_set_connected(xprt)) {
|
|
|
- struct sock_xprt *transport = container_of(xprt,
|
|
|
- struct sock_xprt, xprt);
|
|
|
|
|
|
/* Reset TCP record info */
|
|
|
transport->tcp_offset = 0;
|
|
@@ -1464,6 +1464,8 @@ static void xs_tcp_state_change(struct sock *sk)
|
|
|
transport->tcp_flags =
|
|
|
TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID;
|
|
|
xprt->connect_cookie++;
|
|
|
+ clear_bit(XPRT_SOCK_CONNECTING, &transport->sock_state);
|
|
|
+ xprt_clear_connecting(xprt);
|
|
|
|
|
|
xprt_wake_pending_tasks(xprt, -EAGAIN);
|
|
|
}
|
|
@@ -1499,6 +1501,9 @@ static void xs_tcp_state_change(struct sock *sk)
|
|
|
smp_mb__after_atomic();
|
|
|
break;
|
|
|
case TCP_CLOSE:
|
|
|
+ if (test_and_clear_bit(XPRT_SOCK_CONNECTING,
|
|
|
+ &transport->sock_state))
|
|
|
+ xprt_clear_connecting(xprt);
|
|
|
xs_sock_mark_closed(xprt);
|
|
|
}
|
|
|
out:
|
|
@@ -2182,6 +2187,7 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock)
|
|
|
/* Tell the socket layer to start connecting... */
|
|
|
xprt->stat.connect_count++;
|
|
|
xprt->stat.connect_start = jiffies;
|
|
|
+ set_bit(XPRT_SOCK_CONNECTING, &transport->sock_state);
|
|
|
ret = kernel_connect(sock, xs_addr(xprt), xprt->addrlen, O_NONBLOCK);
|
|
|
switch (ret) {
|
|
|
case 0:
|
|
@@ -2243,7 +2249,6 @@ static void xs_tcp_setup_socket(struct work_struct *work)
|
|
|
case -EINPROGRESS:
|
|
|
case -EALREADY:
|
|
|
xprt_unlock_connect(xprt, transport);
|
|
|
- xprt_clear_connecting(xprt);
|
|
|
return;
|
|
|
case -EINVAL:
|
|
|
/* Happens, for instance, if the user specified a link
|