From 6917d0689993f46d97d40dd66c601d0fd5b1dbdd Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 14 Nov 2019 15:34:33 +0100 Subject: block: merge invalidate_partitions into rescan_partitions A lot of the logic in invalidate_partitions and rescan_partitions is shared. Merge the two functions to simplify things. There is a small behavior change in that we now send the kevent change notice also if we were not invalidating but no partitions were found, which seems like the right thing to do. Signed-off-by: Christoph Hellwig Reviewed-by: Jan Kara Signed-off-by: Jens Axboe --- include/linux/genhd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux/genhd.h') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 8b5330dd5ac0..fd7774e64f0b 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -622,8 +622,8 @@ extern dev_t blk_lookup_devt(const char *name, int partno); extern char *disk_name (struct gendisk *hd, int partno, char *buf); extern int disk_expand_part_tbl(struct gendisk *disk, int target); -extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); -extern int invalidate_partitions(struct gendisk *disk, struct block_device *bdev); +int rescan_partitions(struct gendisk *disk, struct block_device *bdev, + bool invalidate); extern struct hd_struct * __must_check add_partition(struct gendisk *disk, int partno, sector_t start, sector_t len, int flags, -- cgit v1.2.3-59-g8ed1b From a1548b674403c0de70cc29a1575689917ba60157 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 14 Nov 2019 15:34:34 +0100 Subject: block: move rescan_partitions to fs/block_dev.c Large parts of rescan_partitions aren't about partitions, and moving it to block_dev.c will allow for some further cleanups by merging it into its only caller. Signed-off-by: Christoph Hellwig Reviewed-by: Jan Kara Signed-off-by: Jens Axboe --- block/partition-generic.c | 37 ++----------------------------------- fs/block_dev.c | 38 ++++++++++++++++++++++++++++++++++++-- include/linux/fs.h | 2 -- include/linux/genhd.h | 4 ++-- 4 files changed, 40 insertions(+), 41 deletions(-) (limited to 'include/linux/genhd.h') diff --git a/block/partition-generic.c b/block/partition-generic.c index 6b9f4f5d993a..2cbc23f6032c 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c @@ -439,7 +439,7 @@ static bool disk_unlock_native_capacity(struct gendisk *disk) } } -static int drop_partitions(struct gendisk *disk, struct block_device *bdev) +int blk_drop_partitions(struct gendisk *disk, struct block_device *bdev) { struct disk_part_iter piter; struct hd_struct *part; @@ -509,7 +509,7 @@ static bool blk_add_partition(struct gendisk *disk, struct block_device *bdev, return true; } -static int blk_add_partitions(struct gendisk *disk, struct block_device *bdev) +int blk_add_partitions(struct gendisk *disk, struct block_device *bdev) { struct parsed_partitions *state; int ret = -EAGAIN, p, highest; @@ -576,39 +576,6 @@ out_free_state: return ret; } -int rescan_partitions(struct gendisk *disk, struct block_device *bdev, - bool invalidate) -{ - int ret; - -rescan: - ret = drop_partitions(disk, bdev); - if (ret) - return ret; - - if (invalidate) - set_capacity(disk, 0); - else if (disk->fops->revalidate_disk) - disk->fops->revalidate_disk(disk); - - check_disk_size_change(disk, bdev, !invalidate); - bdev->bd_invalidated = 0; - - if (!get_capacity(disk)) { - /* - * Tell userspace that the media / partition table may have - * changed. - */ - kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); - return 0; - } - - ret = blk_add_partitions(disk, bdev); - if (ret == -EAGAIN) - goto rescan; - return ret; -} - unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) { struct address_space *mapping = bdev->bd_inode->i_mapping; diff --git a/fs/block_dev.c b/fs/block_dev.c index 0af62b76d031..ec10dacd18d0 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1416,8 +1416,8 @@ static void flush_disk(struct block_device *bdev, bool kill_dirty) * and adjusts it if it differs. When shrinking the bdev size, its all caches * are freed. */ -void check_disk_size_change(struct gendisk *disk, struct block_device *bdev, - bool verbose) +static void check_disk_size_change(struct gendisk *disk, + struct block_device *bdev, bool verbose) { loff_t disk_size, bdev_size; @@ -1508,6 +1508,40 @@ EXPORT_SYMBOL(bd_set_size); static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part); +static int rescan_partitions(struct gendisk *disk, struct block_device *bdev, + bool invalidate) +{ + int ret; + +rescan: + ret = blk_drop_partitions(disk, bdev); + if (ret) + return ret; + + if (invalidate) + set_capacity(disk, 0); + else if (disk->fops->revalidate_disk) + disk->fops->revalidate_disk(disk); + + check_disk_size_change(disk, bdev, !invalidate); + bdev->bd_invalidated = 0; + + if (!get_capacity(disk)) { + /* + * Tell userspace that the media / partition table may have + * changed. + */ + kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); + return 0; + } + + ret = blk_add_partitions(disk, bdev); + if (ret == -EAGAIN) + goto rescan; + return ret; +} + + static void bdev_disk_changed(struct block_device *bdev, bool invalidate) { if (disk_part_scan_enabled(bdev->bd_disk)) { diff --git a/include/linux/fs.h b/include/linux/fs.h index e0d909d35763..d233dd661df7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2703,8 +2703,6 @@ extern void make_bad_inode(struct inode *); extern bool is_bad_inode(struct inode *); #ifdef CONFIG_BLOCK -extern void check_disk_size_change(struct gendisk *disk, - struct block_device *bdev, bool verbose); extern int revalidate_disk(struct gendisk *); extern int check_disk_change(struct block_device *); extern int __invalidate_device(struct block_device *, bool); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index fd7774e64f0b..f5cffbf63abf 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -621,9 +621,9 @@ extern void blk_invalidate_devt(dev_t devt); extern dev_t blk_lookup_devt(const char *name, int partno); extern char *disk_name (struct gendisk *hd, int partno, char *buf); +int blk_add_partitions(struct gendisk *disk, struct block_device *bdev); +int blk_drop_partitions(struct gendisk *disk, struct block_device *bdev); extern int disk_expand_part_tbl(struct gendisk *disk, int target); -int rescan_partitions(struct gendisk *disk, struct block_device *bdev, - bool invalidate); extern struct hd_struct * __must_check add_partition(struct gendisk *disk, int partno, sector_t start, sector_t len, int flags, -- cgit v1.2.3-59-g8ed1b From 142fe8f4bb169e8632024d51c64653a8bf140561 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 14 Nov 2019 15:34:35 +0100 Subject: block: fix bdev_disk_changed for non-partitioned devices We still have to set the capacity to 0 if invalidating or call revalidate_disk if not even if the disk has no partitions. Fix that by merging rescan_partitions into bdev_disk_changed and just stubbing out blk_add_partitions and blk_drop_partitions for non-partitioned devices. Signed-off-by: Christoph Hellwig Reviewed-by: Jan Kara Signed-off-by: Jens Axboe --- block/ioctl.c | 6 ++---- block/partition-generic.c | 5 +++++ fs/block_dev.c | 25 +++++++------------------ include/linux/genhd.h | 1 + 4 files changed, 15 insertions(+), 22 deletions(-) (limited to 'include/linux/genhd.h') diff --git a/block/ioctl.c b/block/ioctl.c index f6576a6d5778..5ccd9f016594 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -162,16 +162,14 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user */ int __blkdev_reread_part(struct block_device *bdev) { - struct gendisk *disk = bdev->bd_disk; - - if (!disk_part_scan_enabled(disk) || bdev != bdev->bd_contains) + if (!disk_part_scan_enabled(bdev->bd_disk) || bdev != bdev->bd_contains) return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EACCES; lockdep_assert_held(&bdev->bd_mutex); - return rescan_partitions(disk, bdev, false); + return bdev_disk_changed(bdev, false); } EXPORT_SYMBOL(__blkdev_reread_part); diff --git a/block/partition-generic.c b/block/partition-generic.c index 2cbc23f6032c..61487421a319 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c @@ -445,6 +445,8 @@ int blk_drop_partitions(struct gendisk *disk, struct block_device *bdev) struct hd_struct *part; int res; + if (!disk_part_scan_enabled(disk)) + return 0; if (bdev->bd_part_count || bdev->bd_super) return -EBUSY; res = invalidate_partition(disk, 0); @@ -514,6 +516,9 @@ 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; diff --git a/fs/block_dev.c b/fs/block_dev.c index ec10dacd18d0..ae16466a67f7 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1508,9 +1508,9 @@ EXPORT_SYMBOL(bd_set_size); static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part); -static int rescan_partitions(struct gendisk *disk, struct block_device *bdev, - bool invalidate) +int bdev_disk_changed(struct block_device *bdev, bool invalidate) { + struct gendisk *disk = bdev->bd_disk; int ret; rescan: @@ -1526,32 +1526,21 @@ rescan: check_disk_size_change(disk, bdev, !invalidate); bdev->bd_invalidated = 0; - if (!get_capacity(disk)) { + if (get_capacity(disk)) { + ret = blk_add_partitions(disk, bdev); + if (ret == -EAGAIN) + goto rescan; + } else { /* * Tell userspace that the media / partition table may have * changed. */ kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); - return 0; } - ret = blk_add_partitions(disk, bdev); - if (ret == -EAGAIN) - goto rescan; return ret; } - -static void bdev_disk_changed(struct block_device *bdev, bool invalidate) -{ - if (disk_part_scan_enabled(bdev->bd_disk)) { - rescan_partitions(bdev->bd_disk, bdev, invalidate); - } else { - check_disk_size_change(bdev->bd_disk, bdev, !invalidate); - bdev->bd_invalidated = 0; - } -} - /* * bd_mutex locking: * diff --git a/include/linux/genhd.h b/include/linux/genhd.h index f5cffbf63abf..8bb63027e4d6 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -621,6 +621,7 @@ extern void blk_invalidate_devt(dev_t devt); extern dev_t blk_lookup_devt(const char *name, int partno); extern char *disk_name (struct gendisk *hd, int partno, char *buf); +int bdev_disk_changed(struct block_device *bdev, bool invalidate); int blk_add_partitions(struct gendisk *disk, struct block_device *bdev); int blk_drop_partitions(struct gendisk *disk, struct block_device *bdev); extern int disk_expand_part_tbl(struct gendisk *disk, int target); -- cgit v1.2.3-59-g8ed1b