mtd: mtd_blkdevs: don't increase 'open' count on error path

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Mon Jan 9 13:59:02 EST 2012


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=342ff28f5a2e5aa3236617bd2bddf6c749677ef2
Commit:     342ff28f5a2e5aa3236617bd2bddf6c749677ef2
Parent:     8c3423359644d01cfba3a401e403c549c3f88ac4
Author:     Brian Norris <computersforpeace at gmail.com>
AuthorDate: Mon Nov 7 15:51:05 2011 -0800
Committer:  David Woodhouse <David.Woodhouse at intel.com>
CommitDate: Mon Jan 9 18:04:01 2012 +0000

    mtd: mtd_blkdevs: don't increase 'open' count on error path
    
    Some error paths in mtd_blkdevs were fixed in the following commit:
    
        commit 94735ec4044a6d318b83ad3c5794e931ed168d10
        mtd: mtd_blkdevs: fix error path in blktrans_open
    
    But on these error paths, the block device's `dev->open' count is
    already incremented before we check for errors. This meant that, while
    the error path was handled correctly on the first time through
    blktrans_open(), the device is erroneously considered already open on
    the second time through.
    
    This problem can be seen, for instance, when a UBI volume is
    simultaneously mounted as a UBIFS partition and read through its
    corresponding gluebi mtdblockX device. This results in blktrans_open()
    passing its error checks (with `dev->open > 0') without actually having
    a handle on the device. Here's a summarized log of the actions and
    results with nandsim:
    
        # modprobe nandsim
        # modprobe mtdblock
        # modprobe gluebi
        # modprobe ubifs
        # ubiattach /dev/ubi_ctrl -m 0
        ...
        # ubimkvol /dev/ubi0 -N test -s 16MiB
        ...
        # mount -t ubifs ubi0:test /mnt
        # ls /dev/mtdblock*
        /dev/mtdblock0  /dev/mtdblock1
        # cat /dev/mtdblock1 > /dev/null
        cat: can't open '/dev/mtdblock4': Device or resource busy
        # cat /dev/mtdblock1 > /dev/null
    
        CPU 0 Unable to handle kernel paging request at virtual address
        fffffff0, epc == 8031536c, ra == 8031f280
        Oops[#1]:
        ...
        Call Trace:
        [<8031536c>] ubi_leb_read+0x14/0x164
        [<8031f280>] gluebi_read+0xf0/0x148
        [<802edba8>] mtdblock_readsect+0x64/0x198
        [<802ecfe4>] mtd_blktrans_thread+0x330/0x3f4
        [<8005be98>] kthread+0x88/0x90
        [<8000bc04>] kernel_thread_helper+0x10/0x18
    
    Cc: stable at kernel.org [3.0+]
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
    Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy at linux.intel.com>
    Signed-off-by: David Woodhouse <David.Woodhouse at intel.com>
---
 drivers/mtd/mtd_blkdevs.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index ed8b5e7..424ca5f 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -215,7 +215,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
 
 	mutex_lock(&dev->lock);
 
-	if (dev->open++)
+	if (dev->open)
 		goto unlock;
 
 	kref_get(&dev->ref);
@@ -235,6 +235,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
 		goto error_release;
 
 unlock:
+	dev->open++;
 	mutex_unlock(&dev->lock);
 	blktrans_dev_put(dev);
 	return ret;



More information about the linux-mtd-cvs mailing list