Messages in this thread Patch in this message | | | Date | Tue, 25 Jul 2006 13:26:51 -0700 | From | Pete Zaitcev <> | Subject | Patch for sparse block minors (RFC) |
| |
This is a resend and a bugfix to the original. I added the minor twice in the md code. Other than that, it's the same thing, only rediffed to apply to 2.6.18-rc1.
Again, not touching sd. Maybe Jeff wants to push that for libata, I don't feel up to the task.
The patch is tested to work more or less. Nautilus works, udev works, fdisk works. Open-close-rmmod stress test seems to pass, though it's not a guarantee. If anyone sees locking irregularities, please holler.
-- Pete
diff -urp -X dontdiff linux-2.6.18-rc1/arch/um/drivers/ubd_kern.c linux-2.6.18-rc1-lem/arch/um/drivers/ubd_kern.c --- linux-2.6.18-rc1/arch/um/drivers/ubd_kern.c 2006-07-09 17:53:56.000000000 -0700 +++ linux-2.6.18-rc1-lem/arch/um/drivers/ubd_kern.c 2006-07-09 20:12:02.000000000 -0700 @@ -633,8 +633,7 @@ static int ubd_new_disk(int major, u64 s if(disk == NULL) return(-ENOMEM); - disk->major = major; - disk->first_minor = unit << UBD_SHIFT; + disk->gd_dev = MKDEV(major, unit << UBD_SHIFT); disk->fops = &ubd_blops; set_capacity(disk, size / 512); if(major == MAJOR_NR) diff -urp -X dontdiff linux-2.6.18-rc1/block/genhd.c linux-2.6.18-rc1-lem/block/genhd.c --- linux-2.6.18-rc1/block/genhd.c 2006-07-09 17:53:58.000000000 -0700 +++ linux-2.6.18-rc1-lem/block/genhd.c 2006-07-09 20:12:02.000000000 -0700 @@ -181,7 +181,8 @@ static int exact_lock(dev_t dev, void *d void add_disk(struct gendisk *disk) { disk->flags |= GENHD_FL_UP; - blk_register_region(MKDEV(disk->major, disk->first_minor), + if (!(disk->flags & GENHD_FL_SPARSE_MINORS)) + blk_register_region(disk->gd_dev, disk->minors, NULL, exact_match, exact_lock, disk); register_disk(disk); blk_register_queue(disk); @@ -193,8 +194,8 @@ EXPORT_SYMBOL(del_gendisk); /* in partit void unlink_gendisk(struct gendisk *disk) { blk_unregister_queue(disk); - blk_unregister_region(MKDEV(disk->major, disk->first_minor), - disk->minors); + if (!(disk->flags & GENHD_FL_SPARSE_MINORS)) + blk_unregister_region(disk->gd_dev, disk->minors); } #define to_disk(obj) container_of(obj,struct gendisk,kobj) @@ -257,17 +258,18 @@ static int show_partition(struct seq_fil /* show the full disk and all non-0 size partitions of it */ seq_printf(part, "%4d %4d %10llu %s\n", - sgp->major, sgp->first_minor, + MAJOR(sgp->gd_dev), MINOR(sgp->gd_dev), (unsigned long long)get_capacity(sgp) >> 1, disk_name(sgp, 0, buf)); for (n = 0; n < sgp->minors - 1; n++) { - if (!sgp->part[n]) + struct hd_struct *p; + if ((p = sgp->part[n]) == NULL) continue; - if (sgp->part[n]->nr_sects == 0) + if (p->nr_sects == 0) continue; seq_printf(part, "%4d %4d %10llu %s\n", - sgp->major, n + 1 + sgp->first_minor, - (unsigned long long)sgp->part[n]->nr_sects >> 1 , + MAJOR(p->dev), MINOR(p->dev), + (unsigned long long)p->nr_sects >> 1 , disk_name(sgp, n + 1, buf)); } @@ -347,8 +349,7 @@ static ssize_t disk_uevent_store(struct } static ssize_t disk_dev_read(struct gendisk * disk, char *page) { - dev_t base = MKDEV(disk->major, disk->first_minor); - return print_dev_t(page, base); + return print_dev_t(page, disk->gd_dev); } static ssize_t disk_range_read(struct gendisk * disk, char *page) { @@ -459,19 +460,19 @@ static int block_uevent(struct kset *kse if (ktype == &ktype_block) { disk = container_of(kobj, struct gendisk, kobj); add_uevent_var(envp, num_envp, &i, buffer, buffer_size, - &length, "MINOR=%u", disk->first_minor); + &length, "MINOR=%u", MINOR(disk->gd_dev)); + add_uevent_var(envp, num_envp, &i, buffer, buffer_size, + &length, "MAJOR=%u", MAJOR(disk->gd_dev)); } else if (ktype == &ktype_part) { disk = container_of(kobj->parent, struct gendisk, kobj); part = container_of(kobj, struct hd_struct, kobj); add_uevent_var(envp, num_envp, &i, buffer, buffer_size, - &length, "MINOR=%u", - disk->first_minor + part->partno); + &length, "MINOR=%u", MINOR(part->dev)); + add_uevent_var(envp, num_envp, &i, buffer, buffer_size, + &length, "MAJOR=%u", MAJOR(part->dev)); } else return 0; - add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, - "MAJOR=%u", disk->major); - /* add physical device, backing this device */ physdev = disk->driverfs_dev; if (physdev) { @@ -551,7 +552,7 @@ static int diskstats_show(struct seq_fil { struct gendisk *gp = v; char buf[BDEVNAME_SIZE]; - int n = 0; + int n; /* if (&sgp->kobj.entry == block_subsys.kset.list.next) @@ -565,7 +566,7 @@ static int diskstats_show(struct seq_fil disk_round_stats(gp); preempt_enable(); seq_printf(s, "%4d %4d %s %lu %lu %llu %u %lu %lu %llu %u %u %u %u\n", - gp->major, n + gp->first_minor, disk_name(gp, n, buf), + MAJOR(gp->gd_dev), MINOR(gp->gd_dev), disk_name(gp, 0, buf), disk_stat_read(gp, ios[0]), disk_stat_read(gp, merges[0]), (unsigned long long)disk_stat_read(gp, sectors[0]), jiffies_to_msecs(disk_stat_read(gp, ticks[0])), @@ -582,7 +583,7 @@ static int diskstats_show(struct seq_fil if (hd && hd->nr_sects) seq_printf(s, "%4d %4d %s %u %u %u %u\n", - gp->major, n + gp->first_minor + 1, + MAJOR(hd->dev), MINOR(hd->dev), disk_name(gp, n + 1, buf), hd->ios[0], hd->sectors[0], hd->ios[1], hd->sectors[1]); @@ -698,7 +699,16 @@ EXPORT_SYMBOL(bdev_read_only); int invalidate_partition(struct gendisk *disk, int index) { int res = 0; - struct block_device *bdev = bdget_disk(disk, index); + struct block_device *bdev; + + if (index == 0) + bdev = bdget_disk(disk); + else { + if (disk->part[index-1]) + bdev = bdget(disk->part[index-1]->dev); + else + bdev = NULL; + } if (bdev) { fsync_bdev(bdev); res = __invalidate_device(bdev); diff -urp -X dontdiff linux-2.6.18-rc1/block/ioctl.c linux-2.6.18-rc1-lem/block/ioctl.c --- linux-2.6.18-rc1/block/ioctl.c 2006-06-21 14:14:17.000000000 -0700 +++ linux-2.6.18-rc1-lem/block/ioctl.c 2006-07-09 20:12:02.000000000 -0700 @@ -69,7 +69,7 @@ static int blkpg_ioctl(struct block_devi return -ENXIO; if (disk->part[part - 1]->nr_sects == 0) return -ENXIO; - bdevp = bdget_disk(disk, part); + bdevp = bdget(disk->part[part-1]->dev); if (!bdevp) return -ENOMEM; mutex_lock(&bdevp->bd_mutex); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/acorn/block/fd1772.c linux-2.6.18-rc1-lem/drivers/acorn/block/fd1772.c --- linux-2.6.18-rc1/drivers/acorn/block/fd1772.c 2005-10-28 19:11:34.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/acorn/block/fd1772.c 2006-07-09 20:12:03.000000000 -0700 @@ -1568,8 +1568,7 @@ int fd1772_init(void) for (i = 0; i < FD_MAX_UNITS; i++) { unit[i].track = -1; - disks[i]->major = MAJOR_NR; - disks[i]->first_minor = 0; + disks[i]->gd_dev = MKDEV(MAJOR_NR, 0); disks[i]->fops = &floppy_fops; sprintf(disks[i]->disk_name, "fd%d", i); disks[i]->private_data = &unit[i]; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/acorn/block/mfmhd.c linux-2.6.18-rc1-lem/drivers/acorn/block/mfmhd.c --- linux-2.6.18-rc1/drivers/acorn/block/mfmhd.c 2006-07-09 17:53:59.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/acorn/block/mfmhd.c 2006-07-09 20:12:03.000000000 -0700 @@ -1269,8 +1269,7 @@ static int mfm_do_init(unsigned char irq struct gendisk *disk = alloc_disk(64); if (!disk) goto Enomem; - disk->major = MAJOR_NR; - disk->first_minor = i << 6; + disk->gd_dev = MKDEV(MAJOR_NR, i << 6); disk->fops = &mfm_fops; sprintf(disk->disk_name, "mfm%c", 'a'+i); mfm_gendisk[i] = disk; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/acsi.c linux-2.6.18-rc1-lem/drivers/block/acsi.c --- linux-2.6.18-rc1/drivers/block/acsi.c 2006-07-09 17:54:00.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/acsi.c 2006-07-09 18:32:48.000000000 -0700 @@ -1731,8 +1731,7 @@ int acsi_init( void ) struct gendisk *disk = acsi_gendisk[i]; sprintf(disk->disk_name, "ad%c", 'a'+i); aip = &acsi_info[NDevices]; - disk->major = ACSI_MAJOR; - disk->first_minor = i << 4; + disk->gd_dev = MKDEV(ACSI_MAJOR, i << 4); if (acsi_info[i].type != HARDDISK) disk->minors = 1; disk->fops = &acsi_fops; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/amiflop.c linux-2.6.18-rc1-lem/drivers/block/amiflop.c --- linux-2.6.18-rc1/drivers/block/amiflop.c 2006-07-09 17:54:00.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/amiflop.c 2006-07-09 20:12:03.000000000 -0700 @@ -1681,8 +1681,7 @@ static int __init fd_probe_drives(void) nomem = 1; } printk("fd%d ",drive); - disk->major = FLOPPY_MAJOR; - disk->first_minor = drive; + disk->gd_dev = MKDEV(FLOPPY_MAJOR, drive); disk->fops = &floppy_fops; sprintf(disk->disk_name, "fd%d", drive); disk->private_data = &unit[drive]; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/aoe/aoeblk.c linux-2.6.18-rc1-lem/drivers/block/aoe/aoeblk.c --- linux-2.6.18-rc1/drivers/block/aoe/aoeblk.c 2006-06-21 14:14:18.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/aoe/aoeblk.c 2006-07-09 20:12:03.000000000 -0700 @@ -224,8 +224,7 @@ aoeblk_gdalloc(void *vp) spin_lock_irqsave(&d->lock, flags); blk_queue_make_request(&d->blkq, aoeblk_make_request); - gd->major = AOE_MAJOR; - gd->first_minor = d->sysminor * AOE_PARTITIONS; + gd->gd_dev = MKDEV(AOE_MAJOR, d->sysminor * AOE_PARTITIONS); gd->fops = &aoe_bdops; gd->private_data = d; gd->capacity = d->ssize; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/aoe/aoecmd.c linux-2.6.18-rc1-lem/drivers/block/aoe/aoecmd.c --- linux-2.6.18-rc1/drivers/block/aoe/aoecmd.c 2006-06-21 14:14:18.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/aoe/aoecmd.c 2006-07-09 20:12:03.000000000 -0700 @@ -380,7 +380,7 @@ aoecmd_sleepwork(void *vp) u64 ssize; ssize = d->gd->capacity; - bd = bdget_disk(d->gd, 0); + bd = bdget_disk(d->gd); if (bd) { mutex_lock(&bd->bd_inode->i_mutex); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/ataflop.c linux-2.6.18-rc1-lem/drivers/block/ataflop.c --- linux-2.6.18-rc1/drivers/block/ataflop.c 2006-06-21 14:14:18.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/ataflop.c 2006-07-09 20:12:03.000000000 -0700 @@ -1923,8 +1923,7 @@ static int __init atari_floppy_init (voi for (i = 0; i < FD_MAX_UNITS; i++) { unit[i].track = -1; unit[i].flags = 0; - unit[i].disk->major = FLOPPY_MAJOR; - unit[i].disk->first_minor = i; + unit[i].disk->gd_dev = MKDEV(FLOPPY_MAJOR, i); sprintf(unit[i].disk->disk_name, "fd%d", i); unit[i].disk->fops = &floppy_fops; unit[i].disk->private_data = &unit[i]; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/cciss.c linux-2.6.18-rc1-lem/drivers/block/cciss.c --- linux-2.6.18-rc1/drivers/block/cciss.c 2006-07-09 17:54:00.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/cciss.c 2006-07-09 18:33:49.000000000 -0700 @@ -3248,8 +3248,7 @@ static int __devinit cciss_init_one(stru q->queuedata = hba[i]; sprintf(disk->disk_name, "cciss/c%dd%d", i, j); - disk->major = hba[i]->major; - disk->first_minor = j << NWD_SHIFT; + disk->gd_dev = MKDEV(hba[i]->major, j << NWD_SHIFT); disk->fops = &cciss_fops; disk->queue = q; disk->private_data = drv; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/cpqarray.c linux-2.6.18-rc1-lem/drivers/block/cpqarray.c --- linux-2.6.18-rc1/drivers/block/cpqarray.c 2006-07-09 17:54:00.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/cpqarray.c 2006-07-09 20:12:03.000000000 -0700 @@ -471,8 +471,7 @@ static int __init cpqarray_register_ctlr struct gendisk *disk = ida_gendisk[i][j]; drv_info_t *drv = &hba[i]->drv[j]; sprintf(disk->disk_name, "ida/c%dd%d", i, j); - disk->major = COMPAQ_SMART2_MAJOR + i; - disk->first_minor = j<<NWD_SHIFT; + disk->gd_dev = MKDEV(COMPAQ_SMART2_MAJOR + i, j<<NWD_SHIFT); disk->fops = &ida_fops; if (j && !drv->nr_blks) continue; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/DAC960.c linux-2.6.18-rc1-lem/drivers/block/DAC960.c --- linux-2.6.18-rc1/drivers/block/DAC960.c 2006-07-09 17:54:00.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/DAC960.c 2006-07-09 18:34:41.000000000 -0700 @@ -2530,8 +2530,7 @@ static boolean DAC960_RegisterBlockDevic blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand); disk->queue = RequestQueue; sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n); - disk->major = MajorNumber; - disk->first_minor = n << DAC960_MaxPartitionsBits; + disk->gd_dev = MKDEV(MajorNumber, n << DAC960_MaxPartitionsBits); disk->fops = &DAC960_BlockDeviceOperations; } /* diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/floppy.c linux-2.6.18-rc1-lem/drivers/block/floppy.c --- linux-2.6.18-rc1/drivers/block/floppy.c 2006-07-09 17:54:00.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/floppy.c 2006-07-09 20:12:03.000000000 -0700 @@ -4186,8 +4186,7 @@ static int __init floppy_init(void) goto out_put_disk; } - disks[dr]->major = FLOPPY_MAJOR; - disks[dr]->first_minor = TOMINOR(dr); + disks[dr]->gd_dev = MKDEV(FLOPPY_MAJOR, TOMINOR(dr)); disks[dr]->fops = &floppy_fops; sprintf(disks[dr]->disk_name, "fd%d", dr); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/loop.c linux-2.6.18-rc1-lem/drivers/block/loop.c --- linux-2.6.18-rc1/drivers/block/loop.c 2006-07-09 17:54:00.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/loop.c 2006-07-09 18:35:47.000000000 -0700 @@ -1288,8 +1288,7 @@ static int __init loop_init(void) init_completion(&lo->lo_bh_done); lo->lo_number = i; spin_lock_init(&lo->lo_lock); - disk->major = LOOP_MAJOR; - disk->first_minor = i; + disk->gd_dev = MKDEV(LOOP_MAJOR, i); disk->fops = &lo_fops; sprintf(disk->disk_name, "loop%d", i); disk->private_data = lo; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/nbd.c linux-2.6.18-rc1-lem/drivers/block/nbd.c --- linux-2.6.18-rc1/drivers/block/nbd.c 2006-07-09 17:54:00.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/nbd.c 2006-07-09 20:12:03.000000000 -0700 @@ -651,8 +651,7 @@ static int __init nbd_init(void) init_waitqueue_head(&nbd_dev[i].active_wq); nbd_dev[i].blksize = 1024; nbd_dev[i].bytesize = 0x7ffffc00ULL << 10; /* 2TB */ - disk->major = NBD_MAJOR; - disk->first_minor = i; + disk->gd_dev = MKDEV(NBD_MAJOR, i); disk->fops = &nbd_fops; disk->private_data = &nbd_dev[i]; disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/paride/pcd.c linux-2.6.18-rc1-lem/drivers/block/paride/pcd.c --- linux-2.6.18-rc1/drivers/block/paride/pcd.c 2005-10-28 19:11:38.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/paride/pcd.c 2006-07-09 20:12:03.000000000 -0700 @@ -299,8 +299,7 @@ static void pcd_init_units(void) cd->info.speed = 0; cd->info.capacity = 1; cd->info.mask = 0; - disk->major = major; - disk->first_minor = unit; + disk->gd_dev = MKDEV(major, unit); strcpy(disk->disk_name, cd->name); /* umm... */ disk->fops = &pcd_bdops; } diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/paride/pd.c linux-2.6.18-rc1-lem/drivers/block/paride/pd.c --- linux-2.6.18-rc1/drivers/block/paride/pd.c 2006-06-21 14:14:18.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/paride/pd.c 2006-07-09 20:12:03.000000000 -0700 @@ -831,8 +831,7 @@ static void pd_probe_drive(struct pd_uni return; strcpy(p->disk_name, disk->name); p->fops = &pd_fops; - p->major = major; - p->first_minor = (disk - pd) << PD_BITS; + p->gd_dev = MKDEV(major, (disk - pd) << PD_BITS); disk->gd = p; p->private_data = disk; p->queue = pd_queue; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/paride/pf.c linux-2.6.18-rc1-lem/drivers/block/paride/pf.c --- linux-2.6.18-rc1/drivers/block/paride/pf.c 2006-07-09 17:54:00.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/paride/pf.c 2006-07-09 20:12:03.000000000 -0700 @@ -287,8 +287,7 @@ static void __init pf_init_units(void) pf->drive = (*drives[unit])[D_SLV]; pf->lun = (*drives[unit])[D_LUN]; snprintf(pf->name, PF_NAMELEN, "%s%d", name, unit); - disk->major = major; - disk->first_minor = unit; + disk->gd_dev = MKDEV(major, unit); strcpy(disk->disk_name, pf->name); disk->fops = &pf_fops; if (!(*drives[unit])[D_PRT]) diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/pktcdvd.c linux-2.6.18-rc1-lem/drivers/block/pktcdvd.c --- linux-2.6.18-rc1/drivers/block/pktcdvd.c 2006-07-09 17:54:00.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/pktcdvd.c 2006-07-10 19:17:00.000000000 -0700 @@ -2474,8 +2474,7 @@ static int pkt_setup_dev(struct pkt_ctrl init_waitqueue_head(&pd->wqueue); pd->bio_queue = RB_ROOT; - disk->major = pkt_major; - disk->first_minor = idx; + disk->gd_dev = MKDEV(pkt_major, idx); disk->fops = &pktcdvd_ops; disk->flags = GENHD_FL_REMOVABLE; sprintf(disk->disk_name, "pktcdvd%d", idx); @@ -2484,7 +2483,7 @@ static int pkt_setup_dev(struct pkt_ctrl if (!disk->queue) goto out_mem2; - pd->pkt_dev = MKDEV(disk->major, disk->first_minor); + pd->pkt_dev = disk->gd_dev; ret = pkt_new_dev(pd, dev); if (ret) goto out_new_dev; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/ps2esdi.c linux-2.6.18-rc1-lem/drivers/block/ps2esdi.c --- linux-2.6.18-rc1/drivers/block/ps2esdi.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/ps2esdi.c 2006-07-09 18:36:36.000000000 -0700 @@ -417,8 +417,7 @@ static int __init ps2esdi_geninit(void) struct gendisk *disk = alloc_disk(64); if (!disk) goto err_out4; - disk->major = PS2ESDI_MAJOR; - disk->first_minor = i<<6; + disk->gd_dev = MKDEV(PS2ESDI_MAJOR, i<<6); sprintf(disk->disk_name, "ed%c", 'a'+i); disk->fops = &ps2esdi_fops; ps2esdi_gendisk[i] = disk; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/rd.c linux-2.6.18-rc1-lem/drivers/block/rd.c --- linux-2.6.18-rc1/drivers/block/rd.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/rd.c 2006-07-09 20:12:03.000000000 -0700 @@ -450,8 +450,7 @@ static int __init rd_init(void) blk_queue_hardsect_size(rd_queue[i], rd_blocksize); /* rd_size is given in kB */ - disk->major = RAMDISK_MAJOR; - disk->first_minor = i; + disk->gd_dev = MKDEV(RAMDISK_MAJOR, i); disk->fops = &rd_bd_op; disk->queue = rd_queue[i]; disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/swim3.c linux-2.6.18-rc1-lem/drivers/block/swim3.c --- linux-2.6.18-rc1/drivers/block/swim3.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/swim3.c 2006-07-09 20:41:48.000000000 -0700 @@ -1141,8 +1141,7 @@ static int __devinit swim3_attach(struct if (disk == NULL) return 0; - disk->major = FLOPPY_MAJOR; - disk->first_minor = i; + disk->gd_dev = MKDEV(FLOPPY_MAJOR, i); disk->fops = &floppy_fops; disk->private_data = &floppy_states[i]; disk->queue = swim3_queue; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/swim_iop.c linux-2.6.18-rc1-lem/drivers/block/swim_iop.c --- linux-2.6.18-rc1/drivers/block/swim_iop.c 2005-10-28 19:11:38.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/swim_iop.c 2006-07-09 20:12:03.000000000 -0700 @@ -193,8 +193,7 @@ int swimiop_init(void) struct gendisk *disk = alloc_disk(1); if (!disk) continue; - disk->major = FLOPPY_MAJOR; - disk->first_minor = i; + disk->gd_dev = MKDEV(FLOPPY_MAJOR, i); disk->fops = &floppy_fops; sprintf(disk->disk_name, "fd%d", i); disk->private_data = &floppy_states[i]; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/sx8.c linux-2.6.18-rc1-lem/drivers/block/sx8.c --- linux-2.6.18-rc1/drivers/block/sx8.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/sx8.c 2006-07-09 18:39:21.000000000 -0700 @@ -1509,8 +1509,7 @@ static int carm_init_disks(struct carm_h port->disk = disk; sprintf(disk->disk_name, DRV_NAME "/%u", (unsigned int) (host->id * CARM_MAX_PORTS) + i); - disk->major = host->major; - disk->first_minor = i * CARM_MINORS_PER_MAJOR; + disk->gd_dev = MKDEV(host->major, i * CARM_MINORS_PER_MAJOR); disk->fops = &carm_bd_ops; disk->private_data = port; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/ub.c linux-2.6.18-rc1-lem/drivers/block/ub.c --- linux-2.6.18-rc1/drivers/block/ub.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/ub.c 2006-07-10 18:39:34.000000000 -0700 @@ -105,9 +105,18 @@ #define UB_MAX_LUNS 9 /* - */ + * The minor layout is: + * 19 - 11 0xFF800 + * 10 - 8 0x700 Upper 3 bits of partition number + * 7 - 3 0xF8 Host index, or same as "id". UB_MAX_HOSTS fit here. + * 2 - 0 0x7 Lower 3 bits of partition number + */ +#define UB_PARTS_PER_LUN 64 +#define UB_PARTS_LOW 8 +#define UB_MINORS 2048 -#define UB_PARTS_PER_LUN 8 +/* + */ #define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */ @@ -377,6 +387,7 @@ static int ub_submit_clear_stall(struct static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); static void ub_reset_enter(struct ub_dev *sc, int try); static void ub_reset_task(void *arg); +static dev_t ub_bd_map(struct gendisk *disk, int partno); static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, struct ub_capacity *ret); @@ -400,14 +411,10 @@ MODULE_DEVICE_TABLE(usb, ub_usb_ids); #endif /* CONFIG_USB_LIBUSUAL */ /* - * Find me a way to identify "next free minor" for add_disk(), - * and the array disappears the next day. However, the number of - * hosts has something to do with the naming and /proc/partitions. - * This has to be thought out in detail before changing. - * If UB_MAX_HOST was 1000, we'd use a bitmap. Or a better data structure. + * If UB_MAX_HOST were 1000, we'd use a better data structure. */ #define UB_MAX_HOSTS 26 -static char ub_hostv[UB_MAX_HOSTS]; +static struct ub_lun *ub_hostv[UB_MAX_HOSTS]; #define UB_QLOCK_NUM 5 static spinlock_t ub_qlockv[UB_QLOCK_NUM]; @@ -427,8 +434,8 @@ static int ub_id_get(void) spin_lock_irqsave(&ub_lock, flags); for (i = 0; i < UB_MAX_HOSTS; i++) { - if (ub_hostv[i] == 0) { - ub_hostv[i] = 1; + if (ub_hostv[i] == NULL) { + ub_hostv[i] = (struct ub_lun *) 1; spin_unlock_irqrestore(&ub_lock, flags); return i; } @@ -437,6 +444,15 @@ static int ub_id_get(void) return -1; } +static void ub_id_commit(int id, struct ub_lun *lun) +{ + unsigned long flags; + + spin_lock_irqsave(&ub_lock, flags); + ub_hostv[id] = lun; + spin_unlock_irqrestore(&ub_lock, flags); +} + static void ub_id_put(int id) { unsigned long flags; @@ -447,12 +463,12 @@ static void ub_id_put(int id) } spin_lock_irqsave(&ub_lock, flags); - if (ub_hostv[id] == 0) { + if (ub_hostv[id] == NULL) { spin_unlock_irqrestore(&ub_lock, flags); printk(KERN_ERR DRV_NAME ": freeing free host ID %d\n", id); return; } - ub_hostv[id] = 0; + ub_hostv[id] = NULL; spin_unlock_irqrestore(&ub_lock, flags); } @@ -1768,9 +1787,97 @@ static struct block_device_operations ub .ioctl = ub_bd_ioctl, .media_changed = ub_bd_media_changed, .revalidate_disk = ub_bd_revalidate, + .partmap = ub_bd_map, }; /* + * Since we want to remap minor bits, we have to use this weird API. + * It consists of two entries: ->lock and ->get. The ->lock is called first + * and grabs the relevant gendisk, plus everything there is to grab + * so that ->get works. The ->get (often called "match") remaps minor + * bits into an index for the array of partitions. + * + * If ->get fails, it has to undo everything ->lock has done. + * Also, if that happens, the whole set is called again, so we better + * make ->lock to fail too. + */ + +static int ub_blk_lock(dev_t dev, void *data) +{ + unsigned int minor = MINOR(dev); + unsigned int host; + struct ub_dev *sc; + struct ub_lun *lun; + unsigned long flags; + + host = (minor >> 3) & 0x1f; + if (host >= UB_MAX_HOSTS) + return -1; + + spin_lock_irqsave(&ub_lock, flags); + lun = ub_hostv[host]; + if (lun == NULL || (unsigned long)lun == 1) { + spin_unlock_irqrestore(&ub_lock, flags); + return -1; + } + sc = lun->udev; + if (atomic_read(&sc->poison)) { + spin_unlock_irqrestore(&ub_lock, flags); + return -1; + } + sc->openc++; + spin_unlock_irqrestore(&ub_lock, flags); + + if (!get_disk(lun->disk)) { + ub_put(sc); + return -1; + } + + return 0; +} + +static struct kobject *ub_blk_match(dev_t dev, int *part, void *data) +{ + unsigned int minor = MINOR(dev); + struct ub_dev *sc; + struct ub_lun *lun; + struct kobject *kobj; + unsigned long flags; + + spin_lock_irqsave(&ub_lock, flags); + lun = ub_hostv[(minor >> 3) & 0x1f]; + if (lun == NULL || (unsigned long)lun == 1) { /* This cannot happen */ + spin_unlock_irqrestore(&ub_lock, flags); + printk(KERN_ERR DRV_NAME ": NULL lun for %u:%u\n", + (unsigned int) MAJOR(dev), minor); + return NULL; + } + sc = lun->udev; + if (atomic_read(&sc->poison)) { /* This can happen */ + spin_unlock_irqrestore(&ub_lock, flags); + /* Undo results of ub_blk_lock() */ + put_disk(lun->disk); + ub_put(sc); + return NULL; + } + spin_unlock_irqrestore(&ub_lock, flags); + + *part = ((minor & 0x700) >> 5) | (minor & 0x7); + kobj = &lun->disk->kobj; + ub_put(sc); + return kobj; +} + +static dev_t ub_bd_map(struct gendisk *disk, int partno) +{ + struct ub_lun *lun = disk->private_data; + unsigned int minor; + + minor = ((partno & 0x38) << 5) | (lun->id << 3) | (partno & 0x7); + return MKDEV(UB_MAJOR, minor); +} + +/* * Common ->done routine for commands executed synchronously. */ static void ub_probe_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) @@ -2289,11 +2399,11 @@ static int ub_probe_lun(struct ub_dev *s goto err_diskalloc; sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); - disk->major = UB_MAJOR; - disk->first_minor = lun->id * UB_PARTS_PER_LUN; + disk->gd_dev = MKDEV(UB_MAJOR, lun->id * UB_PARTS_LOW); disk->fops = &ub_bd_fops; disk->private_data = lun; disk->driverfs_dev = &sc->intf->dev; + disk->flags |= GENHD_FL_SPARSE_MINORS; rc = -ENOMEM; if ((q = blk_init_queue(ub_request_fn, sc->lock)) == NULL) @@ -2316,6 +2426,7 @@ static int ub_probe_lun(struct ub_dev *s if (lun->removable) disk->flags |= GENHD_FL_REMOVABLE; + ub_id_commit(lun->id, lun); add_disk(disk); return 0; @@ -2440,6 +2551,8 @@ static int __init ub_init(void) for (i = 0; i < UB_QLOCK_NUM; i++) spin_lock_init(&ub_qlockv[i]); + blk_register_region(MKDEV(UB_MAJOR, 0), UB_MINORS, THIS_MODULE, + ub_blk_match, ub_blk_lock, NULL); if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0) goto err_regblkdev; @@ -2452,6 +2565,7 @@ static int __init ub_init(void) err_register: unregister_blkdev(UB_MAJOR, DRV_NAME); err_regblkdev: + blk_unregister_region(MKDEV(UB_MAJOR, 0), UB_MINORS); return rc; } @@ -2461,6 +2575,7 @@ static void __exit ub_exit(void) unregister_blkdev(UB_MAJOR, DRV_NAME); usb_usual_clear_present(USB_US_TYPE_UB); + blk_unregister_region(MKDEV(UB_MAJOR, 0), UB_MINORS); } module_init(ub_init); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/umem.c linux-2.6.18-rc1-lem/drivers/block/umem.c --- linux-2.6.18-rc1/drivers/block/umem.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/umem.c 2006-07-09 18:40:07.000000000 -0700 @@ -1192,8 +1192,7 @@ static int __init mm_init(void) struct gendisk *disk = mm_gendisk[i]; sprintf(disk->disk_name, "umem%c", 'a'+i); spin_lock_init(&cards[i].lock); - disk->major = major_nr; - disk->first_minor = i << MM_SHIFT; + disk->gd_dev = MKDEV(major_nr, i << MM_SHIFT); disk->fops = &mm_fops; disk->private_data = &cards[i]; disk->queue = cards[i].queue; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/viodasd.c linux-2.6.18-rc1-lem/drivers/block/viodasd.c --- linux-2.6.18-rc1/drivers/block/viodasd.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/viodasd.c 2006-07-09 20:12:03.000000000 -0700 @@ -513,8 +513,7 @@ retry: blk_queue_max_hw_segments(q, VIOMAXBLOCKDMA); blk_queue_max_phys_segments(q, VIOMAXBLOCKDMA); blk_queue_max_sectors(q, VIODASD_MAXSECTORS); - g->major = VIODASD_MAJOR; - g->first_minor = dev_no << PARTITION_SHIFT; + g->gd_dev = MKDEV(VIODASD_MAJOR, dev_no << PARTITION_SHIFT); if (dev_no >= 26) snprintf(g->disk_name, sizeof(g->disk_name), VIOD_GENHD_NAME "%c%c", diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/xd.c linux-2.6.18-rc1-lem/drivers/block/xd.c --- linux-2.6.18-rc1/drivers/block/xd.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/xd.c 2006-07-09 18:40:57.000000000 -0700 @@ -212,8 +212,7 @@ static int __init xd_init(void) if (!disk) goto Enomem; p->unit = i; - disk->major = XT_DISK_MAJOR; - disk->first_minor = i<<6; + disk->gd_dev = MKDEV(XT_DISK_MAJOR, i<<6); sprintf(disk->disk_name, "xd%c", i+'a'); disk->fops = &xd_fops; disk->private_data = p; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/block/z2ram.c linux-2.6.18-rc1-lem/drivers/block/z2ram.c --- linux-2.6.18-rc1/drivers/block/z2ram.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/block/z2ram.c 2006-07-09 18:42:10.000000000 -0700 @@ -350,8 +350,7 @@ z2_init(void) if (!z2_queue) goto out_queue; - z2ram_gendisk->major = Z2RAM_MAJOR; - z2ram_gendisk->first_minor = 0; + z2ram_gendisk->gd_dev = MKDEV(Z2RAM_MAJOR, 0); z2ram_gendisk->fops = &z2_fops; sprintf(z2ram_gendisk->disk_name, "z2ram"); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/cdrom/aztcd.c linux-2.6.18-rc1-lem/drivers/cdrom/aztcd.c --- linux-2.6.18-rc1/drivers/cdrom/aztcd.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/cdrom/aztcd.c 2006-07-09 18:43:02.000000000 -0700 @@ -1914,8 +1914,7 @@ static int __init aztcd_init(void) } blk_queue_hardsect_size(azt_queue, 2048); - azt_disk->major = MAJOR_NR; - azt_disk->first_minor = 0; + azt_disk->gd_dev = MKDEV(MAJOR_NR, 0); azt_disk->fops = &azt_fops; sprintf(azt_disk->disk_name, "aztcd"); azt_disk->queue = azt_queue; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/cdrom/cdu31a.c linux-2.6.18-rc1-lem/drivers/cdrom/cdu31a.c --- linux-2.6.18-rc1/drivers/cdrom/cdu31a.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/cdrom/cdu31a.c 2006-07-09 20:12:03.000000000 -0700 @@ -3122,8 +3122,7 @@ int __init cdu31a_init(void) disk = alloc_disk(1); if (!disk) goto errout1; - disk->major = MAJOR_NR; - disk->first_minor = 0; + disk->gd_dev = MKDEV(MAJOR_NR, 0); sprintf(disk->disk_name, "cdu31a"); disk->fops = &scd_bdops; disk->flags = GENHD_FL_CD; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/cdrom/cm206.c linux-2.6.18-rc1-lem/drivers/cdrom/cm206.c --- linux-2.6.18-rc1/drivers/cdrom/cm206.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/cdrom/cm206.c 2006-07-09 20:12:03.000000000 -0700 @@ -1470,8 +1470,7 @@ int __init cm206_init(void) disk = alloc_disk(1); if (!disk) goto out_disk; - disk->major = MAJOR_NR; - disk->first_minor = 0; + disk->gd_dev = MKDEV(MAJOR_NR, 0); sprintf(disk->disk_name, "cm206cd"); disk->fops = &cm206_bdops; disk->flags = GENHD_FL_CD; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/cdrom/gscd.c linux-2.6.18-rc1-lem/drivers/cdrom/gscd.c --- linux-2.6.18-rc1/drivers/cdrom/gscd.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/cdrom/gscd.c 2006-07-09 18:43:44.000000000 -0700 @@ -951,8 +951,7 @@ static int __init gscd_init(void) gscd_disk = alloc_disk(1); if (!gscd_disk) goto err_out1; - gscd_disk->major = MAJOR_NR; - gscd_disk->first_minor = 0; + gscd_disk->gd_dev = MKDEV(MAJOR_NR, 0); gscd_disk->fops = &gscd_fops; sprintf(gscd_disk->disk_name, "gscd"); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/cdrom/mcdx.c linux-2.6.18-rc1-lem/drivers/cdrom/mcdx.c --- linux-2.6.18-rc1/drivers/cdrom/mcdx.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/cdrom/mcdx.c 2006-07-09 20:12:03.000000000 -0700 @@ -1226,8 +1226,7 @@ static int __init mcdx_init_drive(int dr stuffp->info.capacity = 1; stuffp->info.handle = stuffp; sprintf(stuffp->info.name, "mcdx%d", drive); - disk->major = MAJOR_NR; - disk->first_minor = drive; + disk->gd_dev = MKDEV(MAJOR_NR, drive); strcpy(disk->disk_name, stuffp->info.name); disk->fops = &mcdx_bdops; disk->flags = GENHD_FL_CD; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/cdrom/optcd.c linux-2.6.18-rc1-lem/drivers/cdrom/optcd.c --- linux-2.6.18-rc1/drivers/cdrom/optcd.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/cdrom/optcd.c 2006-07-09 18:44:28.000000000 -0700 @@ -2029,8 +2029,7 @@ static int __init optcd_init(void) printk(KERN_ERR "optcd: can't allocate disk\n"); return -ENOMEM; } - optcd_disk->major = MAJOR_NR; - optcd_disk->first_minor = 0; + optcd_disk->gd_dev = MKDEV(MAJOR_NR, 0); optcd_disk->fops = &opt_fops; sprintf(optcd_disk->disk_name, "optcd"); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/cdrom/sbpcd.c linux-2.6.18-rc1-lem/drivers/cdrom/sbpcd.c --- linux-2.6.18-rc1/drivers/cdrom/sbpcd.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/cdrom/sbpcd.c 2006-07-09 20:12:03.000000000 -0700 @@ -5862,8 +5862,7 @@ int __init sbpcd_init(void) sbpcd_infop->handle = p; p->sbpcd_infop = sbpcd_infop; disk = alloc_disk(1); - disk->major = MAJOR_NR; - disk->first_minor = j; + disk->gd_dev = MKDEV(MAJOR_NR, j); disk->fops = &sbpcd_bdops; strcpy(disk->disk_name, sbpcd_infop->name); disk->flags = GENHD_FL_CD; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/cdrom/sjcd.c linux-2.6.18-rc1-lem/drivers/cdrom/sjcd.c --- linux-2.6.18-rc1/drivers/cdrom/sjcd.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/cdrom/sjcd.c 2006-07-09 18:45:12.000000000 -0700 @@ -1691,8 +1691,7 @@ static int __init sjcd_init(void) printk(KERN_ERR "SJCD: can't allocate disk"); goto out1; } - sjcd_disk->major = MAJOR_NR, - sjcd_disk->first_minor = 0, + sjcd_disk->gd_dev = MKDEV(MAJOR_NR, 0); sjcd_disk->fops = &sjcd_fops, sprintf(sjcd_disk->disk_name, "sjcd"); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/cdrom/sonycd535.c linux-2.6.18-rc1-lem/drivers/cdrom/sonycd535.c --- linux-2.6.18-rc1/drivers/cdrom/sonycd535.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/cdrom/sonycd535.c 2006-07-09 18:45:49.000000000 -0700 @@ -1585,8 +1585,7 @@ static int __init sony535_init(void) cdu_disk = alloc_disk(1); if (!cdu_disk) goto out6; - cdu_disk->major = MAJOR_NR; - cdu_disk->first_minor = 0; + cdu_disk->gd_dev = MKDEV(MAJOR_NR, 0); cdu_disk->fops = &cdu_fops; sprintf(cdu_disk->disk_name, "cdu"); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/cdrom/viocd.c linux-2.6.18-rc1-lem/drivers/cdrom/viocd.c --- linux-2.6.18-rc1/drivers/cdrom/viocd.c 2006-07-09 17:54:01.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/cdrom/viocd.c 2006-07-09 20:12:03.000000000 -0700 @@ -683,8 +683,7 @@ static int viocd_probe(struct vio_dev *v c->name); goto out_cleanup_queue; } - gendisk->major = VIOCD_MAJOR; - gendisk->first_minor = deviceno; + gendisk->gd_dev = MKDEV(VIOCD_MAJOR, deviceno); strncpy(gendisk->disk_name, c->name, sizeof(gendisk->disk_name)); blk_queue_max_hw_segments(q, 1); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/char/random.c linux-2.6.18-rc1-lem/drivers/char/random.c --- linux-2.6.18-rc1/drivers/char/random.c 2006-07-09 17:54:04.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/char/random.c 2006-07-09 20:12:03.000000000 -0700 @@ -660,10 +660,9 @@ void add_disk_randomness(struct gendisk if (!disk || !disk->random) return; /* first major is 1, so we get >= 0x200 here */ - DEBUG_ENT("disk event %d:%d\n", disk->major, disk->first_minor); + DEBUG_ENT("disk event %d:%d\n",MAJOR(disk->gd_dev),MINOR(disk->gd_dev)); - add_timer_randomness(disk->random, - 0x100 + MKDEV(disk->major, disk->first_minor)); + add_timer_randomness(disk->random, 0x100 + disk->gd_dev); } EXPORT_SYMBOL(add_disk_randomness); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/ide/ide-probe.c linux-2.6.18-rc1-lem/drivers/ide/ide-probe.c --- linux-2.6.18-rc1/drivers/ide/ide-probe.c 2006-07-09 17:54:06.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/ide/ide-probe.c 2006-07-09 20:12:03.000000000 -0700 @@ -1222,7 +1222,7 @@ static int exact_lock(dev_t dev, void *d void ide_register_region(struct gendisk *disk) { - blk_register_region(MKDEV(disk->major, disk->first_minor), + blk_register_region(disk->gd_dev, disk->minors, NULL, exact_match, exact_lock, disk); } @@ -1230,8 +1230,7 @@ EXPORT_SYMBOL_GPL(ide_register_region); void ide_unregister_region(struct gendisk *disk) { - blk_unregister_region(MKDEV(disk->major, disk->first_minor), - disk->minors); + blk_unregister_region(disk->gd_dev, disk->minors); } EXPORT_SYMBOL_GPL(ide_unregister_region); @@ -1241,8 +1240,7 @@ void ide_init_disk(struct gendisk *disk, ide_hwif_t *hwif = drive->hwif; unsigned int unit = (drive->select.all >> 4) & 1; - disk->major = hwif->major; - disk->first_minor = unit << PARTN_BITS; + disk->gd_dev = MKDEV(hwif->major, unit << PARTN_BITS); sprintf(disk->disk_name, "hd%c", 'a' + hwif->index * MAX_DRIVES + unit); disk->queue = drive->queue; } diff -urp -X dontdiff linux-2.6.18-rc1/drivers/ide/legacy/hd.c linux-2.6.18-rc1-lem/drivers/ide/legacy/hd.c --- linux-2.6.18-rc1/drivers/ide/legacy/hd.c 2006-07-09 17:54:06.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/ide/legacy/hd.c 2006-07-09 20:12:03.000000000 -0700 @@ -792,8 +792,7 @@ static int __init hd_init(void) struct hd_i_struct *p = &hd_info[drive]; if (!disk) goto Enomem; - disk->major = MAJOR_NR; - disk->first_minor = drive << 6; + disk->gd_dev = MKDEV(MAJOR_NR, drive << 6); disk->fops = &hd_fops; sprintf(disk->disk_name, "hd%c", 'a'+drive); disk->private_data = p; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/md/dm.c linux-2.6.18-rc1-lem/drivers/md/dm.c --- linux-2.6.18-rc1/drivers/md/dm.c 2006-07-09 17:54:10.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/md/dm.c 2006-07-09 20:39:54.000000000 -0700 @@ -929,8 +929,7 @@ static struct mapped_device *alloc_dev(i init_waitqueue_head(&md->wait); init_waitqueue_head(&md->eventq); - md->disk->major = _major; - md->disk->first_minor = minor; + md->disk->gd_dev = MKDEV(_major, minor); md->disk->fops = &dm_blk_dops; md->disk->queue = md->queue; md->disk->private_data = md; @@ -963,7 +962,7 @@ static struct mapped_device *alloc_dev(i static void free_dev(struct mapped_device *md) { - int minor = md->disk->first_minor; + int minor = MINOR(md->disk->gd_dev); if (md->suspended_bdev) { thaw_bdev(md->suspended_bdev, NULL); @@ -1073,7 +1072,7 @@ static struct mapped_device *dm_find_md( md = idr_find(&_minor_idr, minor); if (md && (md == MINOR_ALLOCED || - (dm_disk(md)->first_minor != minor) || + MINOR(dm_disk(md)->gd_dev) != minor || test_bit(DMF_FREEING, &md->flags))) { md = NULL; goto out; @@ -1124,7 +1123,7 @@ void dm_put(struct mapped_device *md) if (atomic_dec_and_lock(&md->holders, &_minor_lock)) { map = dm_get_table(md); - idr_replace(&_minor_idr, MINOR_ALLOCED, dm_disk(md)->first_minor); + idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(dm_disk(md)->gd_dev)); set_bit(DMF_FREEING, &md->flags); spin_unlock(&_minor_lock); if (!dm_suspended(md)) { @@ -1232,7 +1231,7 @@ int dm_suspend(struct mapped_device *md, /* This does not get reverted if there's an error later. */ dm_table_presuspend_targets(map); - md->suspended_bdev = bdget_disk(md->disk, 0); + md->suspended_bdev = bdget_disk(md->disk); if (!md->suspended_bdev) { DMWARN("bdget failed in dm_suspend"); r = -ENOMEM; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/md/dm-ioctl.c linux-2.6.18-rc1-lem/drivers/md/dm-ioctl.c --- linux-2.6.18-rc1/drivers/md/dm-ioctl.c 2006-07-09 17:54:10.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/md/dm-ioctl.c 2006-07-09 20:40:27.000000000 -0700 @@ -423,7 +423,7 @@ static int list_devices(struct dm_ioctl old_nl->next = (uint32_t) ((void *) nl - (void *) old_nl); disk = dm_disk(hc->md); - nl->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor)); + nl->dev = huge_encode_dev(disk->gd_dev); nl->next = 0; strcpy(nl->name, hc->name); @@ -536,7 +536,7 @@ static int __dev_status(struct mapped_de if (dm_suspended(md)) param->flags |= DM_SUSPEND_FLAG; - param->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor)); + param->dev = huge_encode_dev(disk->gd_dev); /* * Yes, this will be out of date by the time it gets back diff -urp -X dontdiff linux-2.6.18-rc1/drivers/md/md.c linux-2.6.18-rc1-lem/drivers/md/md.c --- linux-2.6.18-rc1/drivers/md/md.c 2006-07-09 17:54:11.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/md/md.c 2006-07-09 20:12:03.000000000 -0700 @@ -2907,8 +2907,7 @@ static struct kobject *md_probe(dev_t de mddev_put(mddev); return NULL; } - disk->major = MAJOR(dev); - disk->first_minor = unit << shift; + disk->gd_dev = dev; if (partitioned) sprintf(disk->disk_name, "md_d%d", unit); else @@ -4054,7 +4053,7 @@ static int update_size(mddev_t *mddev, u if (!rv) { struct block_device *bdev; - bdev = bdget_disk(mddev->gendisk, 0); + bdev = bdget_disk(mddev->gendisk); if (bdev) { mutex_lock(&bdev->bd_inode->i_mutex); i_size_write(bdev->bd_inode, (loff_t)mddev->array_size << 10); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/md/raid5.c linux-2.6.18-rc1-lem/drivers/md/raid5.c --- linux-2.6.18-rc1/drivers/md/raid5.c 2006-07-09 17:54:11.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/md/raid5.c 2006-07-09 20:12:03.000000000 -0700 @@ -3604,7 +3604,7 @@ static void end_reshape(raid5_conf_t *co set_capacity(conf->mddev->gendisk, conf->mddev->array_size << 1); conf->mddev->changed = 1; - bdev = bdget_disk(conf->mddev->gendisk, 0); + bdev = bdget_disk(conf->mddev->gendisk); if (bdev) { mutex_lock(&bdev->bd_inode->i_mutex); i_size_write(bdev->bd_inode, conf->mddev->array_size << 10); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/message/i2o/i2o_block.c linux-2.6.18-rc1-lem/drivers/message/i2o/i2o_block.c --- linux-2.6.18-rc1/drivers/message/i2o/i2o_block.c 2006-07-09 17:54:15.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/message/i2o/i2o_block.c 2006-07-09 20:09:48.000000000 -0700 @@ -1010,7 +1010,6 @@ static struct i2o_block_device *i2o_bloc blk_queue_prep_rq(queue, i2o_block_prep_req_fn); blk_queue_issue_flush_fn(queue, i2o_block_issue_flush); - gd->major = I2O_MAJOR; gd->queue = queue; gd->fops = &i2o_block_fops; gd->private_data = dev; @@ -1087,7 +1086,7 @@ static int i2o_block_probe(struct device /* setup gendisk */ gd = i2o_blk_dev->gd; - gd->first_minor = unit << 4; + gd->gd_dev = MKDEV(I2O_MAJOR, unit << 4); sprintf(gd->disk_name, "i2o/hd%c", 'a' + unit); gd->driverfs_dev = &i2o_dev->device; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/mmc/mmc_block.c linux-2.6.18-rc1-lem/drivers/mmc/mmc_block.c --- linux-2.6.18-rc1/drivers/mmc/mmc_block.c 2006-07-09 17:54:15.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/mmc/mmc_block.c 2006-07-09 20:12:03.000000000 -0700 @@ -388,8 +388,7 @@ static struct mmc_blk_data *mmc_blk_allo md->queue.issue_fn = mmc_blk_issue_rq; md->queue.data = md; - md->disk->major = major; - md->disk->first_minor = devidx << MMC_SHIFT; + md->disk->gd_dev = MKDEV(major, devidx << MMC_SHIFT); md->disk->fops = &mmc_bdops; md->disk->private_data = md; md->disk->queue = md->queue.queue; @@ -496,7 +495,7 @@ static void mmc_blk_remove(struct mmc_ca */ md->disk->queue = NULL; - devidx = md->disk->first_minor >> MMC_SHIFT; + devidx = MINOR(md->disk->gd_dev) >> MMC_SHIFT; __clear_bit(devidx, dev_use); mmc_blk_put(md); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/mtd/mtd_blkdevs.c linux-2.6.18-rc1-lem/drivers/mtd/mtd_blkdevs.c --- linux-2.6.18-rc1/drivers/mtd/mtd_blkdevs.c 2006-06-21 14:14:32.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/mtd/mtd_blkdevs.c 2006-07-09 20:12:03.000000000 -0700 @@ -278,8 +278,7 @@ int add_mtd_blktrans_dev(struct mtd_blkt list_del(&new->list); return -ENOMEM; } - gd->major = tr->major; - gd->first_minor = (new->devnum) << tr->part_bits; + gd->gd_dev = MKDEV(tr->major, new->devnum << tr->part_bits); gd->fops = &mtd_blktrans_ops; if (tr->part_bits) diff -urp -X dontdiff linux-2.6.18-rc1/drivers/s390/block/dasd_genhd.c linux-2.6.18-rc1-lem/drivers/s390/block/dasd_genhd.c --- linux-2.6.18-rc1/drivers/s390/block/dasd_genhd.c 2006-07-09 17:54:27.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/s390/block/dasd_genhd.c 2006-07-09 20:12:03.000000000 -0700 @@ -40,8 +40,7 @@ dasd_gendisk_alloc(struct dasd_device *d return -ENOMEM; /* Initialize gendisk structure. */ - gdp->major = DASD_MAJOR; - gdp->first_minor = device->devindex << DASD_PARTN_BITS; + gdp->gd_dev = MKDEV(DASD_MAJOR, device->devindex << DASD_PARTN_BITS); gdp->fops = &dasd_device_operations; gdp->driverfs_dev = &device->cdev->dev; @@ -97,7 +96,7 @@ dasd_scan_partitions(struct dasd_device { struct block_device *bdev; - bdev = bdget_disk(device->gdp, 0); + bdev = bdget_disk(device->gdp); if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0) return -ENODEV; /* diff -urp -X dontdiff linux-2.6.18-rc1/drivers/s390/block/dasd_ioctl.c linux-2.6.18-rc1-lem/drivers/s390/block/dasd_ioctl.c --- linux-2.6.18-rc1/drivers/s390/block/dasd_ioctl.c 2006-07-09 17:54:27.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/s390/block/dasd_ioctl.c 2006-07-09 20:12:03.000000000 -0700 @@ -156,7 +156,7 @@ dasd_format(struct dasd_device * device, * enabling the device later. */ if (fdata->start_unit == 0) { - struct block_device *bdev = bdget_disk(device->gdp, 0); + struct block_device *bdev = bdget_disk(device->gdp); bdev->bd_inode->i_blkbits = blksize_bits(fdata->blksize); bdput(bdev); } diff -urp -X dontdiff linux-2.6.18-rc1/drivers/s390/block/dasd_proc.c linux-2.6.18-rc1-lem/drivers/s390/block/dasd_proc.c --- linux-2.6.18-rc1/drivers/s390/block/dasd_proc.c 2006-07-09 17:54:27.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/s390/block/dasd_proc.c 2006-07-09 20:12:03.000000000 -0700 @@ -67,7 +67,8 @@ dasd_devices_show(struct seq_file *m, vo /* Print kdev. */ if (device->gdp) seq_printf(m, " at (%3d:%6d)", - device->gdp->major, device->gdp->first_minor); + MAJOR(device->gdp->gd_dev), + MINOR(device->gdp->gd_dev)); else seq_printf(m, " at (???:??????)"); /* Print device name. */ diff -urp -X dontdiff linux-2.6.18-rc1/drivers/s390/block/dcssblk.c linux-2.6.18-rc1-lem/drivers/s390/block/dcssblk.c --- linux-2.6.18-rc1/drivers/s390/block/dcssblk.c 2006-06-21 14:14:43.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/s390/block/dcssblk.c 2006-07-09 20:12:03.000000000 -0700 @@ -114,13 +114,13 @@ dcssblk_assign_free_minor(struct dcssblk found = 0; // test if minor available list_for_each_entry(entry, &dcssblk_devices, lh) - if (minor == entry->gd->first_minor) + if (minor == MINOR(entry->gd->gd_dev)) found++; if (!found) break; // got unused minor } if (found) return -EBUSY; - dev_info->gd->first_minor = minor; + dev_info->gd->gd_dev = MKDEV(dcssblk_major, minor); return 0; } @@ -404,7 +404,6 @@ dcssblk_add_store(struct device *dev, st rc = -ENOMEM; goto free_dev_info; } - dev_info->gd->major = dcssblk_major; dev_info->gd->fops = &dcssblk_devops; dev_info->dcssblk_queue = blk_alloc_queue(GFP_KERNEL); dev_info->gd->queue = dev_info->dcssblk_queue; @@ -442,7 +441,7 @@ dcssblk_add_store(struct device *dev, st goto unload_seg; } sprintf(dev_info->gd->disk_name, "dcssblk%d", - dev_info->gd->first_minor); + MINOR(dev_info->gd->gd_dev)); list_add_tail(&dev_info->lh, &dcssblk_devices); if (!try_module_get(THIS_MODULE)) { diff -urp -X dontdiff linux-2.6.18-rc1/drivers/s390/block/xpram.c linux-2.6.18-rc1-lem/drivers/s390/block/xpram.c --- linux-2.6.18-rc1/drivers/s390/block/xpram.c 2006-07-09 17:54:27.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/s390/block/xpram.c 2006-07-09 20:12:03.000000000 -0700 @@ -460,8 +460,7 @@ static int __init xpram_setup_blkdev(voi xpram_devices[i].size = xpram_sizes[i] / 4; xpram_devices[i].offset = offset; offset += xpram_devices[i].size; - disk->major = XPRAM_MAJOR; - disk->first_minor = i; + disk->gd_dev = MKDEV(XPRAM_MAJOR, i); disk->fops = &xpram_devops; disk->private_data = &xpram_devices[i]; disk->queue = xpram_queue; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/s390/char/tape_block.c linux-2.6.18-rc1-lem/drivers/s390/char/tape_block.c --- linux-2.6.18-rc1/drivers/s390/char/tape_block.c 2006-07-09 17:54:27.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/s390/char/tape_block.c 2006-07-09 20:12:03.000000000 -0700 @@ -240,8 +240,7 @@ tapeblock_setup_device(struct tape_devic goto cleanup_queue; } - disk->major = tapeblock_major; - disk->first_minor = device->first_minor; + disk->gd_dev = MKDEV(tapeblock_major, device->first_minor); disk->fops = &tapeblock_fops; disk->private_data = tape_get_device_reference(device); disk->queue = blkdat->request_queue; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/sbus/char/jsflash.c linux-2.6.18-rc1-lem/drivers/sbus/char/jsflash.c --- linux-2.6.18-rc1/drivers/sbus/char/jsflash.c 2006-01-03 20:03:29.000000000 -0800 +++ linux-2.6.18-rc1-lem/drivers/sbus/char/jsflash.c 2006-07-09 20:12:03.000000000 -0700 @@ -575,8 +575,7 @@ static int jsfd_init(void) jsf = &jsf0; /* actually, &jsfv[i >> JSF_PART_BITS] */ jdp = &jsf->dv[i&JSF_PART_MASK]; - disk->major = JSFD_MAJOR; - disk->first_minor = i; + disk->gd_dev = MKDEV(JSFD_MAJOR, i); sprintf(disk->disk_name, "jsfd%d", i); disk->fops = &jsfd_fops; set_capacity(disk, jdp->dsize >> 9); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/scsi/sd.c linux-2.6.18-rc1-lem/drivers/scsi/sd.c --- linux-2.6.18-rc1/drivers/scsi/sd.c 2006-07-09 17:54:32.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/scsi/sd.c 2006-07-09 20:12:03.000000000 -0700 @@ -1617,6 +1617,7 @@ static int sd_probe(struct device *dev) struct scsi_device *sdp = to_scsi_device(dev); struct scsi_disk *sdkp; struct gendisk *gd; + unsigned int major; u32 index; int error; @@ -1671,8 +1672,8 @@ static int sd_probe(struct device *dev) sdp->timeout = SD_MOD_TIMEOUT; } - gd->major = sd_major((index & 0xf0) >> 4); - gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); + major = sd_major((index & 0xf0) >> 4); + gd->gd_dev = MKDEV(major, ((index & 0xf) << 4) | (index & 0xfff00)); gd->minors = 16; gd->fops = &sd_fops; diff -urp -X dontdiff linux-2.6.18-rc1/drivers/scsi/sg.c linux-2.6.18-rc1-lem/drivers/scsi/sg.c --- linux-2.6.18-rc1/drivers/scsi/sg.c 2006-07-09 17:54:32.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/scsi/sg.c 2006-07-09 20:12:03.000000000 -0700 @@ -1362,7 +1362,7 @@ static int sg_alloc(struct gendisk *disk SCSI_LOG_TIMEOUT(3, printk("sg_alloc: dev=%d \n", k)); sprintf(disk->disk_name, "sg%d", k); - disk->first_minor = k; + disk->gd_dev = MKDEV(SCSI_GENERIC_MAJOR, k); sdp->disk = disk; sdp->device = scsidp; init_waitqueue_head(&sdp->o_excl_wait); @@ -1408,7 +1408,6 @@ sg_add(struct class_device *cl_dev, stru printk(KERN_WARNING "alloc_disk failed\n"); return -ENOMEM; } - disk->major = SCSI_GENERIC_MAJOR; error = -ENOMEM; cdev = cdev_alloc(); diff -urp -X dontdiff linux-2.6.18-rc1/drivers/scsi/sr.c linux-2.6.18-rc1-lem/drivers/scsi/sr.c --- linux-2.6.18-rc1/drivers/scsi/sr.c 2006-07-09 17:54:32.000000000 -0700 +++ linux-2.6.18-rc1-lem/drivers/scsi/sr.c 2006-07-09 20:12:03.000000000 -0700 @@ -564,8 +564,7 @@ static int sr_probe(struct device *dev) __set_bit(minor, sr_index_bits); spin_unlock(&sr_index_lock); - disk->major = SCSI_CDROM_MAJOR; - disk->first_minor = minor; + disk->gd_dev = MKDEV(SCSI_CDROM_MAJOR, minor); sprintf(disk->disk_name, "sr%d", minor); disk->fops = &sr_bdops; disk->flags = GENHD_FL_CD; @@ -853,7 +852,7 @@ static void sr_kref_release(struct kref struct gendisk *disk = cd->disk; spin_lock(&sr_index_lock); - clear_bit(disk->first_minor, sr_index_bits); + clear_bit(MINOR(disk->gd_dev), sr_index_bits); spin_unlock(&sr_index_lock); unregister_cdrom(&cd->cdi); diff -urp -X dontdiff linux-2.6.18-rc1/fs/block_dev.c linux-2.6.18-rc1-lem/fs/block_dev.c --- linux-2.6.18-rc1/fs/block_dev.c 2006-07-09 17:54:41.000000000 -0700 +++ linux-2.6.18-rc1-lem/fs/block_dev.c 2006-07-09 20:12:16.000000000 -0700 @@ -929,7 +929,7 @@ do_open(struct block_device *bdev, struc } else { struct hd_struct *p; struct block_device *whole; - whole = bdget_disk(disk, 0); + whole = bdget_disk(disk); ret = -ENOMEM; if (!whole) goto out_first; diff -urp -X dontdiff linux-2.6.18-rc1/fs/partitions/check.c linux-2.6.18-rc1-lem/fs/partitions/check.c --- linux-2.6.18-rc1/fs/partitions/check.c 2006-07-09 17:54:49.000000000 -0700 +++ linux-2.6.18-rc1-lem/fs/partitions/check.c 2006-07-09 20:12:16.000000000 -0700 @@ -129,7 +129,7 @@ char *disk_name(struct gendisk *hd, int const char *bdevname(struct block_device *bdev, char *buf) { - int part = MINOR(bdev->bd_dev) - bdev->bd_disk->first_minor; + int part = bdev->bd_dev - bdev->bd_disk->gd_dev; return disk_name(bdev->bd_disk, part, buf); } @@ -226,9 +226,7 @@ static ssize_t part_uevent_store(struct } static ssize_t part_dev_read(struct hd_struct * p, char *page) { - struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj); - dev_t dev = MKDEV(disk->major, disk->first_minor + p->partno); - return print_dev_t(page, dev); + return print_dev_t(page, p->dev); } static ssize_t part_start_read(struct hd_struct * p, char *page) { @@ -338,7 +336,10 @@ void add_partition(struct gendisk *disk, memset(p, 0, sizeof(*p)); p->start_sect = start; p->nr_sects = len; - p->partno = part; + if (disk->fops->partmap) + p->dev = disk->fops->partmap(disk, part); + else + p->dev = disk->gd_dev + part; if (isdigit(disk->kobj.name[strlen(disk->kobj.name)-1])) snprintf(p->kobj.name,KOBJ_NAME_LEN,"%sp%d",disk->kobj.name,part); @@ -416,7 +417,7 @@ void register_disk(struct gendisk *disk) if (!get_capacity(disk)) goto exit; - bdev = bdget_disk(disk, 0); + bdev = bdget_disk(disk); if (!bdev) goto exit; diff -urp -X dontdiff linux-2.6.18-rc1/include/linux/fs.h linux-2.6.18-rc1-lem/include/linux/fs.h --- linux-2.6.18-rc1/include/linux/fs.h 2006-07-09 17:55:06.000000000 -0700 +++ linux-2.6.18-rc1-lem/include/linux/fs.h 2006-07-09 20:12:16.000000000 -0700 @@ -1011,6 +1011,7 @@ struct block_device_operations { int (*media_changed) (struct gendisk *); int (*revalidate_disk) (struct gendisk *); int (*getgeo)(struct block_device *, struct hd_geometry *); + dev_t (*partmap)(struct gendisk *, int partno); struct module *owner; }; diff -urp -X dontdiff linux-2.6.18-rc1/include/linux/genhd.h linux-2.6.18-rc1-lem/include/linux/genhd.h --- linux-2.6.18-rc1/include/linux/genhd.h 2006-07-09 17:55:06.000000000 -0700 +++ linux-2.6.18-rc1-lem/include/linux/genhd.h 2006-07-09 20:12:16.000000000 -0700 @@ -80,7 +80,8 @@ struct hd_struct { struct kobject kobj; struct kobject *holder_dir; unsigned ios[2], sectors[2]; /* READs and WRITEs */ - int policy, partno; + int policy; + dev_t dev; }; #define GENHD_FL_REMOVABLE 1 @@ -88,6 +89,7 @@ struct hd_struct { #define GENHD_FL_CD 8 #define GENHD_FL_UP 16 #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 +#define GENHD_FL_SPARSE_MINORS 64 struct disk_stats { unsigned long sectors[2]; /* READs and WRITEs */ @@ -97,10 +99,9 @@ struct disk_stats { unsigned long io_ticks; unsigned long time_in_queue; }; - + struct gendisk { - int major; /* major number of driver */ - int first_minor; + dev_t gd_dev; /* whole device */ int minors; /* maximum number of minors, =1 for * disks that can't be partitioned. */ char disk_name[32]; /* name of major driver */ @@ -412,9 +413,9 @@ extern void blk_register_region(dev_t de void *data); extern void blk_unregister_region(dev_t dev, unsigned long range); -static inline struct block_device *bdget_disk(struct gendisk *disk, int index) +static inline struct block_device *bdget_disk(struct gendisk *disk) { - return bdget(MKDEV(disk->major, disk->first_minor) + index); + return bdget(disk->gd_dev); } #endif - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |