Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

block: remove GENHD_FL_EXT_DEVT

All modern drivers can support extra partitions using the extended
dev_t. In fact except for the ioctl method drivers never even see
partitions in normal operation.

So remove the GENHD_FL_EXT_DEVT and allow extra partitions for all
block devices that do support partitions, and require those that
do not support partitions to explicit disallow them using
GENHD_FL_NO_PART.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20211122130625.1136848-12-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christoph Hellwig and committed by
Jens Axboe
1ebe2e5f 3b5149ac

+30 -48
+3 -3
block/genhd.c
··· 376 376 { 377 377 struct block_device *bdev; 378 378 379 - if (!disk_part_scan_enabled(disk)) 379 + if (disk->flags & GENHD_FL_NO_PART) 380 380 return -EINVAL; 381 381 if (disk->open_partitions) 382 382 return -EBUSY; ··· 438 438 return ret; 439 439 disk->major = BLOCK_EXT_MAJOR; 440 440 disk->first_minor = ret; 441 - disk->flags |= GENHD_FL_EXT_DEVT; 442 441 } 443 442 444 443 ret = disk_alloc_events(disk); ··· 871 872 { 872 873 struct gendisk *disk = dev_to_disk(dev); 873 874 874 - return sprintf(buf, "%d\n", disk_max_parts(disk)); 875 + return sprintf(buf, "%d\n", 876 + (disk->flags & GENHD_FL_NO_PART) ? 1 : DISK_MAX_PARTS); 875 877 } 876 878 877 879 static ssize_t disk_removable_show(struct device *dev,
+4 -5
block/partitions/core.c
··· 98 98 static struct parsed_partitions *allocate_partitions(struct gendisk *hd) 99 99 { 100 100 struct parsed_partitions *state; 101 - int nr; 101 + int nr = DISK_MAX_PARTS; 102 102 103 103 state = kzalloc(sizeof(*state), GFP_KERNEL); 104 104 if (!state) 105 105 return NULL; 106 106 107 - nr = disk_max_parts(hd); 108 107 state->parts = vzalloc(array_size(nr, sizeof(state->parts[0]))); 109 108 if (!state->parts) { 110 109 kfree(state); ··· 325 326 326 327 lockdep_assert_held(&disk->open_mutex); 327 328 328 - if (partno >= disk_max_parts(disk)) 329 + if (partno >= DISK_MAX_PARTS) 329 330 return ERR_PTR(-EINVAL); 330 331 331 332 /* ··· 603 604 struct parsed_partitions *state; 604 605 int ret = -EAGAIN, p; 605 606 606 - if (!disk_part_scan_enabled(disk)) 607 + if (disk->flags & GENHD_FL_NO_PART) 607 608 return 0; 608 609 609 610 state = check_partition(disk); ··· 686 687 * userspace for this particular setup. 687 688 */ 688 689 if (invalidate) { 689 - if (disk_part_scan_enabled(disk) || 690 + if (!(disk->flags & GENHD_FL_NO_PART) || 690 691 !(disk->flags & GENHD_FL_REMOVABLE)) 691 692 set_capacity(disk, 0); 692 693 }
+1
drivers/block/amiflop.c
··· 1790 1790 disk->first_minor = drive + system; 1791 1791 disk->minors = 1; 1792 1792 disk->fops = &floppy_fops; 1793 + disk->flags |= GENHD_FL_NO_PART; 1793 1794 disk->events = DISK_EVENT_MEDIA_CHANGE; 1794 1795 if (system) 1795 1796 sprintf(disk->disk_name, "fd%d_msdos", drive);
+1
drivers/block/ataflop.c
··· 2000 2000 disk->minors = 1; 2001 2001 sprintf(disk->disk_name, "fd%d", drive); 2002 2002 disk->fops = &floppy_fops; 2003 + disk->flags |= GENHD_FL_NO_PART; 2003 2004 disk->events = DISK_EVENT_MEDIA_CHANGE; 2004 2005 disk->private_data = &unit[drive]; 2005 2006 set_capacity(disk, MAX_DISK_SIZE * 2);
-1
drivers/block/brd.c
··· 405 405 disk->minors = max_part; 406 406 disk->fops = &brd_fops; 407 407 disk->private_data = brd; 408 - disk->flags = GENHD_FL_EXT_DEVT; 409 408 strlcpy(disk->disk_name, buf, DISK_NAME_LEN); 410 409 set_capacity(disk, rd_size * 2); 411 410
+1
drivers/block/drbd/drbd_main.c
··· 2734 2734 disk->first_minor = minor; 2735 2735 disk->minors = 1; 2736 2736 disk->fops = &drbd_ops; 2737 + disk->flags |= GENHD_FL_NO_PART; 2737 2738 sprintf(disk->disk_name, "drbd%d", minor); 2738 2739 disk->private_data = device; 2739 2740
+1
drivers/block/floppy.c
··· 4503 4503 disk->first_minor = TOMINOR(drive) | (type << 2); 4504 4504 disk->minors = 1; 4505 4505 disk->fops = &floppy_fops; 4506 + disk->flags |= GENHD_FL_NO_PART; 4506 4507 disk->events = DISK_EVENT_MEDIA_CHANGE; 4507 4508 if (type) 4508 4509 sprintf(disk->disk_name, "fd%d_type%d", drive, type);
-1
drivers/block/loop.c
··· 2033 2033 */ 2034 2034 if (!part_shift) 2035 2035 disk->flags |= GENHD_FL_NO_PART; 2036 - disk->flags |= GENHD_FL_EXT_DEVT; 2037 2036 atomic_set(&lo->lo_refcnt, 0); 2038 2037 mutex_init(&lo->lo_mutex); 2039 2038 lo->lo_number = i;
-1
drivers/block/null_blk/main.c
··· 1850 1850 1851 1851 set_capacity(disk, size); 1852 1852 1853 - disk->flags |= GENHD_FL_EXT_DEVT; 1854 1853 disk->major = null_major; 1855 1854 disk->first_minor = nullb->index; 1856 1855 disk->minors = 1;
+1
drivers/block/paride/pcd.c
··· 928 928 disk->minors = 1; 929 929 strcpy(disk->disk_name, cd->name); /* umm... */ 930 930 disk->fops = &pcd_bdops; 931 + disk->flags |= GENHD_FL_NO_PART; 931 932 disk->events = DISK_EVENT_MEDIA_CHANGE; 932 933 disk->event_flags = DISK_EVENT_FLAG_BLOCK_ON_EXCL_WRITE; 933 934
+1
drivers/block/paride/pf.c
··· 942 942 disk->minors = 1; 943 943 strcpy(disk->disk_name, pf->name); 944 944 disk->fops = &pf_fops; 945 + disk->flags |= GENHD_FL_NO_PART; 945 946 disk->events = DISK_EVENT_MEDIA_CHANGE; 946 947 disk->private_data = pf; 947 948
+1 -1
drivers/block/pktcdvd.c
··· 2719 2719 disk->first_minor = idx; 2720 2720 disk->minors = 1; 2721 2721 disk->fops = &pktcdvd_ops; 2722 - disk->flags = GENHD_FL_REMOVABLE; 2722 + disk->flags = GENHD_FL_REMOVABLE | GENHD_FL_NO_PART; 2723 2723 strcpy(disk->disk_name, pd->name); 2724 2724 disk->private_data = pd; 2725 2725
+1
drivers/block/ps3vram.c
··· 742 742 priv->gendisk = gendisk; 743 743 gendisk->major = ps3vram_major; 744 744 gendisk->minors = 1; 745 + gendisk->flags |= GENHD_FL_NO_PART; 745 746 gendisk->fops = &ps3vram_fops; 746 747 gendisk->private_data = dev; 747 748 strlcpy(gendisk->disk_name, DEVICE_NAME, sizeof(gendisk->disk_name));
+2 -4
drivers/block/rbd.c
··· 4924 4924 rbd_dev->dev_id); 4925 4925 disk->major = rbd_dev->major; 4926 4926 disk->first_minor = rbd_dev->minor; 4927 - if (single_major) { 4927 + if (single_major) 4928 4928 disk->minors = (1 << RBD_SINGLE_MAJOR_PART_SHIFT); 4929 - disk->flags |= GENHD_FL_EXT_DEVT; 4930 - } else { 4929 + else 4931 4930 disk->minors = RBD_MINORS_PER_MAJOR; 4932 - } 4933 4931 disk->fops = &rbd_bd_ops; 4934 4932 disk->private_data = rbd_dev; 4935 4933
+1
drivers/block/swim.c
··· 840 840 swd->unit[drive].disk->minors = 1; 841 841 sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive); 842 842 swd->unit[drive].disk->fops = &floppy_fops; 843 + swd->unit[drive].disk->flags |= GENHD_FL_NO_PART; 843 844 swd->unit[drive].disk->events = DISK_EVENT_MEDIA_CHANGE; 844 845 swd->unit[drive].disk->private_data = &swd->unit[drive]; 845 846 set_capacity(swd->unit[drive].disk, 2880);
+1 -1
drivers/block/swim3.c
··· 1227 1227 disk->fops = &floppy_fops; 1228 1228 disk->private_data = fs; 1229 1229 disk->events = DISK_EVENT_MEDIA_CHANGE; 1230 - disk->flags |= GENHD_FL_REMOVABLE; 1230 + disk->flags |= GENHD_FL_REMOVABLE | GENHD_FL_NO_PART; 1231 1231 sprintf(disk->disk_name, "fd%d", floppy_count); 1232 1232 set_capacity(disk, 2880); 1233 1233 rc = add_disk(disk);
-1
drivers/block/virtio_blk.c
··· 843 843 vblk->disk->minors = 1 << PART_BITS; 844 844 vblk->disk->private_data = vblk; 845 845 vblk->disk->fops = &virtblk_fops; 846 - vblk->disk->flags |= GENHD_FL_EXT_DEVT; 847 846 vblk->index = index; 848 847 849 848 /* configure queue flush support */
+1
drivers/block/z2ram.c
··· 327 327 disk->major = Z2RAM_MAJOR; 328 328 disk->first_minor = minor; 329 329 disk->minors = 1; 330 + disk->flags |= GENHD_FL_NO_PART; 330 331 disk->fops = &z2_fops; 331 332 if (minor) 332 333 sprintf(disk->disk_name, "z2ram%d", minor);
+1
drivers/block/zram/zram_drv.c
··· 1947 1947 zram->disk->major = zram_major; 1948 1948 zram->disk->first_minor = device_id; 1949 1949 zram->disk->minors = 1; 1950 + zram->disk->flags |= GENHD_FL_NO_PART; 1950 1951 zram->disk->fops = &zram_devops; 1951 1952 zram->disk->private_data = zram; 1952 1953 snprintf(zram->disk->disk_name, 16, "zram%d", device_id);
+1
drivers/cdrom/gdrom.c
··· 719 719 gd.disk->major = gdrom_major; 720 720 gd.disk->first_minor = 1; 721 721 gd.disk->minors = 1; 722 + gd.disk->flags |= GENHD_FL_NO_PART; 722 723 strcpy(gd.disk->disk_name, GDROM_DEV_NAME); 723 724 } 724 725
+1
drivers/md/dm.c
··· 1778 1778 md->disk->major = _major; 1779 1779 md->disk->first_minor = minor; 1780 1780 md->disk->minors = 1; 1781 + md->disk->flags |= GENHD_FL_NO_PART; 1781 1782 md->disk->fops = &dm_blk_dops; 1782 1783 md->disk->queue = md->queue; 1783 1784 md->disk->private_data = md;
-5
drivers/md/md.c
··· 5707 5707 mddev->queue = disk->queue; 5708 5708 blk_set_stacking_limits(&mddev->queue->limits); 5709 5709 blk_queue_write_cache(mddev->queue, true, true); 5710 - /* Allow extended partitions. This makes the 5711 - * 'mdp' device redundant, but we can't really 5712 - * remove it now. 5713 - */ 5714 - disk->flags |= GENHD_FL_EXT_DEVT; 5715 5710 disk->events |= DISK_EVENT_MEDIA_CHANGE; 5716 5711 mddev->gendisk = disk; 5717 5712 error = add_disk(disk);
-1
drivers/mmc/core/block.c
··· 2395 2395 md->disk->private_data = md; 2396 2396 md->parent = parent; 2397 2397 set_disk_ro(md->disk, md->read_only || default_ro); 2398 - md->disk->flags = GENHD_FL_EXT_DEVT; 2399 2398 if (area_type & (MMC_BLK_DATA_AREA_RPMB | MMC_BLK_DATA_AREA_BOOT)) 2400 2399 md->disk->flags |= GENHD_FL_NO_PART; 2401 2400
+1
drivers/mtd/ubi/block.c
··· 430 430 ret = -ENODEV; 431 431 goto out_cleanup_disk; 432 432 } 433 + gd->flags |= GENHD_FL_NO_PART; 433 434 gd->private_data = dev; 434 435 sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id); 435 436 set_capacity(gd, disk_capacity);
-1
drivers/scsi/sd.c
··· 3566 3566 3567 3567 sd_revalidate_disk(gd); 3568 3568 3569 - gd->flags = GENHD_FL_EXT_DEVT; 3570 3569 if (sdp->removable) { 3571 3570 gd->flags |= GENHD_FL_REMOVABLE; 3572 3571 gd->events |= DISK_EVENT_MEDIA_CHANGE;
+1
drivers/scsi/sr.c
··· 684 684 disk->minors = 1; 685 685 sprintf(disk->disk_name, "sr%d", minor); 686 686 disk->fops = &sr_bdops; 687 + disk->flags |= GENHD_FL_NO_PART; 687 688 disk->events = DISK_EVENT_MEDIA_CHANGE | DISK_EVENT_EJECT_REQUEST; 688 689 disk->event_flags = DISK_EVENT_FLAG_POLL | DISK_EVENT_FLAG_UEVENT | 689 690 DISK_EVENT_FLAG_BLOCK_ON_EXCL_WRITE;
+5 -23
include/linux/genhd.h
··· 46 46 * Must not be set for devices which are removed entirely when the 47 47 * media is removed. 48 48 * 49 - * ``GENHD_FL_EXT_DEVT`` (0x0040): the driver supports extended 50 - * dynamic ``dev_t``, i.e. it wants extended device numbers 51 - * (``BLOCK_EXT_MAJOR``). 52 - * This affects the maximum number of partitions. 53 - * 54 49 * ``GENHD_FL_NO_PART`` (0x0200): partition support is disabled. 55 50 * The kernel will not scan for partitions from add_disk, and users 56 51 * can't add partitions manually. ··· 59 64 #define GENHD_FL_REMOVABLE 0x0001 60 65 /* 2 is unused (used to be GENHD_FL_DRIVERFS) */ 61 66 /* 4 is unused (used to be GENHD_FL_MEDIA_CHANGE_NOTIFY) */ 62 - #define GENHD_FL_EXT_DEVT 0x0040 63 67 #define GENHD_FL_NO_PART 0x0200 64 68 #define GENHD_FL_HIDDEN 0x0400 65 69 ··· 88 94 }; 89 95 90 96 struct gendisk { 91 - /* major, first_minor and minors are input parameters only, 92 - * don't use directly. Use disk_devt() and disk_max_parts(). 97 + /* 98 + * major/first_minor/minors should not be set by any new driver, the 99 + * block core will take care of allocating them automatically. 93 100 */ 94 - int major; /* major number of driver */ 101 + int major; 95 102 int first_minor; 96 - int minors; /* maximum number of minors, =1 for 97 - * disks that can't be partitioned. */ 103 + int minors; 98 104 99 105 char disk_name[DISK_NAME_LEN]; /* name of major driver */ 100 106 ··· 157 163 #else 158 164 #define disk_to_cdi(disk) NULL 159 165 #endif 160 - 161 - static inline int disk_max_parts(struct gendisk *disk) 162 - { 163 - if (disk->flags & GENHD_FL_EXT_DEVT) 164 - return DISK_MAX_PARTS; 165 - return disk->minors; 166 - } 167 - 168 - static inline bool disk_part_scan_enabled(struct gendisk *disk) 169 - { 170 - return disk_max_parts(disk) > 1 && !(disk->flags & GENHD_FL_NO_PART); 171 - } 172 166 173 167 static inline dev_t disk_devt(struct gendisk *disk) 174 168 {