aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2008-09-03 03:01:48 -0400
committerJens Axboe <jens.axboe@oracle.com>2008-10-09 02:56:05 -0400
commitf331c0296f2a9fee0d396a70598b954062603015 (patch)
treef74c467d58940131d97d90c4ea549843185e6ef0
parentcf771cb5a7b716f3f9e532fd42a1e3a0a75adec5 (diff)
block: don't depend on consecutive minor space
* Implement disk_devt() and part_devt() and use them to directly access devt instead of computing it from ->major and ->first_minor. Note that all references to ->major and ->first_minor outside of block layer is used to determine devt of the disk (the part0) and as ->major and ->first_minor will continue to represent devt for the disk, converting these users aren't strictly necessary. However, convert them for consistency. * Implement disk_max_parts() to avoid directly deferencing genhd->minors. * Update bdget_disk() such that it doesn't assume consecutive minor space. * Move devt computation from register_disk() to add_disk() and make it the only one (all other usages use the initially determined value). These changes clean up the code and will help disk->part dereference fix and extended block device numbers. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--block/genhd.c107
-rw-r--r--block/ioctl.c6
-rw-r--r--drivers/block/pktcdvd.c2
-rw-r--r--drivers/block/ps3disk.c2
-rw-r--r--drivers/char/random.c6
-rw-r--r--drivers/md/dm-ioctl.c4
-rw-r--r--drivers/md/dm-stripe.c4
-rw-r--r--drivers/md/dm.c7
-rw-r--r--drivers/memstick/core/mspro_block.c2
-rw-r--r--drivers/mmc/card/block.c2
-rw-r--r--drivers/s390/block/dasd_proc.c3
-rw-r--r--drivers/s390/block/dcssblk.c4
-rw-r--r--drivers/scsi/sr.c2
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/partitions/check.c19
-rw-r--r--include/linux/genhd.h27
16 files changed, 132 insertions, 67 deletions
diff --git a/block/genhd.c b/block/genhd.c
index dc9ad4c171e2..fa32d09fda24 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -186,13 +186,14 @@ void add_disk(struct gendisk *disk)
186 int retval; 186 int retval;
187 187
188 disk->flags |= GENHD_FL_UP; 188 disk->flags |= GENHD_FL_UP;
189 blk_register_region(MKDEV(disk->major, disk->first_minor), 189 disk->dev.devt = MKDEV(disk->major, disk->first_minor);
190 disk->minors, NULL, exact_match, exact_lock, disk); 190 blk_register_region(disk_devt(disk), disk->minors, NULL,
191 exact_match, exact_lock, disk);
191 register_disk(disk); 192 register_disk(disk);
192 blk_register_queue(disk); 193 blk_register_queue(disk);
193 194
194 bdi = &disk->queue->backing_dev_info; 195 bdi = &disk->queue->backing_dev_info;
195 bdi_register_dev(bdi, MKDEV(disk->major, disk->first_minor)); 196 bdi_register_dev(bdi, disk_devt(disk));
196 retval = sysfs_create_link(&disk->dev.kobj, &bdi->dev->kobj, "bdi"); 197 retval = sysfs_create_link(&disk->dev.kobj, &bdi->dev->kobj, "bdi");
197 WARN_ON(retval); 198 WARN_ON(retval);
198} 199}
@@ -205,8 +206,7 @@ void unlink_gendisk(struct gendisk *disk)
205 sysfs_remove_link(&disk->dev.kobj, "bdi"); 206 sysfs_remove_link(&disk->dev.kobj, "bdi");
206 bdi_unregister(&disk->queue->backing_dev_info); 207 bdi_unregister(&disk->queue->backing_dev_info);
207 blk_unregister_queue(disk); 208 blk_unregister_queue(disk);
208 blk_unregister_region(MKDEV(disk->major, disk->first_minor), 209 blk_unregister_region(disk_devt(disk), disk->minors);
209 disk->minors);
210} 210}
211 211
212/** 212/**
@@ -225,6 +225,38 @@ struct gendisk *get_gendisk(dev_t devt, int *partno)
225 return kobj ? dev_to_disk(dev) : NULL; 225 return kobj ? dev_to_disk(dev) : NULL;
226} 226}
227 227
228/**
229 * bdget_disk - do bdget() by gendisk and partition number
230 * @disk: gendisk of interest
231 * @partno: partition number
232 *
233 * Find partition @partno from @disk, do bdget() on it.
234 *
235 * CONTEXT:
236 * Don't care.
237 *
238 * RETURNS:
239 * Resulting block_device on success, NULL on failure.
240 */
241extern struct block_device *bdget_disk(struct gendisk *disk, int partno)
242{
243 dev_t devt = MKDEV(0, 0);
244
245 if (partno == 0)
246 devt = disk_devt(disk);
247 else {
248 struct hd_struct *part = disk->part[partno - 1];
249
250 if (part && part->nr_sects)
251 devt = part_devt(part);
252 }
253
254 if (likely(devt != MKDEV(0, 0)))
255 return bdget(devt);
256 return NULL;
257}
258EXPORT_SYMBOL(bdget_disk);
259
228/* 260/*
229 * print a full list of all partitions - intended for places where the root 261 * print a full list of all partitions - intended for places where the root
230 * filesystem can't be mounted and thus to give the victim some idea of what 262 * filesystem can't be mounted and thus to give the victim some idea of what
@@ -255,7 +287,7 @@ void __init printk_all_partitions(void)
255 * option takes. 287 * option takes.
256 */ 288 */
257 printk("%02x%02x %10llu %s", 289 printk("%02x%02x %10llu %s",
258 disk->major, disk->first_minor, 290 MAJOR(disk_devt(disk)), MINOR(disk_devt(disk)),
259 (unsigned long long)get_capacity(disk) >> 1, 291 (unsigned long long)get_capacity(disk) >> 1,
260 disk_name(disk, 0, buf)); 292 disk_name(disk, 0, buf));
261 if (disk->driverfs_dev != NULL && 293 if (disk->driverfs_dev != NULL &&
@@ -266,15 +298,15 @@ void __init printk_all_partitions(void)
266 printk(" (driver?)\n"); 298 printk(" (driver?)\n");
267 299
268 /* now show the partitions */ 300 /* now show the partitions */
269 for (n = 0; n < disk->minors - 1; ++n) { 301 for (n = 0; n < disk_max_parts(disk); ++n) {
270 if (disk->part[n] == NULL) 302 struct hd_struct *part = disk->part[n];
271 continue; 303
272 if (disk->part[n]->nr_sects == 0) 304 if (!part || !part->nr_sects)
273 continue; 305 continue;
274 printk(" %02x%02x %10llu %s\n", 306 printk(" %02x%02x %10llu %s\n",
275 disk->major, n + 1 + disk->first_minor, 307 MAJOR(part_devt(part)), MINOR(part_devt(part)),
276 (unsigned long long)disk->part[n]->nr_sects >> 1, 308 (unsigned long long)part->nr_sects >> 1,
277 disk_name(disk, n + 1, buf)); 309 disk_name(disk, part->partno, buf));
278 } 310 }
279 } 311 }
280 class_dev_iter_exit(&iter); 312 class_dev_iter_exit(&iter);
@@ -343,26 +375,27 @@ static int show_partition(struct seq_file *seqf, void *v)
343 char buf[BDEVNAME_SIZE]; 375 char buf[BDEVNAME_SIZE];
344 376
345 /* Don't show non-partitionable removeable devices or empty devices */ 377 /* Don't show non-partitionable removeable devices or empty devices */
346 if (!get_capacity(sgp) || 378 if (!get_capacity(sgp) || (!disk_max_parts(sgp) &&
347 (sgp->minors == 1 && (sgp->flags & GENHD_FL_REMOVABLE))) 379 (sgp->flags & GENHD_FL_REMOVABLE)))
348 return 0; 380 return 0;
349 if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO) 381 if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)
350 return 0; 382 return 0;
351 383
352 /* show the full disk and all non-0 size partitions of it */ 384 /* show the full disk and all non-0 size partitions of it */
353 seq_printf(seqf, "%4d %4d %10llu %s\n", 385 seq_printf(seqf, "%4d %4d %10llu %s\n",
354 sgp->major, sgp->first_minor, 386 MAJOR(disk_devt(sgp)), MINOR(disk_devt(sgp)),
355 (unsigned long long)get_capacity(sgp) >> 1, 387 (unsigned long long)get_capacity(sgp) >> 1,
356 disk_name(sgp, 0, buf)); 388 disk_name(sgp, 0, buf));
357 for (n = 0; n < sgp->minors - 1; n++) { 389 for (n = 0; n < disk_max_parts(sgp); n++) {
358 if (!sgp->part[n]) 390 struct hd_struct *part = sgp->part[n];
391 if (!part)
359 continue; 392 continue;
360 if (sgp->part[n]->nr_sects == 0) 393 if (part->nr_sects == 0)
361 continue; 394 continue;
362 seq_printf(seqf, "%4d %4d %10llu %s\n", 395 seq_printf(seqf, "%4d %4d %10llu %s\n",
363 sgp->major, n + 1 + sgp->first_minor, 396 MAJOR(part_devt(part)), MINOR(part_devt(part)),
364 (unsigned long long)sgp->part[n]->nr_sects >> 1 , 397 (unsigned long long)part->nr_sects >> 1,
365 disk_name(sgp, n + 1, buf)); 398 disk_name(sgp, part->partno, buf));
366 } 399 }
367 400
368 return 0; 401 return 0;
@@ -578,7 +611,8 @@ static int diskstats_show(struct seq_file *seqf, void *v)
578 disk_round_stats(gp); 611 disk_round_stats(gp);
579 preempt_enable(); 612 preempt_enable();
580 seq_printf(seqf, "%4d %4d %s %lu %lu %llu %u %lu %lu %llu %u %u %u %u\n", 613 seq_printf(seqf, "%4d %4d %s %lu %lu %llu %u %lu %lu %llu %u %u %u %u\n",
581 gp->major, gp->first_minor, disk_name(gp, 0, buf), 614 MAJOR(disk_devt(gp)), MINOR(disk_devt(gp)),
615 disk_name(gp, 0, buf),
582 disk_stat_read(gp, ios[0]), disk_stat_read(gp, merges[0]), 616 disk_stat_read(gp, ios[0]), disk_stat_read(gp, merges[0]),
583 (unsigned long long)disk_stat_read(gp, sectors[0]), 617 (unsigned long long)disk_stat_read(gp, sectors[0]),
584 jiffies_to_msecs(disk_stat_read(gp, ticks[0])), 618 jiffies_to_msecs(disk_stat_read(gp, ticks[0])),
@@ -590,7 +624,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
590 jiffies_to_msecs(disk_stat_read(gp, time_in_queue))); 624 jiffies_to_msecs(disk_stat_read(gp, time_in_queue)));
591 625
592 /* now show all non-0 size partitions of it */ 626 /* now show all non-0 size partitions of it */
593 for (n = 0; n < gp->minors - 1; n++) { 627 for (n = 0; n < disk_max_parts(gp); n++) {
594 struct hd_struct *hd = gp->part[n]; 628 struct hd_struct *hd = gp->part[n];
595 629
596 if (!hd || !hd->nr_sects) 630 if (!hd || !hd->nr_sects)
@@ -601,8 +635,8 @@ static int diskstats_show(struct seq_file *seqf, void *v)
601 preempt_enable(); 635 preempt_enable();
602 seq_printf(seqf, "%4d %4d %s %lu %lu %llu " 636 seq_printf(seqf, "%4d %4d %s %lu %lu %llu "
603 "%u %lu %lu %llu %u %u %u %u\n", 637 "%u %lu %lu %llu %u %u %u %u\n",
604 gp->major, n + gp->first_minor + 1, 638 MAJOR(part_devt(hd)), MINOR(part_devt(hd)),
605 disk_name(gp, n + 1, buf), 639 disk_name(gp, hd->partno, buf),
606 part_stat_read(hd, ios[0]), 640 part_stat_read(hd, ios[0]),
607 part_stat_read(hd, merges[0]), 641 part_stat_read(hd, merges[0]),
608 (unsigned long long)part_stat_read(hd, sectors[0]), 642 (unsigned long long)part_stat_read(hd, sectors[0]),
@@ -661,11 +695,22 @@ dev_t blk_lookup_devt(const char *name, int partno)
661 while ((dev = class_dev_iter_next(&iter))) { 695 while ((dev = class_dev_iter_next(&iter))) {
662 struct gendisk *disk = dev_to_disk(dev); 696 struct gendisk *disk = dev_to_disk(dev);
663 697
664 if (!strcmp(dev->bus_id, name) && partno < disk->minors) { 698 if (strcmp(dev->bus_id, name))
665 devt = MKDEV(MAJOR(dev->devt), 699 continue;
666 MINOR(dev->devt) + partno); 700 if (partno < 0 || partno > disk_max_parts(disk))
667 break; 701 continue;
702
703 if (partno == 0)
704 devt = disk_devt(disk);
705 else {
706 struct hd_struct *part = disk->part[partno - 1];
707
708 if (!part || !part->nr_sects)
709 continue;
710
711 devt = part_devt(part);
668 } 712 }
713 break;
669 } 714 }
670 class_dev_iter_exit(&iter); 715 class_dev_iter_exit(&iter);
671 return devt; 716 return devt;
@@ -755,7 +800,7 @@ void set_disk_ro(struct gendisk *disk, int flag)
755{ 800{
756 int i; 801 int i;
757 disk->policy = flag; 802 disk->policy = flag;
758 for (i = 0; i < disk->minors - 1; i++) 803 for (i = 0; i < disk_max_parts(disk); i++)
759 if (disk->part[i]) disk->part[i]->policy = flag; 804 if (disk->part[i]) disk->part[i]->policy = flag;
760} 805}
761 806
diff --git a/block/ioctl.c b/block/ioctl.c
index d77f5e280a6e..403f7d7e0c28 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -29,7 +29,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
29 if (bdev != bdev->bd_contains) 29 if (bdev != bdev->bd_contains)
30 return -EINVAL; 30 return -EINVAL;
31 partno = p.pno; 31 partno = p.pno;
32 if (partno <= 0 || partno >= disk->minors) 32 if (partno <= 0 || partno > disk_max_parts(disk))
33 return -EINVAL; 33 return -EINVAL;
34 switch (a.op) { 34 switch (a.op) {
35 case BLKPG_ADD_PARTITION: 35 case BLKPG_ADD_PARTITION:
@@ -47,7 +47,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
47 mutex_lock(&bdev->bd_mutex); 47 mutex_lock(&bdev->bd_mutex);
48 48
49 /* overlap? */ 49 /* overlap? */
50 for (i = 0; i < disk->minors - 1; i++) { 50 for (i = 0; i < disk_max_parts(disk); i++) {
51 struct hd_struct *s = disk->part[i]; 51 struct hd_struct *s = disk->part[i];
52 52
53 if (!s) 53 if (!s)
@@ -96,7 +96,7 @@ static int blkdev_reread_part(struct block_device *bdev)
96 struct gendisk *disk = bdev->bd_disk; 96 struct gendisk *disk = bdev->bd_disk;
97 int res; 97 int res;
98 98
99 if (disk->minors == 1 || bdev != bdev->bd_contains) 99 if (!disk_max_parts(disk) || bdev != bdev->bd_contains)
100 return -EINVAL; 100 return -EINVAL;
101 if (!capable(CAP_SYS_ADMIN)) 101 if (!capable(CAP_SYS_ADMIN))
102 return -EACCES; 102 return -EACCES;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 29b7a648cc6e..e1a90bbb4747 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2911,7 +2911,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
2911 if (!disk->queue) 2911 if (!disk->queue)
2912 goto out_mem2; 2912 goto out_mem2;
2913 2913
2914 pd->pkt_dev = MKDEV(disk->major, disk->first_minor); 2914 pd->pkt_dev = MKDEV(pktdev_major, idx);
2915 ret = pkt_new_dev(pd, dev); 2915 ret = pkt_new_dev(pd, dev);
2916 if (ret) 2916 if (ret)
2917 goto out_new_dev; 2917 goto out_new_dev;
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 4b0d6c7f4c66..936466f62afd 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -541,7 +541,7 @@ static int ps3disk_remove(struct ps3_system_bus_device *_dev)
541 struct ps3disk_private *priv = dev->sbd.core.driver_data; 541 struct ps3disk_private *priv = dev->sbd.core.driver_data;
542 542
543 mutex_lock(&ps3disk_mask_mutex); 543 mutex_lock(&ps3disk_mask_mutex);
544 __clear_bit(priv->gendisk->first_minor / PS3DISK_MINORS, 544 __clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS,
545 &ps3disk_mask); 545 &ps3disk_mask);
546 mutex_unlock(&ps3disk_mask_mutex); 546 mutex_unlock(&ps3disk_mask_mutex);
547 del_gendisk(priv->gendisk); 547 del_gendisk(priv->gendisk);
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7ce1ac4baa6d..6af435b89867 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -661,10 +661,10 @@ void add_disk_randomness(struct gendisk *disk)
661 if (!disk || !disk->random) 661 if (!disk || !disk->random)
662 return; 662 return;
663 /* first major is 1, so we get >= 0x200 here */ 663 /* first major is 1, so we get >= 0x200 here */
664 DEBUG_ENT("disk event %d:%d\n", disk->major, disk->first_minor); 664 DEBUG_ENT("disk event %d:%d\n",
665 MAJOR(disk_devt(disk)), MINOR(disk_devt(disk)));
665 666
666 add_timer_randomness(disk->random, 667 add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
667 0x100 + MKDEV(disk->major, disk->first_minor));
668} 668}
669#endif 669#endif
670 670
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index b262c0042de3..c3de311117a1 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -426,7 +426,7 @@ static int list_devices(struct dm_ioctl *param, size_t param_size)
426 old_nl->next = (uint32_t) ((void *) nl - 426 old_nl->next = (uint32_t) ((void *) nl -
427 (void *) old_nl); 427 (void *) old_nl);
428 disk = dm_disk(hc->md); 428 disk = dm_disk(hc->md);
429 nl->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor)); 429 nl->dev = huge_encode_dev(disk_devt(disk));
430 nl->next = 0; 430 nl->next = 0;
431 strcpy(nl->name, hc->name); 431 strcpy(nl->name, hc->name);
432 432
@@ -539,7 +539,7 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param)
539 if (dm_suspended(md)) 539 if (dm_suspended(md))
540 param->flags |= DM_SUSPEND_FLAG; 540 param->flags |= DM_SUSPEND_FLAG;
541 541
542 param->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor)); 542 param->dev = huge_encode_dev(disk_devt(disk));
543 543
544 /* 544 /*
545 * Yes, this will be out of date by the time it gets back 545 * Yes, this will be out of date by the time it gets back
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 4de90ab3968b..b745d8ac625b 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -284,8 +284,8 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio,
284 284
285 memset(major_minor, 0, sizeof(major_minor)); 285 memset(major_minor, 0, sizeof(major_minor));
286 sprintf(major_minor, "%d:%d", 286 sprintf(major_minor, "%d:%d",
287 bio->bi_bdev->bd_disk->major, 287 MAJOR(disk_devt(bio->bi_bdev->bd_disk)),
288 bio->bi_bdev->bd_disk->first_minor); 288 MINOR(disk_devt(bio->bi_bdev->bd_disk)));
289 289
290 /* 290 /*
291 * Test to see which stripe drive triggered the event 291 * Test to see which stripe drive triggered the event
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index ace998ce59f6..a78caad29996 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1146,7 +1146,7 @@ static void unlock_fs(struct mapped_device *md);
1146 1146
1147static void free_dev(struct mapped_device *md) 1147static void free_dev(struct mapped_device *md)
1148{ 1148{
1149 int minor = md->disk->first_minor; 1149 int minor = MINOR(disk_devt(md->disk));
1150 1150
1151 if (md->suspended_bdev) { 1151 if (md->suspended_bdev) {
1152 unlock_fs(md); 1152 unlock_fs(md);
@@ -1267,7 +1267,7 @@ static struct mapped_device *dm_find_md(dev_t dev)
1267 1267
1268 md = idr_find(&_minor_idr, minor); 1268 md = idr_find(&_minor_idr, minor);
1269 if (md && (md == MINOR_ALLOCED || 1269 if (md && (md == MINOR_ALLOCED ||
1270 (dm_disk(md)->first_minor != minor) || 1270 (MINOR(disk_devt(dm_disk(md))) != minor) ||
1271 test_bit(DMF_FREEING, &md->flags))) { 1271 test_bit(DMF_FREEING, &md->flags))) {
1272 md = NULL; 1272 md = NULL;
1273 goto out; 1273 goto out;
@@ -1318,7 +1318,8 @@ void dm_put(struct mapped_device *md)
1318 1318
1319 if (atomic_dec_and_lock(&md->holders, &_minor_lock)) { 1319 if (atomic_dec_and_lock(&md->holders, &_minor_lock)) {
1320 map = dm_get_table(md); 1320 map = dm_get_table(md);
1321 idr_replace(&_minor_idr, MINOR_ALLOCED, dm_disk(md)->first_minor); 1321 idr_replace(&_minor_idr, MINOR_ALLOCED,
1322 MINOR(disk_devt(dm_disk(md))));
1322 set_bit(DMF_FREEING, &md->flags); 1323 set_bit(DMF_FREEING, &md->flags);
1323 spin_unlock(&_minor_lock); 1324 spin_unlock(&_minor_lock);
1324 if (!dm_suspended(md)) { 1325 if (!dm_suspended(md)) {
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index d2d2318dafa4..82bf649ef138 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -197,7 +197,7 @@ static int mspro_block_bd_open(struct inode *inode, struct file *filp)
197static int mspro_block_disk_release(struct gendisk *disk) 197static int mspro_block_disk_release(struct gendisk *disk)
198{ 198{
199 struct mspro_block_data *msb = disk->private_data; 199 struct mspro_block_data *msb = disk->private_data;
200 int disk_id = disk->first_minor >> MSPRO_BLOCK_PART_SHIFT; 200 int disk_id = MINOR(disk_devt(disk)) >> MSPRO_BLOCK_PART_SHIFT;
201 201
202 mutex_lock(&mspro_block_disk_lock); 202 mutex_lock(&mspro_block_disk_lock);
203 203
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index ebc8b9d77613..97156b689e82 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -83,7 +83,7 @@ static void mmc_blk_put(struct mmc_blk_data *md)
83 mutex_lock(&open_lock); 83 mutex_lock(&open_lock);
84 md->usage--; 84 md->usage--;
85 if (md->usage == 0) { 85 if (md->usage == 0) {
86 int devidx = md->disk->first_minor >> MMC_SHIFT; 86 int devidx = MINOR(disk_devt(md->disk)) >> MMC_SHIFT;
87 __clear_bit(devidx, dev_use); 87 __clear_bit(devidx, dev_use);
88 88
89 put_disk(md->disk); 89 put_disk(md->disk);
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 03c0e40a92ff..e3b5c4d3036e 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -76,7 +76,8 @@ dasd_devices_show(struct seq_file *m, void *v)
76 /* Print kdev. */ 76 /* Print kdev. */
77 if (block->gdp) 77 if (block->gdp)
78 seq_printf(m, " at (%3d:%6d)", 78 seq_printf(m, " at (%3d:%6d)",
79 block->gdp->major, block->gdp->first_minor); 79 MAJOR(disk_devt(block->gdp)),
80 MINOR(disk_devt(block->gdp)));
80 else 81 else
81 seq_printf(m, " at (???:??????)"); 82 seq_printf(m, " at (???:??????)");
82 /* Print device name. */ 83 /* Print device name. */
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 711b3004b3e6..9481e4a3f76e 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -114,7 +114,7 @@ dcssblk_assign_free_minor(struct dcssblk_dev_info *dev_info)
114 found = 0; 114 found = 0;
115 // test if minor available 115 // test if minor available
116 list_for_each_entry(entry, &dcssblk_devices, lh) 116 list_for_each_entry(entry, &dcssblk_devices, lh)
117 if (minor == entry->gd->first_minor) 117 if (minor == MINOR(disk_devt(entry->gd)))
118 found++; 118 found++;
119 if (!found) break; // got unused minor 119 if (!found) break; // got unused minor
120 } 120 }
@@ -397,7 +397,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
397 goto unload_seg; 397 goto unload_seg;
398 } 398 }
399 sprintf(dev_info->gd->disk_name, "dcssblk%d", 399 sprintf(dev_info->gd->disk_name, "dcssblk%d",
400 dev_info->gd->first_minor); 400 MINOR(disk_devt(dev_info->gd)));
401 list_add_tail(&dev_info->lh, &dcssblk_devices); 401 list_add_tail(&dev_info->lh, &dcssblk_devices);
402 402
403 if (!try_module_get(THIS_MODULE)) { 403 if (!try_module_get(THIS_MODULE)) {
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 27f5bfd1def3..8dbe3798d5fd 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -878,7 +878,7 @@ static void sr_kref_release(struct kref *kref)
878 struct gendisk *disk = cd->disk; 878 struct gendisk *disk = cd->disk;
879 879
880 spin_lock(&sr_index_lock); 880 spin_lock(&sr_index_lock);
881 clear_bit(disk->first_minor, sr_index_bits); 881 clear_bit(MINOR(disk_devt(disk)), sr_index_bits);
882 spin_unlock(&sr_index_lock); 882 spin_unlock(&sr_index_lock);
883 883
884 unregister_cdrom(&cd->cdi); 884 unregister_cdrom(&cd->cdi);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index de0776cd7215..72e0a2887cb7 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -892,7 +892,7 @@ int check_disk_change(struct block_device *bdev)
892 892
893 if (bdops->revalidate_disk) 893 if (bdops->revalidate_disk)
894 bdops->revalidate_disk(bdev->bd_disk); 894 bdops->revalidate_disk(bdev->bd_disk);
895 if (bdev->bd_disk->minors > 1) 895 if (disk_max_parts(bdev->bd_disk))
896 bdev->bd_invalidated = 1; 896 bdev->bd_invalidated = 1;
897 return 1; 897 return 1;
898} 898}
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index b86aab1b0df6..e77fa144a07d 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -134,7 +134,11 @@ char *disk_name(struct gendisk *hd, int partno, char *buf)
134 134
135const char *bdevname(struct block_device *bdev, char *buf) 135const char *bdevname(struct block_device *bdev, char *buf)
136{ 136{
137 int partno = MINOR(bdev->bd_dev) - bdev->bd_disk->first_minor; 137 int partno = 0;
138
139 if (bdev->bd_part)
140 partno = bdev->bd_part->partno;
141
138 return disk_name(bdev->bd_disk, partno, buf); 142 return disk_name(bdev->bd_disk, partno, buf);
139} 143}
140 144
@@ -169,7 +173,7 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
169 if (isdigit(state->name[strlen(state->name)-1])) 173 if (isdigit(state->name[strlen(state->name)-1]))
170 sprintf(state->name, "p"); 174 sprintf(state->name, "p");
171 175
172 state->limit = hd->minors; 176 state->limit = disk_max_parts(hd) + 1;
173 i = res = err = 0; 177 i = res = err = 0;
174 while (!res && check_part[i]) { 178 while (!res && check_part[i]) {
175 memset(&state->parts, 0, sizeof(state->parts)); 179 memset(&state->parts, 0, sizeof(state->parts));
@@ -416,7 +420,6 @@ void register_disk(struct gendisk *disk)
416 int err; 420 int err;
417 421
418 disk->dev.parent = disk->driverfs_dev; 422 disk->dev.parent = disk->driverfs_dev;
419 disk->dev.devt = MKDEV(disk->major, disk->first_minor);
420 423
421 strlcpy(disk->dev.bus_id, disk->disk_name, BUS_ID_SIZE); 424 strlcpy(disk->dev.bus_id, disk->disk_name, BUS_ID_SIZE);
422 /* ewww... some of these buggers have / in the name... */ 425 /* ewww... some of these buggers have / in the name... */
@@ -440,7 +443,7 @@ void register_disk(struct gendisk *disk)
440 disk_sysfs_add_subdirs(disk); 443 disk_sysfs_add_subdirs(disk);
441 444
442 /* No minors to use for partitions */ 445 /* No minors to use for partitions */
443 if (disk->minors == 1) 446 if (!disk_max_parts(disk))
444 goto exit; 447 goto exit;
445 448
446 /* No such device (e.g., media were just removed) */ 449 /* No such device (e.g., media were just removed) */
@@ -463,8 +466,8 @@ exit:
463 kobject_uevent(&disk->dev.kobj, KOBJ_ADD); 466 kobject_uevent(&disk->dev.kobj, KOBJ_ADD);
464 467
465 /* announce possible partitions */ 468 /* announce possible partitions */
466 for (i = 1; i < disk->minors; i++) { 469 for (i = 0; i < disk_max_parts(disk); i++) {
467 p = disk->part[i-1]; 470 p = disk->part[i];
468 if (!p || !p->nr_sects) 471 if (!p || !p->nr_sects)
469 continue; 472 continue;
470 kobject_uevent(&p->dev.kobj, KOBJ_ADD); 473 kobject_uevent(&p->dev.kobj, KOBJ_ADD);
@@ -482,7 +485,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
482 if (res) 485 if (res)
483 return res; 486 return res;
484 bdev->bd_invalidated = 0; 487 bdev->bd_invalidated = 0;
485 for (p = 1; p < disk->minors; p++) 488 for (p = 1; p <= disk_max_parts(disk); p++)
486 delete_partition(disk, p); 489 delete_partition(disk, p);
487 if (disk->fops->revalidate_disk) 490 if (disk->fops->revalidate_disk)
488 disk->fops->revalidate_disk(disk); 491 disk->fops->revalidate_disk(disk);
@@ -545,7 +548,7 @@ void del_gendisk(struct gendisk *disk)
545 int p; 548 int p;
546 549
547 /* invalidate stuff */ 550 /* invalidate stuff */
548 for (p = disk->minors - 1; p > 0; p--) { 551 for (p = disk_max_parts(disk); p > 0; p--) {
549 invalidate_partition(disk, p); 552 invalidate_partition(disk, p);
550 delete_partition(disk, p); 553 delete_partition(disk, p);
551 } 554 }
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index d1723c0a8600..0ff75329199c 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -111,10 +111,14 @@ struct hd_struct {
111#define GENHD_FL_FAIL 64 111#define GENHD_FL_FAIL 64
112 112
113struct gendisk { 113struct gendisk {
114 /* major, first_minor and minors are input parameters only,
115 * don't use directly. Use disk_devt() and disk_max_parts().
116 */
114 int major; /* major number of driver */ 117 int major; /* major number of driver */
115 int first_minor; 118 int first_minor;
116 int minors; /* maximum number of minors, =1 for 119 int minors; /* maximum number of minors, =1 for
117 * disks that can't be partitioned. */ 120 * disks that can't be partitioned. */
121
118 char disk_name[32]; /* name of major driver */ 122 char disk_name[32]; /* name of major driver */
119 struct hd_struct **part; /* [indexed by minor - 1] */ 123 struct hd_struct **part; /* [indexed by minor - 1] */
120 struct block_device_operations *fops; 124 struct block_device_operations *fops;
@@ -152,6 +156,21 @@ static inline struct gendisk *part_to_disk(struct hd_struct *part)
152 return NULL; 156 return NULL;
153} 157}
154 158
159static inline int disk_max_parts(struct gendisk *disk)
160{
161 return disk->minors - 1;
162}
163
164static inline dev_t disk_devt(struct gendisk *disk)
165{
166 return disk->dev.devt;
167}
168
169static inline dev_t part_devt(struct hd_struct *part)
170{
171 return part->dev.devt;
172}
173
155/* 174/*
156 * Macros to operate on percpu disk statistics: 175 * Macros to operate on percpu disk statistics:
157 * 176 *
@@ -163,7 +182,7 @@ static inline struct hd_struct *disk_map_sector(struct gendisk *gendiskp,
163{ 182{
164 struct hd_struct *part; 183 struct hd_struct *part;
165 int i; 184 int i;
166 for (i = 0; i < gendiskp->minors - 1; i++) { 185 for (i = 0; i < disk_max_parts(gendiskp); i++) {
167 part = gendiskp->part[i]; 186 part = gendiskp->part[i];
168 if (part && part->start_sect <= sector 187 if (part && part->start_sect <= sector
169 && sector < part->start_sect + part->nr_sects) 188 && sector < part->start_sect + part->nr_sects)
@@ -366,6 +385,7 @@ extern void add_disk(struct gendisk *disk);
366extern void del_gendisk(struct gendisk *gp); 385extern void del_gendisk(struct gendisk *gp);
367extern void unlink_gendisk(struct gendisk *gp); 386extern void unlink_gendisk(struct gendisk *gp);
368extern struct gendisk *get_gendisk(dev_t dev, int *partno); 387extern struct gendisk *get_gendisk(dev_t dev, int *partno);
388extern struct block_device *bdget_disk(struct gendisk *disk, int partno);
369 389
370extern void set_device_ro(struct block_device *bdev, int flag); 390extern void set_device_ro(struct block_device *bdev, int flag);
371extern void set_disk_ro(struct gendisk *disk, int flag); 391extern void set_disk_ro(struct gendisk *disk, int flag);
@@ -553,11 +573,6 @@ extern void blk_register_region(dev_t devt, unsigned long range,
553 void *data); 573 void *data);
554extern void blk_unregister_region(dev_t devt, unsigned long range); 574extern void blk_unregister_region(dev_t devt, unsigned long range);
555 575
556static inline struct block_device *bdget_disk(struct gendisk *disk, int partno)
557{
558 return bdget(MKDEV(disk->major, disk->first_minor) + partno);
559}
560
561#else /* CONFIG_BLOCK */ 576#else /* CONFIG_BLOCK */
562 577
563static inline void printk_all_partitions(void) { } 578static inline void printk_all_partitions(void) { }