It might be easier to just move the check into blkdev_get_whole, which also ensures that non-excluisve openers don't cause a partition scan while someone else has the device exclusively open. diff --git a/block/bdev.c b/block/bdev.c index edc110d90df404..a831b6c9c627d7 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -666,25 +666,28 @@ static void blkdev_flush_mapping(struct block_device *bdev) static int blkdev_get_whole(struct block_device *bdev, fmode_t mode) { struct gendisk *disk = bdev->bd_disk; - int ret; + int ret = 0; - if (disk->fops->open) { + if (disk->fops->open) ret = disk->fops->open(bdev, mode); - if (ret) { - /* avoid ghost partitions on a removed medium */ - if (ret == -ENOMEDIUM && - test_bit(GD_NEED_PART_SCAN, &disk->state)) - bdev_disk_changed(disk, true); + + if (ret) { + /* avoid ghost partitions on a removed medium */ + if (ret != -ENOMEDIUM) return ret; - } + } else { + if (!atomic_read(&bdev->bd_openers)) + set_init_blocksize(bdev); + atomic_inc(&bdev->bd_openers); } - if (!atomic_read(&bdev->bd_openers)) - set_init_blocksize(bdev); - if (test_bit(GD_NEED_PART_SCAN, &disk->state)) + /* + * Skip the partition scan if someone else has the device exclusively + * open. + */ + if (test_bit(GD_NEED_PART_SCAN, &disk->state) && !bdev->bd_holder) bdev_disk_changed(disk, false); - atomic_inc(&bdev->bd_openers); - return 0; + return ret; } static void blkdev_put_whole(struct block_device *bdev, fmode_t mode) diff --git a/block/genhd.c b/block/genhd.c index 23cf83b3331cde..4a7b1b8b9efdb5 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -366,9 +366,6 @@ int disk_scan_partitions(struct gendisk *disk, fmode_t mode, void *owner) return -EINVAL; if (disk->open_partitions) return -EBUSY; - /* Someone else has bdev exclusively open? */ - if (disk->part0->bd_holder && disk->part0->bd_holder != owner) - return -EBUSY; set_bit(GD_NEED_PART_SCAN, &disk->state); bdev = blkdev_get_by_dev(disk_devt(disk), mode, NULL);