[PATCH] kernel: fix mtd partition erase<parent_erasesize writing to wrong address

John Thomson git at johnthomson.fastmail.com.au
Wed Aug 5 17:13:54 EDT 2020


This bug applied where mtd partition end address,
or erase start address, was not cleanly divisible by parent mtd erasesize.

This error would cause the bits following the end of the partition
to the next erasesize block boundary to be erased,
and this partition-overflow data to be written to the partition erase
address (missing additional partition offset address)
of the mtd (top) parent device.

Signed-off-by: John Thomson <git at johnthomson.fastmail.com.au>

--

4.19 also requires this fix

A little discussion here:
https://github.com/openwrt/openwrt/pull/3103#issuecomment-667610510

mtdpart.c should be made to work with 4K erase sectors, where available
Considering this here:
https://github.com/openwrt/openwrt/pull/3271
---
 .../411-mtd-partial_eraseblock_write.patch          | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch b/target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch
index b46c3f5ed4..c48a144d3d 100644
--- a/target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch
+++ b/target/linux/generic/pending-5.4/411-mtd-partial_eraseblock_write.patch
@@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
  /* Our partition linked list */
  static LIST_HEAD(mtd_partitions);
  static DEFINE_MUTEX(mtd_partitions_mutex);
-@@ -206,6 +208,53 @@ static int part_erase(struct mtd_info *m
+@@ -206,11 +208,77 @@ static int part_erase(struct mtd_info *m
  {
  	struct mtd_part *part = mtd_to_part(mtd);
  	int ret;
@@ -73,10 +73,9 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
  
  	instr->addr += part->offset;
  	ret = part->parent->_erase(part->parent, instr);
-@@ -213,6 +262,24 @@ static int part_erase(struct mtd_info *m
+ 	if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
  		instr->fail_addr -= part->offset;
- 	instr->addr -= part->offset;
- 
++
 +	if (mtd->flags & MTD_ERASE_PARTIAL) {
 +		if (partial_start) {
 +			part->parent->_write(part->parent,
@@ -95,10 +94,10 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
 +		kfree(erase_buf);
 +	}
 +
- 	return ret;
- }
+ 	instr->addr -= part->offset;
  
-@@ -525,19 +592,22 @@ static struct mtd_part *allocate_partiti
+ 	return ret;
+@@ -525,19 +593,22 @@ static struct mtd_part *allocate_partiti
  	remainder = do_div(tmp, wr_alignment);
  	if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
  		/* Doesn't start on a boundary of major erase size */
-- 
2.28.0




More information about the openwrt-devel mailing list