Commit 22d0c408 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

block: simplify disk_set_independent_access_ranges

Lift setting disk->ia_ranges from disk_register_independent_access_ranges
into disk_set_independent_access_ranges, and make the behavior the same
for the registered vs non-registered queue cases.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDamien Le Moal <damien.lemoal@opensource.wdc.com>
Tested-by: default avatarDamien Le Moal <damien.lemoal@opensource.wdc.com>
Link: https://lore.kernel.org/r/20220629062013.1331068-3-hch@lst.deSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 6a27d28c
...@@ -102,31 +102,18 @@ static struct kobj_type blk_ia_ranges_ktype = { ...@@ -102,31 +102,18 @@ static struct kobj_type blk_ia_ranges_ktype = {
* disk_register_independent_access_ranges - register with sysfs a set of * disk_register_independent_access_ranges - register with sysfs a set of
* independent access ranges * independent access ranges
* @disk: Target disk * @disk: Target disk
* @new_iars: New set of independent access ranges
* *
* Register with sysfs a set of independent access ranges for @disk. * Register with sysfs a set of independent access ranges for @disk.
* If @new_iars is not NULL, this set of ranges is registered and the old set
* specified by disk->ia_ranges is unregistered. Otherwise, disk->ia_ranges is
* registered if it is not already.
*/ */
int disk_register_independent_access_ranges(struct gendisk *disk, int disk_register_independent_access_ranges(struct gendisk *disk)
struct blk_independent_access_ranges *new_iars)
{ {
struct blk_independent_access_ranges *iars = disk->ia_ranges;
struct request_queue *q = disk->queue; struct request_queue *q = disk->queue;
struct blk_independent_access_ranges *iars;
int i, ret; int i, ret;
lockdep_assert_held(&q->sysfs_dir_lock); lockdep_assert_held(&q->sysfs_dir_lock);
lockdep_assert_held(&q->sysfs_lock); lockdep_assert_held(&q->sysfs_lock);
/* If a new range set is specified, unregister the old one */
if (new_iars) {
if (disk->ia_ranges)
disk_unregister_independent_access_ranges(disk);
disk->ia_ranges = new_iars;
}
iars = disk->ia_ranges;
if (!iars) if (!iars)
return 0; return 0;
...@@ -210,6 +197,9 @@ static bool disk_check_ia_ranges(struct gendisk *disk, ...@@ -210,6 +197,9 @@ static bool disk_check_ia_ranges(struct gendisk *disk,
sector_t sector = 0; sector_t sector = 0;
int i; int i;
if (WARN_ON_ONCE(!iars->nr_ia_ranges))
return false;
/* /*
* While sorting the ranges in increasing LBA order, check that the * While sorting the ranges in increasing LBA order, check that the
* ranges do not overlap, that there are no sector holes and that all * ranges do not overlap, that there are no sector holes and that all
...@@ -298,25 +288,15 @@ void disk_set_independent_access_ranges(struct gendisk *disk, ...@@ -298,25 +288,15 @@ void disk_set_independent_access_ranges(struct gendisk *disk,
{ {
struct request_queue *q = disk->queue; struct request_queue *q = disk->queue;
if (WARN_ON_ONCE(iars && !iars->nr_ia_ranges)) { mutex_lock(&q->sysfs_dir_lock);
mutex_lock(&q->sysfs_lock);
if (iars && !disk_check_ia_ranges(disk, iars)) {
kfree(iars); kfree(iars);
iars = NULL; iars = NULL;
} }
if (iars && !disk_ia_ranges_changed(disk, iars)) {
mutex_lock(&q->sysfs_dir_lock); kfree(iars);
mutex_lock(&q->sysfs_lock); goto unlock;
if (iars) {
if (!disk_check_ia_ranges(disk, iars)) {
kfree(iars);
iars = NULL;
goto reg;
}
if (!disk_ia_ranges_changed(disk, iars)) {
kfree(iars);
goto unlock;
}
} }
/* /*
...@@ -324,17 +304,12 @@ void disk_set_independent_access_ranges(struct gendisk *disk, ...@@ -324,17 +304,12 @@ void disk_set_independent_access_ranges(struct gendisk *disk,
* revalidation. If that is the case, we need to unregister the old * revalidation. If that is the case, we need to unregister the old
* set of independent access ranges and register the new set. If the * set of independent access ranges and register the new set. If the
* queue is not registered, registration of the device request queue * queue is not registered, registration of the device request queue
* will register the independent access ranges, so only swap in the * will register the independent access ranges.
* new set and free the old one.
*/ */
reg: disk_unregister_independent_access_ranges(disk);
if (blk_queue_registered(q)) { disk->ia_ranges = iars;
disk_register_independent_access_ranges(disk, iars); if (blk_queue_registered(q))
} else { disk_register_independent_access_ranges(disk);
swap(disk->ia_ranges, iars);
kfree(iars);
}
unlock: unlock:
mutex_unlock(&q->sysfs_lock); mutex_unlock(&q->sysfs_lock);
mutex_unlock(&q->sysfs_dir_lock); mutex_unlock(&q->sysfs_dir_lock);
......
...@@ -832,7 +832,7 @@ int blk_register_queue(struct gendisk *disk) ...@@ -832,7 +832,7 @@ int blk_register_queue(struct gendisk *disk)
blk_mq_debugfs_register(q); blk_mq_debugfs_register(q);
mutex_unlock(&q->debugfs_mutex); mutex_unlock(&q->debugfs_mutex);
ret = disk_register_independent_access_ranges(disk, NULL); ret = disk_register_independent_access_ranges(disk);
if (ret) if (ret)
goto put_dev; goto put_dev;
......
...@@ -459,8 +459,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg); ...@@ -459,8 +459,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg);
extern const struct address_space_operations def_blk_aops; extern const struct address_space_operations def_blk_aops;
int disk_register_independent_access_ranges(struct gendisk *disk, int disk_register_independent_access_ranges(struct gendisk *disk);
struct blk_independent_access_ranges *new_iars);
void disk_unregister_independent_access_ranges(struct gendisk *disk); void disk_unregister_independent_access_ranges(struct gendisk *disk);
#ifdef CONFIG_FAIL_MAKE_REQUEST #ifdef CONFIG_FAIL_MAKE_REQUEST
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment