summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-08-19 11:03:38 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-08-19 11:03:38 -0700
commit50a60b8c17c2894c415c7374ab373a03b0bf2003 (patch)
treeb37ae6c4aca7eb5c324b8786cb7763529c17a4be
parentd51f2c3010997fc36384496eca4f79fe8e63af3e (diff)
downloadstable-queue-50a60b8c17c2894c415c7374ab373a03b0bf2003.tar.gz
3.0 patches
-rw-r--r--queue-3.0/loop-fix-deadlock-when-sysfs-and-loop_clr_fd-race-against.patch77
-rw-r--r--queue-3.0/series1
2 files changed, 78 insertions, 0 deletions
diff --git a/queue-3.0/loop-fix-deadlock-when-sysfs-and-loop_clr_fd-race-against.patch b/queue-3.0/loop-fix-deadlock-when-sysfs-and-loop_clr_fd-race-against.patch
new file mode 100644
index 0000000000..97fead97ea
--- /dev/null
+++ b/queue-3.0/loop-fix-deadlock-when-sysfs-and-loop_clr_fd-race-against.patch
@@ -0,0 +1,77 @@
+From 05eb0f252b04aa94ace0794f73d56c6a02351d80 Mon Sep 17 00:00:00 2001
+From: Kay Sievers <kay.sievers@vrfy.org>
+Date: Sun, 31 Jul 2011 22:21:35 +0200
+Subject: loop: fix deadlock when sysfs and LOOP_CLR_FD race against
+ each other
+
+From: Kay Sievers <kay.sievers@vrfy.org>
+
+commit 05eb0f252b04aa94ace0794f73d56c6a02351d80 upstream.
+
+LOOP_CLR_FD takes lo->lo_ctl_mutex and tries to remove the loop sysfs
+files. Sysfs calls show() and waits for lo->lo_ctl_mutex. LOOP_CLR_FD
+waits for show() to finish to remove the sysfs file.
+
+ cat /sys/class/block/loop0/loop/backing_file
+ mutex_lock_nested+0x176/0x350
+ ? loop_attr_do_show_backing_file+0x2f/0xd0 [loop]
+ ? loop_attr_do_show_backing_file+0x2f/0xd0 [loop]
+ loop_attr_do_show_backing_file+0x2f/0xd0 [loop]
+ dev_attr_show+0x1b/0x60
+ ? sysfs_read_file+0x86/0x1a0
+ ? __get_free_pages+0x12/0x50
+ sysfs_read_file+0xaf/0x1a0
+
+ ioctl(LOOP_CLR_FD):
+ wait_for_common+0x12c/0x180
+ ? try_to_wake_up+0x2a0/0x2a0
+ wait_for_completion+0x18/0x20
+ sysfs_deactivate+0x178/0x180
+ ? sysfs_addrm_finish+0x43/0x70
+ ? sysfs_addrm_start+0x1d/0x20
+ sysfs_addrm_finish+0x43/0x70
+ sysfs_hash_and_remove+0x85/0xa0
+ sysfs_remove_group+0x59/0x100
+ loop_clr_fd+0x1dc/0x3f0 [loop]
+ lo_ioctl+0x223/0x7a0 [loop]
+
+Instead of taking the lo_ctl_mutex from sysfs code, take the inner
+lo->lo_lock, to protect the access to the backing_file data.
+
+Thanks to Tejun for help debugging and finding a solution.
+
+Cc: Milan Broz <mbroz@redhat.com>
+Cc: Tejun Heo <tj@kernel.org>
+Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
+Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/block/loop.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -750,10 +750,10 @@ static ssize_t loop_attr_backing_file_sh
+ ssize_t ret;
+ char *p = NULL;
+
+- mutex_lock(&lo->lo_ctl_mutex);
++ spin_lock_irq(&lo->lo_lock);
+ if (lo->lo_backing_file)
+ p = d_path(&lo->lo_backing_file->f_path, buf, PAGE_SIZE - 1);
+- mutex_unlock(&lo->lo_ctl_mutex);
++ spin_unlock_irq(&lo->lo_lock);
+
+ if (IS_ERR_OR_NULL(p))
+ ret = PTR_ERR(p);
+@@ -1007,7 +1007,9 @@ static int loop_clr_fd(struct loop_devic
+
+ kthread_stop(lo->lo_thread);
+
++ spin_lock_irq(&lo->lo_lock);
+ lo->lo_backing_file = NULL;
++ spin_unlock_irq(&lo->lo_lock);
+
+ loop_release_xfer(lo);
+ lo->transfer = NULL;
diff --git a/queue-3.0/series b/queue-3.0/series
index c473522f40..a18651fede 100644
--- a/queue-3.0/series
+++ b/queue-3.0/series
@@ -11,3 +11,4 @@ nfsv4.1-fix-the-callback-highest_used_slotid-behaviour.patch
nfsv4.1-return-nfs4err_badsession-to-callbacks-during.patch
x86-mtrr-lock-stop-machine-during-mtrr-rendezvous-sequence.patch
btrfs-detect-wether-a-device-supports-discard.patch
+loop-fix-deadlock-when-sysfs-and-loop_clr_fd-race-against.patch