Patchwork [3.5.y.z,extended,stable] Patch "loopdev: fix a deadlock" has been added to staging queue

mail settings
Submitter Luis Henriques
Date March 20, 2013, 10:43 a.m.
Message ID <>
Download mbox | patch
Permalink /patch/229320/
State New
Headers show


Luis Henriques - March 20, 2013, 10:43 a.m.
This is a note to let you know that I have just added a patch titled

    loopdev: fix a deadlock

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From 9197d80d8c71433aca94b206582b9446dce6637c Mon Sep 17 00:00:00 2001
From: Guo Chao <>
Date: Thu, 21 Feb 2013 15:16:45 -0800
Subject: [PATCH] loopdev: fix a deadlock

commit 5370019dc2d2c2ff90e95d181468071362934f3a upstream.

bd_mutex and lo_ctl_mutex can be held in different order.

Path #1:

  __blkdev_get (hold bd_mutex)
   lo_open (hold lo_ctl_mutex)

Path #2:

 lo_ioctl (hold lo_ctl_mutex)
  lo_set_capacity (hold bd_mutex)

Lockdep does not report it, because path #2 actually holds a subclass of
lo_ctl_mutex.  This subclass seems creep into the code by mistake.  The
patch author actually just mentioned it in the changelog, see commit
f028f3b2 ("loop: fix circular locking in loop_clr_fd()"), also see:

Path #2 hold bd_mutex to call bd_set_size(), I've protected it
with i_mutex in a previous patch, so drop bd_mutex at this site.

Signed-off-by: Guo Chao <>
Cc: Alexander Viro <>
Cc: Guo Chao <>
Cc: M. Hindess <>
Cc: Nikanth Karthikesan <>
Cc: Jens Axboe <>
Signed-off-by: Andrew Morton <>
Signed-off-by: Jens Axboe <>
Signed-off-by: Luis Henriques <>
 drivers/block/loop.c | 2 --
 1 file changed, 2 deletions(-)



diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 3bba655..11e702c 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1263,11 +1263,9 @@  static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
 	/* the width of sector_t may be narrow for bit-shift */
 	sz = sec;
 	sz <<= 9;
-	mutex_lock(&bdev->bd_mutex);
 	bd_set_size(bdev, sz);
 	/* let user-space know about the new size */
 	kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
-	mutex_unlock(&bdev->bd_mutex);

 	return err;