goto out_unlock;
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)
goto out_unlock;
- }
}
-
- if (!bdev->bd_openers)
+ if (!bdev->bd_openers++)
set_init_blocksize(bdev);
- if (test_bit(GD_NEED_PART_SCAN, &disk->state))
- bdev_disk_changed(disk, false);
- bdev->bd_openers++;
ret = 0;
out_unlock:
mutex_unlock(&disk->open_mutex);
+ if (test_bit(GD_NEED_PART_SCAN, &disk->state) &&
+ (ret == 0 || ret == -ENOMEDIUM))
+ bdev_disk_changed(disk, ret == -ENOMEDIUM);
return ret;
}
if (disk->fops->release)
disk->fops->release(disk, mode);
mutex_unlock(&disk->open_mutex);
+
+ if (test_and_clear_bit(GD_DROP_PARTITIONS, &disk->state)) {
+ mutex_lock(&disk->part_tbl_mutex);
+ blk_drop_partitions(disk);
+ mutex_unlock(&disk->part_tbl_mutex);
+ }
}
static int blkdev_get_part(struct block_device *part, fmode_t mode)
blk_mq_unfreeze_queue(lo->lo_queue);
disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE);
-
- if (lo->lo_flags & LO_FLAGS_PARTSCAN) {
- int err;
-
- err = bdev_disk_changed(lo->lo_disk, false);
- if (err)
- pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
- __func__, lo->lo_number, err);
- /* Device is gone, no point in returning error */
- }
+ set_bit(GD_DROP_PARTITIONS, &lo->lo_disk->state);
lo->lo_flags = 0;
if (!part_shift)
#define GD_READ_ONLY 1
#define GD_DEAD 2
#define GD_NATIVE_CAPACITY 3
+#define GD_DROP_PARTITIONS 4
struct mutex open_mutex; /* open/close mutex */
unsigned open_partitions; /* number of open partitions */