From: Greg Kroah-Hartman Date: Sat, 26 Sep 2015 16:57:00 +0000 (-0700) Subject: 4.1-stable patches X-Git-Tag: v4.1.9~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d438e5d78f05456044ec83f9785417cc8fc1cb3b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.1-stable patches added patches: sunrpc-ensure-that-we-wait-for-connections-to-complete-before-retrying.patch sunrpc-lock-the-transport-layer-on-shutdown.patch --- diff --git a/queue-4.1/series b/queue-4.1/series index c76b5ccee0e..985399e53ed 100644 --- a/queue-4.1/series +++ b/queue-4.1/series @@ -68,3 +68,5 @@ revert-nfsv4-remove-incorrect-check-in-can_open_delegated.patch net-sunrpc-fix-tracepoint-warning-unknown-op.patch sunrpc-fix-a-thinko-in-xs_connect.patch sunrpc-xs_reset_transport-must-mark-the-connection-as-disconnected.patch +sunrpc-ensure-that-we-wait-for-connections-to-complete-before-retrying.patch +sunrpc-lock-the-transport-layer-on-shutdown.patch diff --git a/queue-4.1/sunrpc-ensure-that-we-wait-for-connections-to-complete-before-retrying.patch b/queue-4.1/sunrpc-ensure-that-we-wait-for-connections-to-complete-before-retrying.patch new file mode 100644 index 00000000000..e434dd33b8f --- /dev/null +++ b/queue-4.1/sunrpc-ensure-that-we-wait-for-connections-to-complete-before-retrying.patch @@ -0,0 +1,108 @@ +From 0fdea1e8a2853f79d39b8555cc9de16a7e0ab26f Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Wed, 16 Sep 2015 23:43:17 -0400 +Subject: SUNRPC: Ensure that we wait for connections to complete before retrying + +From: Trond Myklebust + +commit 0fdea1e8a2853f79d39b8555cc9de16a7e0ab26f upstream. + +Commit 718ba5b87343, moved the responsibility for unlocking the socket to +xs_tcp_setup_socket, meaning that the socket will be unlocked before we +know that it has finished trying to connect. The following patch is based on +an initial patch by Russell King to ensure that we delay clearing the +XPRT_CONNECTING flag until we either know that we failed to initiate +a connection attempt, or the connection attempt itself failed. + +Fixes: 718ba5b87343 ("SUNRPC: Add helpers to prevent socket create from racing") +Reported-by: Russell King +Reported-by: Russell King +Tested-by: Russell King +Tested-by: Benjamin Coddington +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/sunrpc/xprtsock.h | 3 +++ + net/sunrpc/xprtsock.c | 11 ++++++++--- + 2 files changed, 11 insertions(+), 3 deletions(-) + +--- a/include/linux/sunrpc/xprtsock.h ++++ b/include/linux/sunrpc/xprtsock.h +@@ -42,6 +42,7 @@ struct sock_xprt { + /* + * Connection of transports + */ ++ unsigned long sock_state; + struct delayed_work connect_worker; + struct sockaddr_storage srcaddr; + unsigned short srcport; +@@ -76,6 +77,8 @@ struct sock_xprt { + */ + #define TCP_RPC_REPLY (1UL << 6) + ++#define XPRT_SOCK_CONNECTING 1U ++ + #endif /* __KERNEL__ */ + + #endif /* _LINUX_SUNRPC_XPRTSOCK_H */ +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -1434,6 +1434,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))) +@@ -1445,13 +1446,12 @@ static void xs_tcp_state_change(struct s + 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; +@@ -1460,6 +1460,8 @@ static void xs_tcp_state_change(struct s + 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); + } +@@ -1495,6 +1497,9 @@ static void xs_tcp_state_change(struct s + 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: +@@ -2111,6 +2116,7 @@ static int xs_tcp_finish_connecting(stru + /* 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: +@@ -2175,7 +2181,6 @@ static void xs_tcp_setup_socket(struct w + 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 diff --git a/queue-4.1/sunrpc-lock-the-transport-layer-on-shutdown.patch b/queue-4.1/sunrpc-lock-the-transport-layer-on-shutdown.patch new file mode 100644 index 00000000000..818ba3895b8 --- /dev/null +++ b/queue-4.1/sunrpc-lock-the-transport-layer-on-shutdown.patch @@ -0,0 +1,50 @@ +From 79234c3db6842a3de03817211d891e0c2878f756 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 18 Sep 2015 15:53:24 -0400 +Subject: SUNRPC: Lock the transport layer on shutdown + +From: Trond Myklebust + +commit 79234c3db6842a3de03817211d891e0c2878f756 upstream. + +Avoid all races with the connect/disconnect handlers by taking the +transport lock. + +Reported-by:"Suzuki K. Poulose" +Acked-by: Jeff Layton +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/xprt.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/net/sunrpc/xprt.c ++++ b/net/sunrpc/xprt.c +@@ -611,6 +611,7 @@ static void xprt_autoclose(struct work_s + xprt->ops->close(xprt); + clear_bit(XPRT_CLOSE_WAIT, &xprt->state); + xprt_release_write(xprt, NULL); ++ wake_up_bit(&xprt->state, XPRT_LOCKED); + } + + /** +@@ -720,6 +721,7 @@ void xprt_unlock_connect(struct rpc_xprt + xprt->ops->release_xprt(xprt, NULL); + out: + spin_unlock_bh(&xprt->transport_lock); ++ wake_up_bit(&xprt->state, XPRT_LOCKED); + } + + /** +@@ -1389,6 +1391,10 @@ out: + static void xprt_destroy(struct rpc_xprt *xprt) + { + dprintk("RPC: destroying transport %p\n", xprt); ++ ++ /* Exclude transport connect/disconnect handlers */ ++ wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_UNINTERRUPTIBLE); ++ + del_timer_sync(&xprt->timer); + + rpc_xprt_debugfs_unregister(xprt);