Support erase regions with odd numbered blocks
RFC PATCH 2/2 Support erase regions with odd numbered blocks
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 <[email protected]>
--- mtdpart.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
drivers/mtd/mtdpart.c +24 -1
@@ -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;
---