]> 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)
commitb507cca571d0f449f7e2394fb377e0124d559124
tree62ae10aef5f6b0c59124a14a89f22dd37ce20f09
parentea12f47ce2e94a738290b3c77d589458177c576b
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