[PATCH] mtd: cmdlinepart: allow fill-up partition at any point

From: Ben Shelton
Date: Thu May 07 2015 - 22:58:26 EST


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.shelton@xxxxxx>
---
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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/