Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ae9da83f6d800fe1f3b23bfbc8f7222ad1c5bb74
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
    device.
    Otherwise, thaw_bdev() will up bd_mount_sem and corrupt the semaphore 
counter.
    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:
      #!/bin/sh
      while [ 1 ]; do
         dmsetup --notable create a
         dmsetup --nolockfs suspend a
         dmsetup remove a
      done
    
    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",
                            atomic_read(&ei->bdev.bd_mount_sem.count),
                            &ei->bdev);
    
    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 2.6.15.5.
    
    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
    noflush.
    
    Signed-off-by: Jun'ichi Nomura <[EMAIL PROTECTED]>
    Signed-off-by: Alasdair G Kergon <[EMAIL PROTECTED]>
    Cc: [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);
                bdput(md->suspended_bdev);
        }
        mempool_destroy(md->tio_pool);
-
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  http://vger.kernel.org/majordomo-info.html

Reply via email to