diff options
author | Christoph Hellwig <hch@lst.de> | 2021-06-24 15:32:39 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2021-06-24 21:01:06 +0300 |
commit | 630161cfdf5cdc696a82b59410d1ff00b23d946e (patch) | |
tree | d84d056d9038e311454ca852b8da9057a3a5173b /block | |
parent | 2bc8cda5ea4b42ff78be1b11011092d57b424d37 (diff) | |
download | linux-630161cfdf5cdc696a82b59410d1ff00b23d946e.tar.xz |
block: move bdev_disk_changed
Move bdev_disk_changed to block/partitions/core.c, together with the
rest of the partition scanning code.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20210624123240.441814-2-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r-- | block/partitions/core.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/block/partitions/core.c b/block/partitions/core.c index 186d4fbd9f09..b79785f7027c 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -596,7 +596,7 @@ static bool blk_add_partition(struct gendisk *disk, struct block_device *bdev, return true; } -int blk_add_partitions(struct gendisk *disk, struct block_device *bdev) +static int blk_add_partitions(struct gendisk *disk, struct block_device *bdev) { struct parsed_partitions *state; int ret = -EAGAIN, p; @@ -657,6 +657,59 @@ out_free_state: return ret; } +int bdev_disk_changed(struct block_device *bdev, bool invalidate) +{ + struct gendisk *disk = bdev->bd_disk; + int ret = 0; + + lockdep_assert_held(&disk->open_mutex); + + if (!(disk->flags & GENHD_FL_UP)) + return -ENXIO; + +rescan: + if (disk->open_partitions) + return -EBUSY; + sync_blockdev(bdev); + invalidate_bdev(bdev); + blk_drop_partitions(disk); + + clear_bit(GD_NEED_PART_SCAN, &disk->state); + + /* + * Historically we only set the capacity to zero for devices that + * support partitions (independ of actually having partitions created). + * Doing that is rather inconsistent, but changing it broke legacy + * udisks polling for legacy ide-cdrom devices. Use the crude check + * below to get the sane behavior for most device while not breaking + * userspace for this particular setup. + */ + if (invalidate) { + if (disk_part_scan_enabled(disk) || + !(disk->flags & GENHD_FL_REMOVABLE)) + set_capacity(disk, 0); + } + + if (get_capacity(disk)) { + ret = blk_add_partitions(disk, bdev); + if (ret == -EAGAIN) + goto rescan; + } else if (invalidate) { + /* + * Tell userspace that the media / partition table may have + * changed. + */ + kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); + } + + return ret; +} +/* + * Only exported for loop and dasd for historic reasons. Don't use in new + * code! + */ +EXPORT_SYMBOL_GPL(bdev_disk_changed); + void *read_part_sector(struct parsed_partitions *state, sector_t n, Sector *p) { struct address_space *mapping = state->bdev->bd_inode->i_mapping; |