Currently, a fill-up partition (indicated by '-') must be the last partition, and no other partitions can go after it. Change the cmdlinepart parsing code to allow a fill-up partition at any point. This is useful, for example, if you want to reserve a partition at the end of the flash where the bad block table will go.
Signed-off-by: Ben Shelton <ben.shel...@ni.com> --- drivers/mtd/cmdlinepart.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index c850300..2d0eda2 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c @@ -97,6 +97,7 @@ static struct mtd_partition * newpart(char *s, char **retptr, int *num_parts, int this_part, + int size_remaining_found, unsigned char **extra_mem_ptr, int extra_mem_size) { @@ -110,9 +111,16 @@ static struct mtd_partition * newpart(char *s, /* fetch the partition size */ if (*s == '-') { + if (size_remaining_found) { + printk(KERN_ERR ERRP + "more than one '-' partition specified\n"); + return ERR_PTR(-EINVAL); + } + /* assign all remaining space to this partition */ size = SIZE_REMAINING; s++; + size_remaining_found = 1; } else { size = memparse(s, &s); if (size < PAGE_SIZE) { @@ -169,13 +177,10 @@ static struct mtd_partition * newpart(char *s, /* test if more partitions are following */ if (*s == ',') { - if (size == SIZE_REMAINING) { - printk(KERN_ERR ERRP "no partitions allowed after a fill-up partition\n"); - return ERR_PTR(-EINVAL); - } /* more partitions follow, parse them */ parts = newpart(s + 1, &s, num_parts, this_part + 1, - &extra_mem, extra_mem_size); + size_remaining_found, &extra_mem, + extra_mem_size); if (IS_ERR(parts)) return parts; } else { @@ -252,6 +257,7 @@ static int mtdpart_setup_real(char *s) &s, /* out: updated cmdline ptr */ &num_parts, /* out: number of parts */ 0, /* first partition */ + 0, /* size_remaining not found */ (unsigned char**)&this_mtd, /* out: extra mem */ mtd_id_len + 1 + sizeof(*this_mtd) + sizeof(void*)-1 /*alignment*/); @@ -313,6 +319,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, int i, err; struct cmdline_mtd_partition *part; const char *mtd_id = master->name; + int sr_part_num = -1; /* parse command line */ if (!cmdline_parsed) { @@ -339,8 +346,10 @@ static int parse_cmdline_partitions(struct mtd_info *master, else offset = part->parts[i].offset; - if (part->parts[i].size == SIZE_REMAINING) - part->parts[i].size = master->size - offset; + if (part->parts[i].size == SIZE_REMAINING) { + sr_part_num = i; + continue; + } if (offset + part->parts[i].size > master->size) { printk(KERN_WARNING ERRP @@ -361,6 +370,16 @@ static int parse_cmdline_partitions(struct mtd_info *master, } } + /* if a partition was marked as SIZE_REMAINING */ + if (sr_part_num != -1) { + /* fix up the size of the SIZE_REMAINING partition */ + part->parts[sr_part_num].size = master->size - offset; + + /* fix up the offsets of the subsequent partitions */ + for (i = (sr_part_num + 1); i < part->num_parts; i++) + part->parts[i].offset += part->parts[sr_part_num].size; + } + *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts, GFP_KERNEL); if (!*pparts) -- 2.4.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/