From: Zhou Minqiang <zhouminqiang2@huawei.com>
To: linux@armlinux.org.uk, vz@mleia.com,
piotr.wojtaszczyk@timesys.com, maddy@linux.ibm.com,
dwmw2@infradead.org, richard@nod.at
Cc: linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
linux-mtd@lists.infradead.org, chengzhihao1@huawei.com,
yangerkun@huawei.com, yi.zhang@huawei.com,
zhouminqiang <zhouminqiang2@huawei.com>
Subject: [PATCH v4 3/8] jffs2: replace per-superblock verify buffer with per-write buffer
Date: Sun, 6 Sep 2026 11:03:39 +0800 [thread overview]
Message-ID: <20260906030344.2448622-4-zhouminqiang2@huawei.com> (raw)
In-Reply-To: <20260906030344.2448622-1-zhouminqiang2@huawei.com>
From: zhouminqiang <zhouminqiang2@huawei.com>
Subsequent patches will extend write verification to additional write
paths that may execute concurrently. A shared per-superblock buffer
would require a coarse lock to serialize all verification, hurting
concurrency.
To avoid this contention, remove the wbuf_verify field from
jffs2_sb_info, along with the scattered kmalloc/kfree of wbuf_verify
in jffs2_nand_flash_setup, jffs2_dataflash_setup,
jffs2_nor_wbuf_flash_setup and their corresponding cleanup functions.
Instead, allocate a temporary buffer inside jffs2_verify_write(),
giving each invocation its own buffer and eliminating the shared state.
Signed-off-by: zhouminqiang <zhouminqiang2@huawei.com>
---
fs/jffs2/jffs2_fs_sb.h | 3 ---
fs/jffs2/wbuf.c | 61 ++++++++++++++++--------------------------
2 files changed, 23 insertions(+), 41 deletions(-)
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
index 5a7091746f68..8a75870d3fc8 100644
--- a/fs/jffs2/jffs2_fs_sb.h
+++ b/fs/jffs2/jffs2_fs_sb.h
@@ -124,9 +124,6 @@ struct jffs2_sb_info {
uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */
-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
- unsigned char *wbuf_verify; /* read-back buffer for verification */
-#endif
#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
unsigned char *wbuf; /* Write-behind buffer for NAND flash */
uint32_t wbuf_ofs;
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index ab247117ec77..7e52241de457 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -233,19 +233,31 @@ static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf,
int ret;
size_t retlen;
char *eccstr;
+ void *verify_buf;
+
+ verify_buf = kmalloc(c->wbuf_pagesize, GFP_NOFS);
+ if (!verify_buf) {
+ pr_warn("%s(): verify buffer allocation failed, skipping verification\n",
+ __func__);
+ return 0;
+ }
+
+ ret = mtd_read(c->mtd, ofs, c->wbuf_pagesize, &retlen, verify_buf);
- ret = mtd_read(c->mtd, ofs, c->wbuf_pagesize, &retlen, c->wbuf_verify);
if (ret && ret != -EUCLEAN && ret != -EBADMSG) {
pr_warn("%s(): Read back of page at %08x failed: %d\n",
__func__, c->wbuf_ofs, ret);
- return 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",
__func__, ofs, retlen, c->wbuf_pagesize);
- return -EIO;
+ ret = -EIO;
+ goto out_free;
+ }
+ if (!memcmp(buf, verify_buf, c->wbuf_pagesize)) {
+ ret = 0;
+ goto out_free;
}
- if (!memcmp(buf, c->wbuf_verify, c->wbuf_pagesize))
- return 0;
if (ret == -EUCLEAN)
eccstr = "corrected";
@@ -261,9 +273,14 @@ static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf,
pr_warn("Read back:\n");
print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1,
- c->wbuf_verify, c->wbuf_pagesize, 0);
+ verify_buf, c->wbuf_pagesize, 0);
+ kfree(verify_buf);
return -EIO;
+
+out_free:
+ kfree(verify_buf);
+ return ret;
}
#else
#define jffs2_verify_write(c,b,o) (0)
@@ -1217,22 +1234,11 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
return -ENOMEM;
}
-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
- c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
- if (!c->wbuf_verify) {
- kfree(c->oobbuf);
- kfree(c->wbuf);
- return -ENOMEM;
- }
-#endif
return 0;
}
void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
{
-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
- kfree(c->wbuf_verify);
-#endif
kfree(c->wbuf);
kfree(c->oobbuf);
}
@@ -1272,14 +1278,6 @@ int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
if (!c->wbuf)
return -ENOMEM;
-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
- c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
- if (!c->wbuf_verify) {
- kfree(c->wbuf);
- return -ENOMEM;
- }
-#endif
-
pr_info("write-buffering enabled buffer (%d) erasesize (%d)\n",
c->wbuf_pagesize, c->sector_size);
@@ -1287,9 +1285,6 @@ int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
}
void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) {
-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
- kfree(c->wbuf_verify);
-#endif
kfree(c->wbuf);
}
@@ -1309,20 +1304,10 @@ int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) {
if (!c->wbuf)
return -ENOMEM;
-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
- c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
- if (!c->wbuf_verify) {
- kfree(c->wbuf);
- return -ENOMEM;
- }
-#endif
return 0;
}
void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c) {
-#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
- kfree(c->wbuf_verify);
-#endif
kfree(c->wbuf);
}
--
2.52.0
next prev parent reply other threads:[~2026-09-06 3:13 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-06 3:03 [PATCH v4 0/8] jffs2: extend write verification to all write paths Zhou Minqiang
2026-09-06 3:03 ` [PATCH v4 1/8] jffs2: wbuf: clear wbuf on recovery failure paths Zhou Minqiang
2026-09-06 3:03 ` [PATCH v4 2/8] jffs2: wbuf: fix OBSOLETE under-coverage on recovery failure Zhou Minqiang
2026-09-06 3:03 ` Zhou Minqiang [this message]
2026-09-06 3:03 ` [PATCH v4 4/8] jffs2: write verify: add byte-by-byte comparison on mismatch Zhou Minqiang
2026-09-06 3:03 ` [PATCH v4 5/8] jffs2: add write verification to direct page writes in flash_writev Zhou Minqiang
2026-09-06 3:03 ` [PATCH v4 6/8] jffs2: add write verification to NOR direct write paths Zhou Minqiang
2026-09-06 3:03 ` [PATCH v4 7/8] jffs2: rename CONFIG_JFFS2_FS_WBUF_VERIFY to CONFIG_JFFS2_FS_WRITE_VERIFY Zhou Minqiang
2026-09-06 3:03 ` [PATCH v4 8/8] jffs2: add runtime toggle for write verification Zhou Minqiang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260906030344.2448622-4-zhouminqiang2@huawei.com \
--to=zhouminqiang2@huawei.com \
--cc=chengzhihao1@huawei.com \
--cc=dwmw2@infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=linux@armlinux.org.uk \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=maddy@linux.ibm.com \
--cc=piotr.wojtaszczyk@timesys.com \
--cc=richard@nod.at \
--cc=vz@mleia.com \
--cc=yangerkun@huawei.com \
--cc=yi.zhang@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox