mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
block: refactor device number setup in __device_add_disk
Untangle the mess around blk_alloc_devt by moving the check for the used allocation scheme into the callers. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Link: https://lore.kernel.org/r/20210521055116.1053587-2-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
d97e594c51
commit
7c3f828b52
@ -343,8 +343,8 @@ static inline void blk_queue_free_zone_bitmaps(struct request_queue *q) {}
|
||||
static inline void blk_queue_clear_zone_settings(struct request_queue *q) {}
|
||||
#endif
|
||||
|
||||
int blk_alloc_devt(struct block_device *part, dev_t *devt);
|
||||
void blk_free_devt(dev_t devt);
|
||||
int blk_alloc_ext_minor(void);
|
||||
void blk_free_ext_minor(unsigned int minor);
|
||||
char *disk_name(struct gendisk *hd, int partno, char *buf);
|
||||
#define ADDPART_FLAG_NONE 0
|
||||
#define ADDPART_FLAG_RAID 1
|
||||
|
@ -333,52 +333,22 @@ static int blk_mangle_minor(int minor)
|
||||
return minor;
|
||||
}
|
||||
|
||||
/**
|
||||
* blk_alloc_devt - allocate a dev_t for a block device
|
||||
* @bdev: block device to allocate dev_t for
|
||||
* @devt: out parameter for resulting dev_t
|
||||
*
|
||||
* Allocate a dev_t for block device.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 on success, allocated dev_t is returned in *@devt. -errno on
|
||||
* failure.
|
||||
*
|
||||
* CONTEXT:
|
||||
* Might sleep.
|
||||
*/
|
||||
int blk_alloc_devt(struct block_device *bdev, dev_t *devt)
|
||||
int blk_alloc_ext_minor(void)
|
||||
{
|
||||
struct gendisk *disk = bdev->bd_disk;
|
||||
int idx;
|
||||
|
||||
/* in consecutive minor range? */
|
||||
if (bdev->bd_partno < disk->minors) {
|
||||
*devt = MKDEV(disk->major, disk->first_minor + bdev->bd_partno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
idx = ida_alloc_range(&ext_devt_ida, 0, NR_EXT_DEVT, GFP_KERNEL);
|
||||
if (idx < 0)
|
||||
return idx == -ENOSPC ? -EBUSY : idx;
|
||||
|
||||
*devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx));
|
||||
return 0;
|
||||
if (idx < 0) {
|
||||
if (idx == -ENOSPC)
|
||||
return -EBUSY;
|
||||
return idx;
|
||||
}
|
||||
return blk_mangle_minor(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* blk_free_devt - free a dev_t
|
||||
* @devt: dev_t to free
|
||||
*
|
||||
* Free @devt which was allocated using blk_alloc_devt().
|
||||
*
|
||||
* CONTEXT:
|
||||
* Might sleep.
|
||||
*/
|
||||
void blk_free_devt(dev_t devt)
|
||||
void blk_free_ext_minor(unsigned int minor)
|
||||
{
|
||||
if (MAJOR(devt) == BLOCK_EXT_MAJOR)
|
||||
ida_free(&ext_devt_ida, blk_mangle_minor(MINOR(devt)));
|
||||
ida_free(&ext_devt_ida, blk_mangle_minor(minor));
|
||||
}
|
||||
|
||||
static char *bdevt_str(dev_t devt, char *buf)
|
||||
@ -499,8 +469,7 @@ static void __device_add_disk(struct device *parent, struct gendisk *disk,
|
||||
const struct attribute_group **groups,
|
||||
bool register_queue)
|
||||
{
|
||||
dev_t devt;
|
||||
int retval;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* The disk queue should now be all set with enough information about
|
||||
@ -511,24 +480,30 @@ static void __device_add_disk(struct device *parent, struct gendisk *disk,
|
||||
if (register_queue)
|
||||
elevator_init_mq(disk->queue);
|
||||
|
||||
/* minors == 0 indicates to use ext devt from part0 and should
|
||||
* be accompanied with EXT_DEVT flag. Make sure all
|
||||
* parameters make sense.
|
||||
/*
|
||||
* If the driver provides an explicit major number it also must provide
|
||||
* the number of minors numbers supported, and those will be used to
|
||||
* setup the gendisk.
|
||||
* Otherwise just allocate the device numbers for both the whole device
|
||||
* and all partitions from the extended dev_t space.
|
||||
*/
|
||||
WARN_ON(disk->minors && !(disk->major || disk->first_minor));
|
||||
WARN_ON(!disk->minors &&
|
||||
!(disk->flags & (GENHD_FL_EXT_DEVT | GENHD_FL_HIDDEN)));
|
||||
if (disk->major) {
|
||||
WARN_ON(!disk->minors);
|
||||
} else {
|
||||
WARN_ON(disk->minors);
|
||||
WARN_ON(!(disk->flags & (GENHD_FL_EXT_DEVT | GENHD_FL_HIDDEN)));
|
||||
|
||||
ret = blk_alloc_ext_minor();
|
||||
if (ret < 0) {
|
||||
WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
disk->major = BLOCK_EXT_MAJOR;
|
||||
disk->first_minor = MINOR(ret);
|
||||
}
|
||||
|
||||
disk->flags |= GENHD_FL_UP;
|
||||
|
||||
retval = blk_alloc_devt(disk->part0, &devt);
|
||||
if (retval) {
|
||||
WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
disk->major = MAJOR(devt);
|
||||
disk->first_minor = MINOR(devt);
|
||||
|
||||
disk_alloc_events(disk);
|
||||
|
||||
if (disk->flags & GENHD_FL_HIDDEN) {
|
||||
@ -541,14 +516,14 @@ static void __device_add_disk(struct device *parent, struct gendisk *disk,
|
||||
} else {
|
||||
struct backing_dev_info *bdi = disk->queue->backing_dev_info;
|
||||
struct device *dev = disk_to_dev(disk);
|
||||
int ret;
|
||||
|
||||
/* Register BDI before referencing it from bdev */
|
||||
dev->devt = devt;
|
||||
ret = bdi_register(bdi, "%u:%u", MAJOR(devt), MINOR(devt));
|
||||
dev->devt = MKDEV(disk->major, disk->first_minor);
|
||||
ret = bdi_register(bdi, "%u:%u",
|
||||
disk->major, disk->first_minor);
|
||||
WARN_ON(ret);
|
||||
bdi_set_owner(bdi, dev);
|
||||
bdev_add(disk->part0, devt);
|
||||
bdev_add(disk->part0, dev->devt);
|
||||
}
|
||||
register_disk(parent, disk, groups);
|
||||
if (register_queue)
|
||||
@ -1120,7 +1095,8 @@ static void disk_release(struct device *dev)
|
||||
|
||||
might_sleep();
|
||||
|
||||
blk_free_devt(dev->devt);
|
||||
if (MAJOR(dev->devt) == BLOCK_EXT_MAJOR)
|
||||
blk_free_ext_minor(MINOR(dev->devt));
|
||||
disk_release_events(disk);
|
||||
kfree(disk->random);
|
||||
xa_destroy(&disk->part_tbl);
|
||||
|
@ -260,7 +260,8 @@ static const struct attribute_group *part_attr_groups[] = {
|
||||
|
||||
static void part_release(struct device *dev)
|
||||
{
|
||||
blk_free_devt(dev->devt);
|
||||
if (MAJOR(dev->devt) == BLOCK_EXT_MAJOR)
|
||||
blk_free_ext_minor(MINOR(dev->devt));
|
||||
bdput(dev_to_bdev(dev));
|
||||
}
|
||||
|
||||
@ -379,9 +380,15 @@ static struct block_device *add_partition(struct gendisk *disk, int partno,
|
||||
pdev->type = &part_type;
|
||||
pdev->parent = ddev;
|
||||
|
||||
err = blk_alloc_devt(bdev, &devt);
|
||||
if (err)
|
||||
goto out_put;
|
||||
/* in consecutive minor range? */
|
||||
if (bdev->bd_partno < disk->minors) {
|
||||
devt = MKDEV(disk->major, disk->first_minor + bdev->bd_partno);
|
||||
} else {
|
||||
err = blk_alloc_ext_minor();
|
||||
if (err < 0)
|
||||
goto out_put;
|
||||
devt = MKDEV(BLOCK_EXT_MAJOR, err);
|
||||
}
|
||||
pdev->devt = devt;
|
||||
|
||||
/* delay uevent until 'holders' subdir is created */
|
||||
|
Loading…
Reference in New Issue
Block a user