diff options
author | Tejun Heo <tj@kernel.org> | 2008-09-03 03:01:48 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-10-09 02:56:05 -0400 |
commit | f331c0296f2a9fee0d396a70598b954062603015 (patch) | |
tree | f74c467d58940131d97d90c4ea549843185e6ef0 | |
parent | cf771cb5a7b716f3f9e532fd42a1e3a0a75adec5 (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.c | 107 | ||||
-rw-r--r-- | block/ioctl.c | 6 | ||||
-rw-r--r-- | drivers/block/pktcdvd.c | 2 | ||||
-rw-r--r-- | drivers/block/ps3disk.c | 2 | ||||
-rw-r--r-- | drivers/char/random.c | 6 | ||||
-rw-r--r-- | drivers/md/dm-ioctl.c | 4 | ||||
-rw-r--r-- | drivers/md/dm-stripe.c | 4 | ||||
-rw-r--r-- | drivers/md/dm.c | 7 | ||||
-rw-r--r-- | drivers/memstick/core/mspro_block.c | 2 | ||||
-rw-r--r-- | drivers/mmc/card/block.c | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_proc.c | 3 | ||||
-rw-r--r-- | drivers/s390/block/dcssblk.c | 4 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 2 | ||||
-rw-r--r-- | fs/block_dev.c | 2 | ||||
-rw-r--r-- | fs/partitions/check.c | 19 | ||||
-rw-r--r-- | include/linux/genhd.h | 27 |
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 | */ | ||
241 | extern 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 | } | ||
258 | EXPORT_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 | ||
1147 | static void free_dev(struct mapped_device *md) | 1147 | static 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) | |||
197 | static int mspro_block_disk_release(struct gendisk *disk) | 197 | static 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 | ||
135 | const char *bdevname(struct block_device *bdev, char *buf) | 135 | const 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 | ||
113 | struct gendisk { | 113 | struct 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 | ||
159 | static inline int disk_max_parts(struct gendisk *disk) | ||
160 | { | ||
161 | return disk->minors - 1; | ||
162 | } | ||
163 | |||
164 | static inline dev_t disk_devt(struct gendisk *disk) | ||
165 | { | ||
166 | return disk->dev.devt; | ||
167 | } | ||
168 | |||
169 | static 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); | |||
366 | extern void del_gendisk(struct gendisk *gp); | 385 | extern void del_gendisk(struct gendisk *gp); |
367 | extern void unlink_gendisk(struct gendisk *gp); | 386 | extern void unlink_gendisk(struct gendisk *gp); |
368 | extern struct gendisk *get_gendisk(dev_t dev, int *partno); | 387 | extern struct gendisk *get_gendisk(dev_t dev, int *partno); |
388 | extern struct block_device *bdget_disk(struct gendisk *disk, int partno); | ||
369 | 389 | ||
370 | extern void set_device_ro(struct block_device *bdev, int flag); | 390 | extern void set_device_ro(struct block_device *bdev, int flag); |
371 | extern void set_disk_ro(struct gendisk *disk, int flag); | 391 | extern 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); |
554 | extern void blk_unregister_region(dev_t devt, unsigned long range); | 574 | extern void blk_unregister_region(dev_t devt, unsigned long range); |
555 | 575 | ||
556 | static 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 | ||
563 | static inline void printk_all_partitions(void) { } | 578 | static inline void printk_all_partitions(void) { } |