diff --git a/block/partitions/core.c b/block/partitions/core.c index 1f031f074ffd64b4205798ffb2169378d88698b7..569b0ca9f6e1a115f1b517207d2d8ef4b66c0fe6 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -523,6 +523,7 @@ int bdev_add_partition(struct block_device *bdev, int partno, int ret; mutex_lock(&bdev->bd_mutex); + down_read(&disk->lookup_sem); if (!(disk->flags & GENHD_FL_UP)) { ret = -ENXIO; goto out; @@ -537,6 +538,7 @@ int bdev_add_partition(struct block_device *bdev, int partno, ADDPART_FLAG_NONE, NULL); ret = PTR_ERR_OR_ZERO(part); out: + up_read(&disk->lookup_sem); mutex_unlock(&bdev->bd_mutex); return ret; } @@ -553,6 +555,7 @@ int bdev_del_partition(struct block_device *bdev, int partno) mutex_lock(&bdevp->bd_mutex); mutex_lock_nested(&bdev->bd_mutex, 1); + down_read(&bdev->bd_disk->lookup_sem); ret = -ENXIO; part = disk_get_part(bdev->bd_disk, partno); @@ -569,6 +572,7 @@ int bdev_del_partition(struct block_device *bdev, int partno) delete_partition(part); ret = 0; out_unlock: + up_read(&bdev->bd_disk->lookup_sem); mutex_unlock(&bdev->bd_mutex); mutex_unlock(&bdevp->bd_mutex); bdput(bdevp); diff --git a/fs/block_dev.c b/fs/block_dev.c index d2881fd351a3ffd0e3033195f8ab422caa9322a5..46801789f2dc30bedfa2c210a4834a4487bf4df3 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1427,14 +1427,16 @@ int bdev_disk_changed(struct block_device *bdev, bool invalidate) int ret; lockdep_assert_held(&bdev->bd_mutex); - - if (!(disk->flags & GENHD_FL_UP)) - return -ENXIO; + down_read(&disk->lookup_sem); + if (!(disk->flags & GENHD_FL_UP)) { + ret = -ENXIO; + goto out; + } rescan: ret = blk_drop_partitions(bdev); if (ret) - return ret; + goto out; clear_bit(GD_NEED_PART_SCAN, &disk->state); @@ -1469,6 +1471,8 @@ int bdev_disk_changed(struct block_device *bdev, bool invalidate) kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); } +out: + up_read(&disk->lookup_sem); return ret; } /*