• Jan Kara's avatar
    blockdev: Avoid two active bdev inodes for one device · 560e7cb2
    Jan Kara authored
    When blkdev_open() races with device removal and creation it can happen
    that unhashed bdev inode gets associated with newly created gendisk
    CPU0					CPU1
      bdev = bd_acquire()
    					remove device
    					create new device with the same number
        disk = get_gendisk()
          - gets reference to gendisk of the new device
    Now another blkdev_open() will not find original 'bdev' as it got
    unhashed, create a new one and associate it with the same 'disk' at
    which point problems start as we have two independent page caches for
    one device.
    Fix the problem by verifying that the bdev inode didn't get unhashed
    before we acquired gendisk reference. That way we make sure gendisk can
    get associated only with visible bdev inodes.
    Tested-by: 's avatarHou Tao <houtao1@huawei.com>
    Signed-off-by: 's avatarJan Kara <jack@suse.cz>
    Signed-off-by: 's avatarJens Axboe <axboe@kernel.dk>
block_dev.c 53.7 KB