Commit:     ae9da83f6d800fe1f3b23bfbc8f7222ad1c5bb74
Parent:     79662d1ea37392651f2cff08626cab6a40ba3adc
Author:     Jun'ichi Nomura <[EMAIL PROTECTED]>
AuthorDate: Fri Oct 19 22:38:43 2007 +0100
Committer:  Alasdair G Kergon <[EMAIL PROTECTED]>
CommitDate: Sat Oct 20 02:01:05 2007 +0100

    dm: fix thaw_bdev
    This patch fixes a bd_mount_sem counter corruption bug in device-mapper.
    thaw_bdev() should be called only when freeze_bdev() was called for the
    Otherwise, thaw_bdev() will up bd_mount_sem and corrupt the semaphore 
    struct block_device with the corrupted semaphore may remain in slab cache
    and be reused later.
    Attached patch will fix it by calling unlock_fs() instead.
    unlock_fs() will determine whether it should call thaw_bdev()
    by checking the device is frozen or not.
    Easy reproducer is:
      while [ 1 ]; do
         dmsetup --notable create a
         dmsetup --nolockfs suspend a
         dmsetup remove a
    It's not easy to see the effect of corrupted semaphore.
    So I have tested with putting printk below in bdev_alloc_inode():
            if (atomic_read(&ei->bdev.bd_mount_sem.count) != 1)
                    printk(KERN_DEBUG "Incorrect semaphore count = %d (%p)\n",
    Without the patch, I saw something like:
     Incorrect semaphore count = 17 (f2ab91c0)
    With the patch, the message didn't appear.
    The bug was introduced in 2.6.16 with this bug fix:
    commit d9dde59ba03095e526640988c0fedd75e93bc8b7
    Date:   Fri Feb 24 13:04:24 2006 -0800
        [PATCH] dm: missing bdput/thaw_bdev at removal
        Need to unfreeze and release bdev otherwise the bdev inode with
        inconsistent state is reused later and cause problem.
    and backported to
    It occurs only in free_dev(), which is called only when the dm device is
    removed.  The buggy code is executed only if md->suspended_bdev is
    non-NULL and that can happen only when the device was suspended without
    Signed-off-by: Jun'ichi Nomura <[EMAIL PROTECTED]>
    Signed-off-by: Alasdair G Kergon <[EMAIL PROTECTED]>
 drivers/md/dm.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index d837d37..7cb61ab 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1044,12 +1044,14 @@ static struct mapped_device *alloc_dev(int minor)
        return NULL;
+static void unlock_fs(struct mapped_device *md);
 static void free_dev(struct mapped_device *md)
        int minor = md->disk->first_minor;
        if (md->suspended_bdev) {
-               thaw_bdev(md->suspended_bdev, NULL);
+               unlock_fs(md);
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at

Reply via email to