@@ -425,7 +425,7 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
}
if (master->numeraseregions > 1) {
/* Deal with variable erase size stuff */
- int i, max = master->numeraseregions;
+ int i, rgn, max = master->numeraseregions;
u32 end = slave->offset + slave->mtd.size;
struct mtd_erase_region_info *regions = master->eraseregions;
@@ -437,12 +437,35 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
i--;
/* Pick biggest erasesize */
+ rgn = i;
for (; i < max && regions[i].offset < end; i++) {
if (slave->mtd.erasesize < regions[i].erasesize) {
slave->mtd.erasesize = regions[i].erasesize;
}
}
BUG_ON(slave->mtd.erasesize == 0);
+
+ if (slave->mtd.flags & MTD_WRITEABLE) {
+ /* If partition spans many erase regions,
+ * the partition portion present in each region
+ * should be multiple of biggest erase size
+ */
+ unsigned portion_start, portion_end, region_end;
+
+ for (i = rgn; i < max && regions[i].offset < end; i++) {
+ portion_start = max(regions[i].offset, slave->offset);
+ region_end = regions[i].offset +
+ regions[i].erasesize * regions[i].numblocks;
+ portion_end = min(end, region_end);
+
+ if ((portion_end - portion_start) % slave->mtd.erasesize) {
+ slave->mtd.flags &= ~MTD_WRITEABLE;
+ printk(KERN_WARNING"mtd: partition \"%s\" is not erase block"
+ " aligned within erase region -- force read-only\n", part->name);
+ break;
+ }
+ }
+ }
} else {
/* Single erase size */
slave->mtd.erasesize = master->erasesize;
An erroneous partition spanning across erase regions with odd number of blocks may go undetected. Examples are: 1. Region 0 has 1 block of 128KB, region 1 has blocks of 256KB. A partition with offset 0 and length 256KB (gets erase size 256KB) is invalid but passes all checks. 2. Region 0 has 1 block of 128KB, region 1 has 1 block of 256KB and region 2 has 128KB blocks. A partition with offset 0 and length 512KB (gets biggest erasesize ie 256KB) is invalid. Such a partition passes all checks. The patch checks if the portion of a partition present in each region is multiple of erase size of partition. Signed-off-by: Rohit Hagargundgi <h.rohit@samsung.com> --- mtdpart.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) ---