Commit 1fca1f6a authored by Linus Walleij's avatar Linus Walleij Committed by Richard Weinberger

mtd: afs: simplify partition parsing

This simplifies the AFS partition parsing to make the code
more straight-forward and readable.

Before this patch the code tried to calculate the memory required
to hold the partition info by adding up the sizes of the strings
of the names and adding that to a single memory allocation,
indexing the name pointers in front of the struct mtd_partition
allocations so all allocated data was in one chunk.

This is overzealous. Instead use kstrdup and bail out,
kfree():ing the memory used for MTD partitions and names alike
on the errorpath.

In the process rename the index variable from idx to i.

Cc: Ryan Harkin <ryan.harkin@linaro.org>
Acked-by: default avatarLiviu Dudau <liviu.dudau@arm.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent 22749bf5
...@@ -166,9 +166,9 @@ static int parse_afs_partitions(struct mtd_info *mtd, ...@@ -166,9 +166,9 @@ static int parse_afs_partitions(struct mtd_info *mtd,
struct mtd_part_parser_data *data) struct mtd_part_parser_data *data)
{ {
struct mtd_partition *parts; struct mtd_partition *parts;
u_int mask, off, idx, sz; u_int mask, off, sz;
int ret = 0; int ret = 0;
char *str; int i;
/* /*
* This is the address mask; we use this to mask off out of * This is the address mask; we use this to mask off out of
...@@ -181,78 +181,75 @@ static int parse_afs_partitions(struct mtd_info *mtd, ...@@ -181,78 +181,75 @@ static int parse_afs_partitions(struct mtd_info *mtd,
* partition information. We include in this the size of * partition information. We include in this the size of
* the strings. * the strings.
*/ */
for (idx = off = sz = 0; off < mtd->size; off += mtd->erasesize) { for (i = off = sz = 0; off < mtd->size; off += mtd->erasesize) {
struct image_info_v1 iis;
u_int iis_ptr, img_ptr; u_int iis_ptr, img_ptr;
ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask); ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
if (ret < 0) if (ret < 0)
break; return ret;
if (ret) { if (ret) {
ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
if (ret < 0)
break;
if (ret == 0)
continue;
sz += sizeof(struct mtd_partition); sz += sizeof(struct mtd_partition);
sz += strlen(iis.name) + 1; i += 1;
idx += 1;
} }
} }
if (!sz) if (!i)
return ret; return 0;
parts = kzalloc(sz, GFP_KERNEL); parts = kzalloc(sz, GFP_KERNEL);
if (!parts) if (!parts)
return -ENOMEM; return -ENOMEM;
str = (char *)(parts + idx);
/* /*
* Identify the partitions * Identify the partitions
*/ */
for (idx = off = 0; off < mtd->size; off += mtd->erasesize) { for (i = off = 0; off < mtd->size; off += mtd->erasesize) {
struct image_info_v1 iis; struct image_info_v1 iis;
u_int iis_ptr, img_ptr; u_int iis_ptr, img_ptr;
/* Read the footer. */ /* Read the footer. */
ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask); ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask);
if (ret < 0) if (ret < 0)
break; goto out_free_parts;
if (ret == 0) if (ret == 0)
continue; continue;
/* Read the image info block */ /* Read the image info block */
ret = afs_read_iis_v1(mtd, &iis, iis_ptr); ret = afs_read_iis_v1(mtd, &iis, iis_ptr);
if (ret < 0) if (ret < 0)
break; goto out_free_parts;
if (ret == 0) if (ret == 0)
continue; continue;
strcpy(str, iis.name); parts[i].name = kstrdup(iis.name, GFP_KERNEL);
if (!parts[i].name) {
ret = -ENOMEM;
goto out_free_parts;
}
parts[idx].name = str; parts[i].size = (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1);
parts[idx].size = (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1); parts[i].offset = img_ptr;
parts[idx].offset = img_ptr; parts[i].mask_flags = 0;
parts[idx].mask_flags = 0;
printk(" mtd%d: at 0x%08x, %5lluKiB, %8u, %s\n", printk(" mtd%d: at 0x%08x, %5lluKiB, %8u, %s\n",
idx, img_ptr, parts[idx].size / 1024, i, img_ptr, parts[i].size / 1024,
iis.imageNumber, str); iis.imageNumber, parts[i].name);
idx += 1;
str = str + strlen(iis.name) + 1;
}
if (!idx) { i += 1;
kfree(parts);
parts = NULL;
} }
*pparts = parts; *pparts = parts;
return idx ? idx : ret; return i;
out_free_parts:
while (i >= 0) {
if (parts[i].name)
kfree(parts[i].name);
i--;
}
kfree(parts);
*pparts = NULL;
return ret;
} }
static const struct of_device_id mtd_parser_afs_of_match_table[] = { static const struct of_device_id mtd_parser_afs_of_match_table[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment