Skip to content

Commit 7c3f828

Browse files
Christoph Hellwigaxboe
authored andcommitted
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 <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: Luis Chamberlain <[email protected]> Reviewed-by: Ulf Hansson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent d97e594 commit 7c3f828

File tree

3 files changed

+49
-66
lines changed

3 files changed

+49
-66
lines changed

block/blk.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,8 @@ static inline void blk_queue_free_zone_bitmaps(struct request_queue *q) {}
343343
static inline void blk_queue_clear_zone_settings(struct request_queue *q) {}
344344
#endif
345345

346-
int blk_alloc_devt(struct block_device *part, dev_t *devt);
347-
void blk_free_devt(dev_t devt);
346+
int blk_alloc_ext_minor(void);
347+
void blk_free_ext_minor(unsigned int minor);
348348
char *disk_name(struct gendisk *hd, int partno, char *buf);
349349
#define ADDPART_FLAG_NONE 0
350350
#define ADDPART_FLAG_RAID 1

block/genhd.c

Lines changed: 36 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -333,52 +333,22 @@ static int blk_mangle_minor(int minor)
333333
return minor;
334334
}
335335

336-
/**
337-
* blk_alloc_devt - allocate a dev_t for a block device
338-
* @bdev: block device to allocate dev_t for
339-
* @devt: out parameter for resulting dev_t
340-
*
341-
* Allocate a dev_t for block device.
342-
*
343-
* RETURNS:
344-
* 0 on success, allocated dev_t is returned in *@devt. -errno on
345-
* failure.
346-
*
347-
* CONTEXT:
348-
* Might sleep.
349-
*/
350-
int blk_alloc_devt(struct block_device *bdev, dev_t *devt)
336+
int blk_alloc_ext_minor(void)
351337
{
352-
struct gendisk *disk = bdev->bd_disk;
353338
int idx;
354339

355-
/* in consecutive minor range? */
356-
if (bdev->bd_partno < disk->minors) {
357-
*devt = MKDEV(disk->major, disk->first_minor + bdev->bd_partno);
358-
return 0;
359-
}
360-
361340
idx = ida_alloc_range(&ext_devt_ida, 0, NR_EXT_DEVT, GFP_KERNEL);
362-
if (idx < 0)
363-
return idx == -ENOSPC ? -EBUSY : idx;
364-
365-
*devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx));
366-
return 0;
341+
if (idx < 0) {
342+
if (idx == -ENOSPC)
343+
return -EBUSY;
344+
return idx;
345+
}
346+
return blk_mangle_minor(idx);
367347
}
368348

369-
/**
370-
* blk_free_devt - free a dev_t
371-
* @devt: dev_t to free
372-
*
373-
* Free @devt which was allocated using blk_alloc_devt().
374-
*
375-
* CONTEXT:
376-
* Might sleep.
377-
*/
378-
void blk_free_devt(dev_t devt)
349+
void blk_free_ext_minor(unsigned int minor)
379350
{
380-
if (MAJOR(devt) == BLOCK_EXT_MAJOR)
381-
ida_free(&ext_devt_ida, blk_mangle_minor(MINOR(devt)));
351+
ida_free(&ext_devt_ida, blk_mangle_minor(minor));
382352
}
383353

