]> git.baikalelectronics.ru Git - kernel.git/commit
blockdev: Avoid two active bdev inodes for one device
authorJan Kara <jack@suse.cz>
Mon, 26 Feb 2018 12:01:42 +0000 (13:01 +0100)
committerJens Axboe <axboe@kernel.dk>
Mon, 26 Feb 2018 16:48:42 +0000 (09:48 -0700)
commit5c43eb719e3d8b95b3b298e05258fde9953f35bd
tree62ae10aef5f6b0c59124a14a89f22dd37ce20f09
parentf2c7e9789855925c6dbefe91a5fd33242e263336
blockdev: Avoid two active bdev inodes for one device

When blkdev_open() races with device removal and creation it can happen
that unhashed bdev inode gets associated with newly created gendisk
like:

CPU0 CPU1
blkdev_open()
  bdev = bd_acquire()
del_gendisk()
  bdev_unhash_inode(bdev);
remove device
create new device with the same number
  __blkdev_get()
    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: Hou Tao <houtao1@huawei.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/block_dev.c