[PATCH 2/6] jffs2: write verify: replace memcmp with byte-by-byte comparison
zhouminqiang
zhouminqiang2 at huawei.com
Thu Aug 20 03:49:58 PDT 2026
jffs2_verify_write() uses memcmp() to compare the write buffer
against data read back from flash. While memcmp() compares byte
by byte internally, it only reports equal or not-equal without
identifying the mismatch offset.
To pinpoint the exact mismatch offset, replace this with the
approach used by UBI's self_check_write(): compare byte by byte
and, on mismatch, report the first differing offset and dump up
to 128 bytes of both the source and read-back data.
Signed-off-by: zhouminqiang <zhouminqiang2 at huawei.com>
---
fs/jffs2/wbuf.c | 53 +++++++++++++++++++++++++++++--------------------
1 file changed, 31 insertions(+), 22 deletions(-)
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 7e4608b43a4e..da6da813a4ef 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -231,8 +231,8 @@ static struct jffs2_raw_node_ref **jffs2_incore_replace_raw(struct jffs2_sb_info
static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf,
uint32_t ofs)
{
- int ret;
- size_t retlen;
+ int ret = 0;
+ size_t retlen, i;
char *eccstr;
void *verify_buf;
@@ -246,37 +246,46 @@ static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf,
ret = mtd_read(c->mtd, ofs, c->wbuf_pagesize, &retlen, verify_buf);
if (ret && ret != -EUCLEAN && ret != -EBADMSG) {
pr_warn("%s(): Read back of page at %08x failed: %d\n",
- __func__, c->wbuf_ofs, ret);
+ __func__, ofs, ret);
goto out_free;
} else if (retlen != c->wbuf_pagesize) {
- pr_warn("%s(): Read back of page at %08x gave short read: %zd not %d\n",
+ pr_warn("%s(): Read back of page at %08x gave short read: %zu not %d\n",
__func__, ofs, retlen, c->wbuf_pagesize);
ret = -EIO;
goto out_free;
}
- if (!memcmp(buf, verify_buf, c->wbuf_pagesize)) {
- ret = 0;
- goto out_free;
- }
- if (ret == -EUCLEAN)
- eccstr = "corrected";
- else if (ret == -EBADMSG)
- eccstr = "correction failed";
- else
- eccstr = "OK or unused";
+ for (i = 0; i < c->wbuf_pagesize; i++) {
+ uint8_t c1 = ((uint8_t *)buf)[i];
+ uint8_t c2 = ((uint8_t *)verify_buf)[i];
+ int dump_len;
- pr_warn("Write verify error (ECC %s) at %08x. Wrote:\n",
- eccstr, c->wbuf_ofs);
- print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1,
- c->wbuf, c->wbuf_pagesize, 0);
+ if (c1 == c2)
+ continue;
- pr_warn("Read back:\n");
- print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1,
- verify_buf, c->wbuf_pagesize, 0);
+ if (ret == -EUCLEAN)
+ eccstr = "corrected";
+ else if (ret == -EBADMSG)
+ eccstr = "correction failed";
+ else
+ eccstr = "OK or unused";
+
+ dump_len = min_t(int, 128, c->wbuf_pagesize - i);
+ pr_warn("Write verify error (ECC %s) at %08x (+%zu/%d). Wrote:\n",
+ eccstr, ofs, i, c->wbuf_pagesize);
+ print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1,
+ buf + i, dump_len, 0);
+
+ pr_warn("Read back:\n");
+ print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1,
+ verify_buf + i, dump_len, 0);
+
+ ret = -EIO;
+ goto out_free;
+ }
vfree(verify_buf);
- return -EIO;
+ return 0;
out_free:
vfree(verify_buf);
--
2.52.0
More information about the linux-mtd
mailing list