aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/genhd.c40
-rw-r--r--block/ioctl.c4
2 files changed, 25 insertions, 19 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
748static ssize_t disk_removable_show(struct device *dev, 753static 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);
diff --git a/block/ioctl.c b/block/ioctl.c
index a5f672ad55f6..64e7c67a64b0 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -30,7 +30,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
30 if (bdev != bdev->bd_contains) 30 if (bdev != bdev->bd_contains)
31 return -EINVAL; 31 return -EINVAL;
32 partno = p.pno; 32 partno = p.pno;
33 if (partno <= 0 || partno > disk_max_parts(disk)) 33 if (partno <= 0 || partno >= disk_max_parts(disk))
34 return -EINVAL; 34 return -EINVAL;
35 switch (a.op) { 35 switch (a.op) {
36 case BLKPG_ADD_PARTITION: 36 case BLKPG_ADD_PARTITION:
@@ -102,7 +102,7 @@ static int blkdev_reread_part(struct block_device *bdev)
102 struct gendisk *disk = bdev->bd_disk; 102 struct gendisk *disk = bdev->bd_disk;
103 int res; 103 int res;
104 104
105 if (!disk_max_parts(disk) || bdev != bdev->bd_contains) 105 if (!disk_partitionable(disk) || bdev != bdev->bd_contains)
106 return -EINVAL; 106 return -EINVAL;
107 if (!capable(CAP_SYS_ADMIN)) 107 if (!capable(CAP_SYS_ADMIN))
108 return -EACCES; 108 return -EACCES;