From 867412c9d13ea54b836a70e92929f13a4ed541cf Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 27 Feb 2013 17:05:19 -0800 Subject: [PATCH] --- yaml --- r: 359395 b: refs/heads/master c: ac2e5327a5e4f6477afc6a3b3b0dc6e0476d71d4 h: refs/heads/master i: 359393: 264b59b6e816e3d7dd22083cf9de766bf697dbad 359391: 0bfa4a82a99f8a8ab04f017d87941120da4369c3 v: v3 --- [refs] | 2 +- trunk/block/partition-generic.c | 4 ++-- trunk/block/partitions/check.c | 37 ++++++++++++++++++++++++++++----- trunk/block/partitions/check.h | 4 +++- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index 5fd7c96e490f..6b57ae7e10e3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 06004e6eebdaf101a0f9b533fac77b5768d2c09c +refs/heads/master: ac2e5327a5e4f6477afc6a3b3b0dc6e0476d71d4 diff --git a/trunk/block/partition-generic.c b/trunk/block/partition-generic.c index 1cb4deca1324..789cdea05893 100644 --- a/trunk/block/partition-generic.c +++ b/trunk/block/partition-generic.c @@ -418,7 +418,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) int p, highest, res; rescan: if (state && !IS_ERR(state)) { - kfree(state); + free_partitions(state); state = NULL; } @@ -525,7 +525,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) md_autodetect_dev(part_to_dev(part)->devt); #endif } - kfree(state); + free_partitions(state); return 0; } diff --git a/trunk/block/partitions/check.c b/trunk/block/partitions/check.c index bc908672c976..19ba207ea7d1 100644 --- a/trunk/block/partitions/check.c +++ b/trunk/block/partitions/check.c @@ -14,6 +14,7 @@ */ #include +#include #include #include @@ -106,18 +107,45 @@ static int (*check_part[])(struct parsed_partitions *) = { NULL }; +static struct parsed_partitions *allocate_partitions(struct gendisk *hd) +{ + struct parsed_partitions *state; + int nr; + + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (!state) + return NULL; + + nr = disk_max_parts(hd); + state->parts = vzalloc(nr * sizeof(state->parts[0])); + if (!state->parts) { + kfree(state); + return NULL; + } + + state->limit = nr; + + return state; +} + +void free_partitions(struct parsed_partitions *state) +{ + vfree(state->parts); + kfree(state); +} + struct parsed_partitions * check_partition(struct gendisk *hd, struct block_device *bdev) { struct parsed_partitions *state; int i, res, err; - state = kzalloc(sizeof(struct parsed_partitions), GFP_KERNEL); + state = allocate_partitions(hd); if (!state) return NULL; state->pp_buf = (char *)__get_free_page(GFP_KERNEL); if (!state->pp_buf) { - kfree(state); + free_partitions(state); return NULL; } state->pp_buf[0] = '\0'; @@ -128,10 +156,9 @@ check_partition(struct gendisk *hd, struct block_device *bdev) if (isdigit(state->name[strlen(state->name)-1])) sprintf(state->name, "p"); - state->limit = disk_max_parts(hd); i = res = err = 0; while (!res && check_part[i]) { - memset(&state->parts, 0, sizeof(state->parts)); + memset(state->parts, 0, state->limit * sizeof(state->parts[0])); res = check_part[i++](state); if (res < 0) { /* 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) printk(KERN_INFO "%s", state->pp_buf); free_page((unsigned long)state->pp_buf); - kfree(state); + free_partitions(state); return ERR_PTR(res); } diff --git a/trunk/block/partitions/check.h b/trunk/block/partitions/check.h index 52b100311ec3..eade17ea910b 100644 --- a/trunk/block/partitions/check.h +++ b/trunk/block/partitions/check.h @@ -15,13 +15,15 @@ struct parsed_partitions { int flags; bool has_info; struct partition_meta_info info; - } parts[DISK_MAX_PARTS]; + } *parts; int next; int limit; bool access_beyond_eod; char *pp_buf; }; +void free_partitions(struct parsed_partitions *state); + struct parsed_partitions * check_partition(struct gendisk *, struct block_device *);