mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02: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
					
				
					 3 changed files with 49 additions and 66 deletions
				
			
		| 
						 | 
				
			
			@ -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,23 +480,29 @@ 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)));
 | 
			
		||||
 | 
			
		||||
	disk->flags |= GENHD_FL_UP;
 | 
			
		||||
 | 
			
		||||
	retval = blk_alloc_devt(disk->part0, &devt);
 | 
			
		||||
	if (retval) {
 | 
			
		||||
		ret = blk_alloc_ext_minor();
 | 
			
		||||
		if (ret < 0) {
 | 
			
		||||
			WARN_ON(1);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	disk->major = MAJOR(devt);
 | 
			
		||||
	disk->first_minor = MINOR(devt);
 | 
			
		||||
		disk->major = BLOCK_EXT_MAJOR;
 | 
			
		||||
		disk->first_minor = MINOR(ret);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	disk->flags |= GENHD_FL_UP;
 | 
			
		||||
 | 
			
		||||
	disk_alloc_events(disk);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
	/* 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 a new issue