From: zhouminqiang <zhouminqiang2@huawei.com>
To: <dwmw2@infradead.org>, <richard@nod.at>
Cc: <linux-mtd@lists.infradead.org>, <linux-kernel@vger.kernel.org>,
<chengzhihao1@huawei.com>, <yangerkun@huawei.com>,
<yi.zhang@huawei.com>
Subject: [PATCH 1/6] jffs2: replace per-superblock verify buffer with per-write buffer
Date: Thu, 20 Aug 2026 18:49:57 +0800 [thread overview]
Message-ID: <20260820105003.2525647-2-zhouminqiang2@huawei.com> (raw)
In-Reply-To: <20260820105003.2525647-1-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 3b7803c75d58..7e4608b43a4e 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>
#include <linux/crc32.h>
#include <linux/mtd/rawnand.h>
@@ -233,19 +234,30 @@ static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf,
int ret;
size_t retlen;
char *eccstr;
+ void *verify_buf;
- ret = mtd_read(c->mtd, ofs, c->wbuf_pagesize, &retlen, c->wbuf_verify);
+ verify_buf = __vmalloc(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);
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);
+ vfree(verify_buf);
return -EIO;
+
+out_free:
+ vfree(verify_buf);
+ return ret;
}
#else
#define jffs2_verify_write(c,b,o) (0)
@@ -1214,22 +1231,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);
}
@@ -1269,14 +1275,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);
@@ -1284,9 +1282,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);
}
@@ -1306,20 +1301,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
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
WARNING: multiple messages have this Message-ID (diff)
From: zhouminqiang <zhouminqiang2@huawei.com>
To: <dwmw2@infradead.org>, <richard@nod.at>
Cc: <linux-mtd@lists.infradead.org>, <linux-kernel@vger.kernel.org>,
<chengzhihao1@huawei.com>, <yangerkun@huawei.com>,
<yi.zhang@huawei.com>
Subject: [PATCH 1/6] jffs2: replace per-superblock verify buffer with per-write buffer
Date: Thu, 20 Aug 2026 18:49:57 +0800 [thread overview]
Message-ID: <20260820105003.2525647-2-zhouminqiang2@huawei.com> (raw)
In-Reply-To: <20260820105003.2525647-1-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 3b7803c75d58..7e4608b43a4e 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>
#include <linux/crc32.h>
#include <linux/mtd/rawnand.h>
@@ -233,19 +234,30 @@ static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf,
int ret;
size_t retlen;
char *eccstr;
+ void *verify_buf;
- ret = mtd_read(c->mtd, ofs, c->wbuf_pagesize, &retlen, c->wbuf_verify);
+ verify_buf = __vmalloc(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);
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);
+ vfree(verify_buf);
return -EIO;
+
+out_free:
+ vfree(verify_buf);
+ return ret;
}
#else
#define jffs2_verify_write(c,b,o) (0)
@@ -1214,22 +1231,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);
}
@@ -1269,14 +1275,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);
@@ -1284,9 +1282,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);
}
@@ -1306,20 +1301,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-08-20 10:57 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-20 10:49 [PATCH 0/6] jffs2: extend write verification to all write paths zhouminqiang
2026-08-20 10:49 ` zhouminqiang
2026-08-20 10:49 ` zhouminqiang [this message]
2026-08-20 10:49 ` [PATCH 1/6] jffs2: replace per-superblock verify buffer with per-write buffer zhouminqiang
2026-08-20 10:49 ` [PATCH 2/6] jffs2: write verify: replace memcmp with byte-by-byte comparison zhouminqiang
2026-08-20 10:49 ` zhouminqiang
2026-08-20 10:49 ` [PATCH 3/6] jffs2: add write verification to direct page writes in flash_writev zhouminqiang
2026-08-20 10:49 ` zhouminqiang
2026-08-20 10:50 ` [PATCH 4/6] jffs2: add write verification to NOR direct write paths zhouminqiang
2026-08-20 10:50 ` zhouminqiang
2026-08-20 10:50 ` [PATCH 5/6] jffs2: rename CONFIG_JFFS2_FS_WBUF_VERIFY to CONFIG_JFFS2_FS_WRITE_VERIFY zhouminqiang
2026-08-20 10:50 ` zhouminqiang
2026-08-20 10:50 ` [PATCH 6/6] jffs2: add runtime toggle for write verification zhouminqiang
2026-08-20 10:50 ` zhouminqiang
2026-08-20 18:58 ` [PATCH 0/6] jffs2: extend write verification to all write paths Richard Weinberger
2026-08-20 18:58 ` Richard Weinberger
2026-08-20 20:46 ` David Woodhouse
2026-08-20 20:46 ` David Woodhouse
2026-08-21 3:37 ` zhouminqiang
2026-08-21 3:37 ` zhouminqiang
2026-08-21 6:31 ` Richard Weinberger
2026-08-21 6:31 ` Richard Weinberger
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=20260820105003.2525647-2-zhouminqiang2@huawei.com \
--to=zhouminqiang2@huawei.com \
--cc=chengzhihao1@huawei.com \
--cc=dwmw2@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=richard@nod.at \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.