384354
static char *bdevt_str(dev_t devt, char *buf)
@@ -499,8 +469,7 @@ static void __device_add_disk(struct device *parent, struct gendisk *disk,
499469
const struct attribute_group **groups,
500470
bool register_queue)
501471
{
502-
dev_t devt;
503-
int retval;
472+
int ret;
504473

505474
/*
506475
* 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,
511480
if (register_queue)
512481
elevator_init_mq(disk->queue);
513482

514-
/* minors == 0 indicates to use ext devt from part0 and should
515-
* be accompanied with EXT_DEVT flag. Make sure all
516-
* parameters make sense.
483+
/*
484+
* If the driver provides an explicit major number it also must provide
485+
* the number of minors numbers supported, and those will be used to
486+
* setup the gendisk.
487+
* Otherwise just allocate the device numbers for both the whole device
488+
* and all partitions from the extended dev_t space.
517489
*/
518-
WARN_ON(disk->minors && !(disk->major || disk->first_minor));
519-
WARN_ON(!disk->minors &&
520-
!(disk->flags & (GENHD_FL_EXT_DEVT | GENHD_FL_HIDDEN)));
521-
522-
disk->flags |= GENHD_FL_UP;
490+
if (disk->major) {
491+
WARN_ON(!disk->minors);
492+
} else {
493+
WARN_ON(disk->minors);
494+
WARN_ON(!(disk->flags & (GENHD_FL_EXT_DEVT | GENHD_FL_HIDDEN)));
523495

524-
retval = blk_alloc_devt(disk->part0, &devt);
525-
if (retval) {
526-
WARN_ON(1);
527-
return;
496+
ret = blk_alloc_ext_minor();
497+
if (ret < 0) {
498+
WARN_ON(1);
499+
return;
500+
}
501+
disk->major = BLOCK_EXT_MAJOR;
502+
disk->first_minor = MINOR(ret);
528503
}
529-
disk->major = MAJOR(devt);
530-
disk->first_minor = MINOR(devt);
504+
505+
disk->flags |= GENHD_FL_UP;
531506

532507
disk_alloc_events(disk);
533508

@@ -541,14 +516,14 @@ static void __device_add_disk(struct device *parent, struct gendisk *disk,
541516
} else {
542517
struct backing_dev_info *bdi = disk->queue->backing_dev_info;
543518
struct device *dev = disk_to_dev(disk);
544-
int ret;
545519

546520
/* Register BDI before referencing it from bdev */
547-
dev->devt = devt;
548-
ret = bdi_register(bdi, "%u:%u", MAJOR(devt), MINOR(devt));
521+
dev->devt = MKDEV(disk->major, disk->first_minor);
522+
ret = bdi_register(bdi, "%u:%u",
523+
disk->major, disk->first_minor);
549524
WARN_ON(ret);
550525
bdi_set_owner(bdi, dev);
551-
bdev_add(disk->part0, devt);
526+
bdev_add(disk->part0, dev->devt);
552527
}
553528
register_disk(parent, disk, groups);
554529
if (register_queue)
@@ -1120,7 +1095,8 @@ static void disk_release(struct device *dev)
11201095

11211096
might_sleep();
11221097

1123-
blk_free_devt(dev->devt);
1098+
if (MAJOR(dev->devt) == BLOCK_EXT_MAJOR)
1099+
blk_free_ext_minor(MINOR(dev->devt));
11241100
disk_release_events(disk);
11251101
kfree(disk->random);
11261102
xa_destroy(&disk->part_tbl);

block/partitions/core.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,8 @@ static const struct attribute_group *part_attr_groups[] = {
260260

261261
static void part_release(struct device *dev)
262262
{
263-
blk_free_devt(dev->devt);
263+
if (MAJOR(dev->devt) == BLOCK_EXT_MAJOR)
264+
blk_free_ext_minor(MINOR(dev->devt));
264265
bdput(dev_to_bdev(dev));
265266
}
266267

@@ -379,9 +380,15 @@ static struct block_device *add_partition(struct gendisk *disk, int partno,
379380
pdev->type = &part_type;
380381
pdev->parent = ddev;
381382

382-
err = blk_alloc_devt(bdev, &devt);
383-
if (err)
384-
goto out_put;
383+
/* in consecutive minor range? */
384+
if (bdev->bd_partno < disk->minors) {
385+
devt = MKDEV(disk->major, disk->first_minor + bdev->bd_partno);
386+
} else {
387+
err = blk_alloc_ext_minor();
388+
if (err < 0)
389+
goto out_put;
390+
devt = MKDEV(BLOCK_EXT_MAJOR, err);
391+
}
385392
pdev->devt = devt;
386393

387394
/* delay uevent until 'holders' subdir is created */

0 commit comments

Comments
 (0)