Commit 3e1a7ff8a0a7b948f2684930166954f9e8e776fe

Authored by Tejun Heo
Committed by Jens Axboe
1 parent 689d6fac40

block: allow disk to have extended device number

Now that disk and partition handlings are mostly unified, it's easy to
allow disk to have extended device number.  This patch makes
add_disk() use extended device number if disk->minors is zero.  Both
sd and ide-disk are updated to use this.

* sd_format_disk_name() is implemented which can generically determine
  the drive name.  This removes disk number restriction stemming from
  limited device names.

* If sd index goes over SD_MAX_DISKS (which can be increased now BTW),
  sd simply doesn't initialize minors letting block layer choose
  extended device number.

* If CONFIG_DEBUG_EXT_DEVT is set, both sd and ide-disk always set
  minors to 0 and use extended device numbers.

Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

Showing 5 changed files with 82 additions and 23 deletions Side-by-side Diff

... ... @@ -478,14 +478,37 @@
478 478 *
479 479 * This function registers the partitioning information in @disk
480 480 * with the kernel.
  481 + *
  482 + * FIXME: error handling
481 483 */
482 484 void add_disk(struct gendisk *disk)
483 485 {
484 486 struct backing_dev_info *bdi;
  487 + dev_t devt;
485 488 int retval;
486 489  
  490 + /* minors == 0 indicates to use ext devt from part0 and should
  491 + * be accompanied with EXT_DEVT flag. Make sure all
  492 + * parameters make sense.
  493 + */
  494 + WARN_ON(disk->minors && !(disk->major || disk->first_minor));
  495 + WARN_ON(!disk->minors && !(disk->flags & GENHD_FL_EXT_DEVT));
  496 +
487 497 disk->flags |= GENHD_FL_UP;
488   - disk_to_dev(disk)->devt = MKDEV(disk->major, disk->first_minor);
  498 +
  499 + retval = blk_alloc_devt(&disk->part0, &devt);
  500 + if (retval) {
  501 + WARN_ON(1);
  502 + return;
  503 + }
  504 + disk_to_dev(disk)->devt = devt;
  505 +
  506 + /* ->major and ->first_minor aren't supposed to be
  507 + * dereferenced from here on, but set them just in case.
  508 + */
  509 + disk->major = MAJOR(devt);
  510 + disk->first_minor = MINOR(devt);
  511 +
489 512 blk_register_region(disk_devt(disk), disk->minors, NULL,
490 513 exact_match, exact_lock, disk);
491 514 register_disk(disk);
drivers/ide/ide-disk.c
... ... @@ -44,7 +44,7 @@
44 44 #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
45 45 #define IDE_DISK_MINORS (1 << PARTN_BITS)
46 46 #else
47   -#define IDE_DISK_MINORS 1
  47 +#define IDE_DISK_MINORS 0
48 48 #endif
49 49  
50 50 struct ide_disk_obj {
... ... @@ -89,7 +89,7 @@
89 89 #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
90 90 #define SD_MINORS 16
91 91 #else
92   -#define SD_MINORS 1
  92 +#define SD_MINORS 0
93 93 #endif
94 94  
95 95 static int sd_revalidate_disk(struct gendisk *);
... ... @@ -1770,6 +1770,52 @@
1770 1770 }
1771 1771  
1772 1772 /**
  1773 + * sd_format_disk_name - format disk name
  1774 + * @prefix: name prefix - ie. "sd" for SCSI disks
  1775 + * @index: index of the disk to format name for
  1776 + * @buf: output buffer
  1777 + * @buflen: length of the output buffer
  1778 + *
  1779 + * SCSI disk names starts at sda. The 26th device is sdz and the
  1780 + * 27th is sdaa. The last one for two lettered suffix is sdzz
  1781 + * which is followed by sdaaa.
  1782 + *
  1783 + * This is basically 26 base counting with one extra 'nil' entry
  1784 + * at the beggining from the second digit on and can be
  1785 + * determined using similar method as 26 base conversion with the
  1786 + * index shifted -1 after each digit is computed.
  1787 + *
  1788 + * CONTEXT:
  1789 + * Don't care.
  1790 + *
  1791 + * RETURNS:
  1792 + * 0 on success, -errno on failure.
  1793 + */
  1794 +static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
  1795 +{
  1796 + const int base = 'z' - 'a' + 1;
  1797 + char *begin = buf + strlen(prefix);
  1798 + char *end = buf + buflen;
  1799 + char *p;
  1800 + int unit;
  1801 +
  1802 + p = end - 1;
  1803 + *p = '\0';
  1804 + unit = base;
  1805 + do {
  1806 + if (p == begin)
  1807 + return -EINVAL;
  1808 + *--p = 'a' + (index % unit);
  1809 + index = (index / unit) - 1;
  1810 + } while (index >= 0);
  1811 +
  1812 + memmove(begin, p, end - p);
  1813 + memcpy(buf, prefix, strlen(prefix));
  1814 +
  1815 + return 0;
  1816 +}
  1817 +
  1818 +/**
1773 1819 * sd_probe - called during driver initialization and whenever a
1774 1820 * new scsi device is attached to the system. It is called once
1775 1821 * for each scsi device (not just disks) present.
... ... @@ -1821,8 +1867,8 @@
1821 1867 if (error)
1822 1868 goto out_put;
1823 1869  
1824   - error = -EBUSY;
1825   - if (index >= SD_MAX_DISKS)
  1870 + error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN);
  1871 + if (error)
1826 1872 goto out_free_index;
1827 1873  
1828 1874 sdkp->device = sdp;
1829 1875  
... ... @@ -1849,24 +1895,12 @@
1849 1895  
1850 1896 get_device(&sdp->sdev_gendev);
1851 1897  
1852   - gd->major = sd_major((index & 0xf0) >> 4);
1853   - gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
1854   - gd->minors = SD_MINORS;
1855   - gd->fops = &sd_fops;
1856   -
1857   - if (index < 26) {
1858   - sprintf(gd->disk_name, "sd%c", 'a' + index % 26);
1859   - } else if (index < (26 + 1) * 26) {
1860   - sprintf(gd->disk_name, "sd%c%c",
1861   - 'a' + index / 26 - 1,'a' + index % 26);
1862   - } else {
1863   - const unsigned int m1 = (index / 26 - 1) / 26 - 1;
1864   - const unsigned int m2 = (index / 26 - 1) % 26;
1865   - const unsigned int m3 = index % 26;
1866   - sprintf(gd->disk_name, "sd%c%c%c",
1867   - 'a' + m1, 'a' + m2, 'a' + m3);
  1898 + if (index < SD_MAX_DISKS) {
  1899 + gd->major = sd_major((index & 0xf0) >> 4);
  1900 + gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
  1901 + gd->minors = SD_MINORS;
1868 1902 }
1869   -
  1903 + gd->fops = &sd_fops;
1870 1904 gd->private_data = &sdkp->driver;
1871 1905 gd->queue = sdkp->device->request_queue;
1872 1906  
fs/partitions/check.c
... ... @@ -593,6 +593,7 @@
593 593 disk_part_iter_exit(&piter);
594 594  
595 595 invalidate_partition(disk, 0);
  596 + blk_free_devt(disk_to_dev(disk)->devt);
596 597 set_capacity(disk, 0);
597 598 disk->flags &= ~GENHD_FL_UP;
598 599 unlink_gendisk(disk);
include/linux/genhd.h
... ... @@ -59,6 +59,7 @@
59 59 };
60 60  
61 61 #define DISK_MAX_PARTS 256
  62 +#define DISK_NAME_LEN 32
62 63  
63 64 #include <linux/major.h>
64 65 #include <linux/device.h>
... ... @@ -140,7 +141,7 @@
140 141 int minors; /* maximum number of minors, =1 for
141 142 * disks that can't be partitioned. */
142 143  
143   - char disk_name[32]; /* name of major driver */
  144 + char disk_name[DISK_NAME_LEN]; /* name of major driver */
144 145  
145 146 /* Array of pointers to partitions indexed by partno.
146 147 * Protected with matching bdev lock but stat and other