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

Tomasz Maciej Nowak tomek_n at o2.pl
Fri Aug 14 07:04:43 EDT 2020


Hi John.
W dniu 05.08.2020 o 23:13, John Thomson pisze:
> 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>

Yay!
The description in this patch matches the symptoms I described Year ago in this bug report:
https://bugs.openwrt.org/index.php?do=details&task_id=2428
and this patch fixes it, Thank You very much.

Tested-by: Tomasz Maciej Nowak <tomek_n at o2.pl>
Fixes: FS#2428

> 
> --
> 
> 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 */
> 


-- 
TMN



More information about the openwrt-devel mailing list