]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.2-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 26 Sep 2015 16:57:06 +0000 (09:57 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 26 Sep 2015 16:57:06 +0000 (09:57 -0700)
added patches:
sunrpc-ensure-that-we-wait-for-connections-to-complete-before-retrying.patch
sunrpc-lock-the-transport-layer-on-shutdown.patch

queue-4.2/series
queue-4.2/sunrpc-ensure-that-we-wait-for-connections-to-complete-before-retrying.patch [new file with mode: 0644]
queue-4.2/sunrpc-lock-the-transport-layer-on-shutdown.patch [new file with mode: 0644]

index 2352e5d60483b0c1c8ac8d3bceb40e358d9856fc..4499e3e3d65395f8032ad3912ab8160b8bde0440 100644 (file)
@@ -91,3 +91,5 @@ svcrdma-change-maximum-server-payload-back-to-rpcsvc_maxpayload.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.2/sunrpc-ensure-that-we-wait-for-connections-to-complete-before-retrying.patch b/queue-4.2/sunrpc-ensure-that-we-wait-for-connections-to-complete-before-retrying.patch
new file mode 100644 (file)
index 0000000..1e40dcc
--- /dev/null
@@ -0,0 +1,108 @@
+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
+@@ -1433,6 +1433,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)))
+@@ -1444,13 +1445,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;
+@@ -1459,6 +1459,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);
+               }
+@@ -1494,6 +1496,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:
+@@ -2177,6 +2182,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:
+@@ -2238,7 +2244,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.2/sunrpc-lock-the-transport-layer-on-shutdown.patch b/queue-4.2/sunrpc-lock-the-transport-layer-on-shutdown.patch
new file mode 100644 (file)
index 0000000..d2355e0
--- /dev/null
@@ -0,0 +1,50 @@
+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
+@@ -614,6 +614,7 @@ static void xprt_autoclose(struct work_s
+       clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
+       xprt->ops->close(xprt);
+       xprt_release_write(xprt, NULL);
++      wake_up_bit(&xprt->state, XPRT_LOCKED);
+ }
+ /**
+@@ -723,6 +724,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);
+ }
+ /**
+@@ -1394,6 +1396,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);