diff options
Diffstat (limited to 'block/partition-generic.c')
-rw-r--r-- | block/partition-generic.c | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/block/partition-generic.c b/block/partition-generic.c index 8a7906fa96fd..1f51aa8dcc06 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c @@ -460,7 +460,7 @@ static bool disk_unlock_native_capacity(struct gendisk *disk) } } -int blk_drop_partitions(struct gendisk *disk, struct block_device *bdev) +static int drop_partitions(struct gendisk *disk, struct block_device *bdev) { struct disk_part_iter piter; struct hd_struct *part; @@ -532,14 +532,11 @@ 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, highest; - if (!disk_part_scan_enabled(disk)) - return 0; - state = check_partition(disk, bdev); if (!state) return 0; @@ -602,6 +599,49 @@ out_free_state: return ret; } +int rescan_partitions(struct gendisk *disk, struct block_device *bdev) +{ + int ret; + +rescan: + ret = drop_partitions(disk, bdev); + if (ret) + return ret; + + if (disk->fops->revalidate_disk) + disk->fops->revalidate_disk(disk); + check_disk_size_change(disk, bdev, true); + bdev->bd_invalidated = 0; + + if (!get_capacity(disk)) + return 0; + + ret = blk_add_partitions(disk, bdev); + if (ret == -EAGAIN) + goto rescan; + return ret; +} + +int invalidate_partitions(struct gendisk *disk, struct block_device *bdev) +{ + int res; + + if (!bdev->bd_invalidated) + return 0; + + res = drop_partitions(disk, bdev); + if (res) + return res; + + set_capacity(disk, 0); + check_disk_size_change(disk, bdev, false); + bdev->bd_invalidated = 0; + /* tell userspace that the media / partition table may have changed */ + kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); + + return 0; +} + unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) { struct address_space *mapping = bdev->bd_inode->i_mapping; |