In jffs2_wbuf_recover(), when the recovery write to the new erase block also fails, the code marks the already-written portion as REF_OBSOLETE via jffs2_add_physical_node_ref(). However, the length passed is ref_totlen(c, jeb, first_raw), which is the length of a single node on the old block, not retlen which is the actual number of bytes written to the new block.
When the recovery buffer contains multiple nodes, ref_totlen only accounts for the first node's length, which can be much smaller than retlen. This under-deducts free_size, causing subsequent allocations to land on already-programmed NAND pages and silently corrupt data. When first_raw is the only node in the recovery range, ref_totlen equals the full unaligned data size and exceeds the page-aligned retlen, over-deducting free_size and wasting space. Use retlen so the new block's free_size accurately reflects which NAND pages have been programmed. Signed-off-by: zhouminqiang <[email protected]> --- fs/jffs2/wbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index 61e3dbd4cd7b..360a291d9fd5 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c @@ -437,7 +437,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) kfree(buf); if (retlen) - jffs2_add_physical_node_ref(c, ofs | REF_OBSOLETE, ref_totlen(c, jeb, first_raw), NULL); + jffs2_add_physical_node_ref(c, ofs | REF_OBSOLETE, retlen, NULL); c->wbuf_len = 0; return; -- 2.52.0
