Home Home > GIT Browse > openSUSE-15.0
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-10-31 16:21:34 +1100
committerNeilBrown <neilb@suse.de>2013-10-31 16:21:34 +1100
commit36fae465249c8f16b115b90b81cbed1c31dcb4a4 (patch)
treedfc4c78f1ca55afc75bfce5a6732127c0274de08
parent831e52b4df1c61567aeed02295aadd8a1b331e4e (diff)
- patches.fixes/nfs-xs_tcp_setup_socket.fix: SUNRPC: close arpm-3.0.101-0.5
rare race in xs_tcp_setup_socket (bnc#794824).
-rw-r--r--kernel-source.changes6
-rw-r--r--patches.fixes/nfs-xs_tcp_setup_socket.fix67
-rw-r--r--series.conf1
3 files changed, 74 insertions, 0 deletions
diff --git a/kernel-source.changes b/kernel-source.changes
index ba1cf0159f..6f732c5751 100644
--- a/kernel-source.changes
+++ b/kernel-source.changes
@@ -1,4 +1,10 @@
-------------------------------------------------------------------
+Thu Oct 31 06:21:24 CET 2013 - nfbrown@suse.de
+
+- patches.fixes/nfs-xs_tcp_setup_socket.fix: SUNRPC: close a
+ rare race in xs_tcp_setup_socket (bnc#794824).
+
+-------------------------------------------------------------------
Wed Oct 30 19:10:58 CET 2013 - dsterba@suse.cz
- patches.kernel.org/revert-Btrfs-change-how-we-queue-blocks-for-backref-checkin.patch:
diff --git a/patches.fixes/nfs-xs_tcp_setup_socket.fix b/patches.fixes/nfs-xs_tcp_setup_socket.fix
new file mode 100644
index 0000000000..169d69b5ae
--- /dev/null
+++ b/patches.fixes/nfs-xs_tcp_setup_socket.fix
@@ -0,0 +1,67 @@
+From: NeilBrown <neilb@suse.de>
+Date: Thu, 31 Oct 2013 16:06:06 +1100
+Subject: [PATCH] SUNRPC: close a rare race in xs_tcp_setup_socket.
+References: bnc#794824
+Patch-mainline: submitted for 3.13
+
+We have one report of a crash in xs_tcp_setup_socket.
+The call path to the crash is:
+
+ xs_tcp_setup_socket -> inet_stream_connect -> lock_sock_nested.
+
+The 'sock' passed to that last function is NULL.
+
+The only way I can see this happening is a concurrent call to
+xs_close:
+
+ xs_close -> xs_reset_transport -> sock_release -> inet_release
+
+inet_release sets:
+ sock->sk = NULL;
+inet_stream_connect calls
+ lock_sock(sock->sk);
+which gets NULL.
+
+All calls to xs_close are protected by XPRT_LOCKED as are most
+activations of the workqueue which runs xs_tcp_setup_socket.
+The exception is xs_tcp_schedule_linger_timeout.
+
+So presumably the timeout queued by the later fires exactly when some
+other code runs xs_close().
+
+To protect against this we can move the cancel_delayed_work_sync()
+call from xs_destory() to xs_close().
+
+As xs_close is never called from the worker scheduled on
+->connect_worker, this can never deadlock.
+
+Signed-off-by: NeilBrown <neilb@suse.de>
+
+---
+ net/sunrpc/xprtsock.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- linux-3.0-SLE11-SP2.orig/net/sunrpc/xprtsock.c
++++ linux-3.0-SLE11-SP2/net/sunrpc/xprtsock.c
+@@ -818,6 +818,8 @@ static void xs_close(struct rpc_xprt *xp
+
+ dprintk("RPC: xs_close xprt %p\n", xprt);
+
++ cancel_delayed_work_sync(&transport->connect_worker);
++
+ xs_reset_transport(transport);
+ xprt->reestablish_timeout = 0;
+
+@@ -844,12 +846,8 @@ static void xs_tcp_close(struct rpc_xprt
+ */
+ static void xs_destroy(struct rpc_xprt *xprt)
+ {
+- struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
+-
+ dprintk("RPC: xs_destroy xprt %p\n", xprt);
+
+- cancel_delayed_work_sync(&transport->connect_worker);
+-
+ xs_close(xprt);
+ xs_free_peer_addresses(xprt);
+ xprt_free(xprt);
diff --git a/series.conf b/series.conf
index ab62f4d726..c8895b7339 100644
--- a/series.conf
+++ b/series.conf
@@ -2132,6 +2132,7 @@
patches.fixes/do_add_mount-umount-l-races.patch
patches.fixes/nfs_lookup_revalidate-fix-a-leak.patch
patches.fixes/nfs_flush_incompatible.fix
+ patches.fixes/nfs-xs_tcp_setup_socket.fix
########################################################
# Lustre enablement