diff options
Diffstat (limited to 'block/genhd.c')
-rw-r--r-- | block/genhd.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/block/genhd.c b/block/genhd.c index 0a2f16bd54b7..65b7386c26d8 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -54,10 +54,10 @@ struct hd_struct *disk_get_part(struct gendisk *disk, int partno) | |||
54 | { | 54 | { |
55 | struct hd_struct *part; | 55 | struct hd_struct *part; |
56 | 56 | ||
57 | if (unlikely(partno < 1 || partno > disk_max_parts(disk))) | 57 | if (unlikely(partno < 0 || partno >= disk_max_parts(disk))) |
58 | return NULL; | 58 | return NULL; |
59 | rcu_read_lock(); | 59 | rcu_read_lock(); |
60 | part = rcu_dereference(disk->__part[partno - 1]); | 60 | part = rcu_dereference(disk->__part[partno]); |
61 | if (part) | 61 | if (part) |
62 | get_device(part_to_dev(part)); | 62 | get_device(part_to_dev(part)); |
63 | rcu_read_unlock(); | 63 | rcu_read_unlock(); |
@@ -85,8 +85,10 @@ void disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk, | |||
85 | 85 | ||
86 | if (flags & DISK_PITER_REVERSE) | 86 | if (flags & DISK_PITER_REVERSE) |
87 | piter->idx = disk_max_parts(piter->disk) - 1; | 87 | piter->idx = disk_max_parts(piter->disk) - 1; |
88 | else | 88 | else if (flags & DISK_PITER_INCL_PART0) |
89 | piter->idx = 0; | 89 | piter->idx = 0; |
90 | else | ||
91 | piter->idx = 1; | ||
90 | 92 | ||
91 | piter->flags = flags; | 93 | piter->flags = flags; |
92 | } | 94 | } |
@@ -114,7 +116,10 @@ struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter) | |||
114 | /* determine iteration parameters */ | 116 | /* determine iteration parameters */ |
115 | if (piter->flags & DISK_PITER_REVERSE) { | 117 | if (piter->flags & DISK_PITER_REVERSE) { |
116 | inc = -1; | 118 | inc = -1; |
117 | end = -1; | 119 | if (piter->flags & DISK_PITER_INCL_PART0) |
120 | end = -1; | ||
121 | else | ||
122 | end = 0; | ||
118 | } else { | 123 | } else { |
119 | inc = 1; | 124 | inc = 1; |
120 | end = disk_max_parts(piter->disk); | 125 | end = disk_max_parts(piter->disk); |
@@ -177,7 +182,7 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector) | |||
177 | { | 182 | { |
178 | int i; | 183 | int i; |
179 | 184 | ||
180 | for (i = 0; i < disk_max_parts(disk); i++) { | 185 | for (i = 1; i < disk_max_parts(disk); i++) { |
181 | struct hd_struct *part = rcu_dereference(disk->__part[i]); | 186 | struct hd_struct *part = rcu_dereference(disk->__part[i]); |
182 | 187 | ||
183 | if (part && part->start_sect <= sector && | 188 | if (part && part->start_sect <= sector && |
@@ -669,7 +674,7 @@ static int show_partition(struct seq_file *seqf, void *v) | |||
669 | char buf[BDEVNAME_SIZE]; | 674 | char buf[BDEVNAME_SIZE]; |
670 | 675 | ||
671 | /* Don't show non-partitionable removeable devices or empty devices */ | 676 | /* Don't show non-partitionable removeable devices or empty devices */ |
672 | if (!get_capacity(sgp) || (!disk_max_parts(sgp) && | 677 | if (!get_capacity(sgp) || (!disk_partitionable(sgp) && |
673 | (sgp->flags & GENHD_FL_REMOVABLE))) | 678 | (sgp->flags & GENHD_FL_REMOVABLE))) |
674 | return 0; | 679 | return 0; |
675 | if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO) | 680 | if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO) |
@@ -742,7 +747,7 @@ static ssize_t disk_ext_range_show(struct device *dev, | |||
742 | { | 747 | { |
743 | struct gendisk *disk = dev_to_disk(dev); | 748 | struct gendisk *disk = dev_to_disk(dev); |
744 | 749 | ||
745 | return sprintf(buf, "%d\n", disk_max_parts(disk) + 1); | 750 | return sprintf(buf, "%d\n", disk_max_parts(disk)); |
746 | } | 751 | } |
747 | 752 | ||
748 | static ssize_t disk_removable_show(struct device *dev, | 753 | static ssize_t disk_removable_show(struct device *dev, |
@@ -998,7 +1003,7 @@ dev_t blk_lookup_devt(const char *name, int partno) | |||
998 | 1003 | ||
999 | if (strcmp(dev->bus_id, name)) | 1004 | if (strcmp(dev->bus_id, name)) |
1000 | continue; | 1005 | continue; |
1001 | if (partno < 0 || partno > disk_max_parts(disk)) | 1006 | if (partno < 0 || partno >= disk_max_parts(disk)) |
1002 | continue; | 1007 | continue; |
1003 | 1008 | ||
1004 | if (partno == 0) | 1009 | if (partno == 0) |
@@ -1045,21 +1050,22 @@ struct gendisk *alloc_disk_ext_node(int minors, int ext_minors, int node_id) | |||
1045 | GFP_KERNEL | __GFP_ZERO, node_id); | 1050 | GFP_KERNEL | __GFP_ZERO, node_id); |
1046 | if (disk) { | 1051 | if (disk) { |
1047 | int tot_minors = minors + ext_minors; | 1052 | int tot_minors = minors + ext_minors; |
1053 | int size = tot_minors * sizeof(struct hd_struct *); | ||
1048 | 1054 | ||
1049 | if (!init_disk_stats(disk)) { | 1055 | if (!init_disk_stats(disk)) { |
1050 | kfree(disk); | 1056 | kfree(disk); |
1051 | return NULL; | 1057 | return NULL; |
1052 | } | 1058 | } |
1053 | if (tot_minors > 1) { | 1059 | |
1054 | int size = (tot_minors - 1) * sizeof(struct hd_struct *); | 1060 | disk->__part = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, |
1055 | disk->__part = kmalloc_node(size, | 1061 | node_id); |
1056 | GFP_KERNEL | __GFP_ZERO, node_id); | 1062 | if (!disk->__part) { |
1057 | if (!disk->__part) { | 1063 | free_disk_stats(disk); |
1058 | free_disk_stats(disk); | 1064 | kfree(disk); |
1059 | kfree(disk); | 1065 | return NULL; |
1060 | return NULL; | ||
1061 | } | ||
1062 | } | 1066 | } |
1067 | disk->__part[0] = &disk->part0; | ||
1068 | |||
1063 | disk->minors = minors; | 1069 | disk->minors = minors; |
1064 | disk->ext_minors = ext_minors; | 1070 | disk->ext_minors = ext_minors; |
1065 | rand_initialize_disk(disk); | 1071 | rand_initialize_disk(disk); |