--- /dev/null
+From 0fdea1e8a2853f79d39b8555cc9de16a7e0ab26f Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Wed, 16 Sep 2015 23:43:17 -0400
+Subject: SUNRPC: Ensure that we wait for connections to complete before retrying
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+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 <linux@arm.linux.org.uk>
+Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Tested-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Tested-by: Benjamin Coddington <bcodding@redhat.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
--- /dev/null
+From 79234c3db6842a3de03817211d891e0c2878f756 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Fri, 18 Sep 2015 15:53:24 -0400
+Subject: SUNRPC: Lock the transport layer on shutdown
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit 79234c3db6842a3de03817211d891e0c2878f756 upstream.
+
+Avoid all races with the connect/disconnect handlers by taking the
+transport lock.
+
+Reported-by:"Suzuki K. Poulose" <suzuki.poulose@arm.com>
+Acked-by: Jeff Layton <jlayton@poochiereds.net>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);