aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/partition-generic.c4
-rw-r--r--block/partitions/check.c37
-rw-r--r--block/partitions/check.h4
3 files changed, 37 insertions, 8 deletions
diff --git a/block/partition-generic.c b/block/partition-generic.c
index 1cb4deca1324..789cdea05893 100644
--- a/block/partition-generic.c
+++ b/block/partition-generic.c
@@ -418,7 +418,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
418 int p, highest, res; 418 int p, highest, res;
419rescan: 419rescan:
420 if (state && !IS_ERR(state)) { 420 if (state && !IS_ERR(state)) {
421 kfree(state); 421 free_partitions(state);
422 state = NULL; 422 state = NULL;
423 } 423 }
424 424
@@ -525,7 +525,7 @@ rescan:
525 md_autodetect_dev(part_to_dev(part)->devt); 525 md_autodetect_dev(part_to_dev(part)->devt);
526#endif 526#endif
527 } 527 }
528 kfree(state); 528 free_partitions(state);
529 return 0; 529 return 0;
530} 530}
531 531
diff --git a/block/partitions/check.c b/block/partitions/check.c
index bc908672c976..19ba207ea7d1 100644
--- a/block/partitions/check.c
+++ b/block/partitions/check.c
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/vmalloc.h>
17#include <linux/ctype.h> 18#include <linux/ctype.h>
18#include <linux/genhd.h> 19#include <linux/genhd.h>
19 20
@@ -106,18 +107,45 @@ static int (*check_part[])(struct parsed_partitions *) = {
106 NULL 107 NULL
107}; 108};
108 109
110static struct parsed_partitions *allocate_partitions(struct gendisk *hd)
111{
112 struct parsed_partitions *state;
113 int nr;
114
115 state = kzalloc(sizeof(*state), GFP_KERNEL);
116 if (!state)
117 return NULL;
118
119 nr = disk_max_parts(hd);
120 state->parts = vzalloc(nr * sizeof(state->parts[0]));
121 if (!state->parts) {
122 kfree(state);
123 return NULL;
124 }
125
126 state->limit = nr;
127
128 return state;
129}
130
131void free_partitions(struct parsed_partitions *state)
132{
133 vfree(state->parts);
134 kfree(state);
135}
136
109struct parsed_partitions * 137struct parsed_partitions *
110check_partition(struct gendisk *hd, struct block_device *bdev) 138check_partition(struct gendisk *hd, struct block_device *bdev)
111{ 139{
112 struct parsed_partitions *state; 140 struct parsed_partitions *state;
113 int i, res, err; 141 int i, res, err;
114 142
115 state = kzalloc(sizeof(struct parsed_partitions), GFP_KERNEL); 143 state = allocate_partitions(hd);
116 if (!state) 144 if (!state)
117 return NULL; 145 return NULL;
118 state->pp_buf = (char *)__get_free_page(GFP_KERNEL); 146 state->pp_buf = (char *)__get_free_page(GFP_KERNEL);
119 if (!state->pp_buf) { 147 if (!state->pp_buf) {
120 kfree(state); 148 free_partitions(state);
121 return NULL; 149 return NULL;
122 } 150 }
123 state->pp_buf[0] = '\0'; 151 state->pp_buf[0] = '\0';
@@ -128,10 +156,9 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
128 if (isdigit(state->name[strlen(state->name)-1])) 156 if (isdigit(state->name[strlen(state->name)-1]))
129 sprintf(state->name, "p"); 157 sprintf(state->name, "p");
130 158
131 state->limit = disk_max_parts(hd);
132 i = res = err = 0; 159 i = res = err = 0;
133 while (!res && check_part[i]) { 160 while (!res && check_part[i]) {
134 memset(&state->parts, 0, sizeof(state->parts)); 161 memset(state->parts, 0, state->limit * sizeof(state->parts[0]));
135 res = check_part[i++](state); 162 res = check_part[i++](state);
136 if (res < 0) { 163 if (res < 0) {
137 /* We have hit an I/O error which we don't report now. 164 /* We have hit an I/O error which we don't report now.
@@ -161,6 +188,6 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
161 printk(KERN_INFO "%s", state->pp_buf); 188 printk(KERN_INFO "%s", state->pp_buf);
162 189
163 free_page((unsigned long)state->pp_buf); 190 free_page((unsigned long)state->pp_buf);
164 kfree(state); 191 free_partitions(state);
165 return ERR_PTR(res); 192 return ERR_PTR(res);
166} 193}
diff --git a/block/partitions/check.h b/block/partitions/check.h
index 52b100311ec3..eade17ea910b 100644
--- a/block/partitions/check.h
+++ b/block/partitions/check.h
@@ -15,13 +15,15 @@ struct parsed_partitions {
15 int flags; 15 int flags;
16 bool has_info; 16 bool has_info;
17 struct partition_meta_info info; 17 struct partition_meta_info info;
18 } parts[DISK_MAX_PARTS]; 18 } *parts;
19 int next; 19 int next;
20 int limit; 20 int limit;
21 bool access_beyond_eod; 21 bool access_beyond_eod;
22 char *pp_buf; 22 char *pp_buf;
23}; 23};
24 24
25void free_partitions(struct parsed_partitions *state);
26
25struct parsed_partitions * 27struct parsed_partitions *
26check_partition(struct gendisk *, struct block_device *); 28check_partition(struct gendisk *, struct block_device *);
27 29