]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Fri, 19 Aug 2011 18:03:38 +0000 (11:03 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 19 Aug 2011 18:03:38 +0000 (11:03 -0700)
queue-3.0/loop-fix-deadlock-when-sysfs-and-loop_clr_fd-race-against.patch [new file with mode: 0644]
queue-3.0/series

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 (file)
index 0000000..97fead9
--- /dev/null
@@ -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;
index c473522f40c32c15a80b2a66bce769faf422e608..a18651fede53cc5e8bcfcf8b1b708b073cd6ff44 100644 (file)
@@ -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