From 6faad04a002603d800134398fcd042b403b32d35 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Tue, 29 Sep 2026 15:38:14 +0900 Subject: [PATCH] nilfs2: clear dirty flag on bdev buffers on log write failure Since the commit referenced in the Fixes tag stopped directly calling inode_attach_wb(), a dirty flag is set on buffers (with mark_buffer_dirty()) allocated to the backing device for segment summaries and the super root block during log writes. While this dirty flag is cleared upon a successful log write, it remains uncleared if the log write fails. Consequently, when a log write fails, these backing device buffers are left in an inconsistent state where their uptodate flag and the dirty flag of the containing page/folio are cleared, but the buffer's dirty flag remains as stale garbage. Particularly when the block size is smaller than the page size, if other buffers on the same page/folio become dirty, this buffer unexpectedly becomes a target for writeback again. As a result, if the block is later reused for other data or metadata, that contents risks being corrupted. Fix this issue by calling clear_buffer_dirty() for the backing device buffers when aborting log writes in nilfs_abort_logs(). Fixes: 68142cb628f7 ("nilfs2: do not call inode_attach_wb() directly") Cc: stable@vger.kernel.org Signed-off-by: Ryusuke Konishi Signed-off-by: Viacheslav Dubeyko --- fs/nilfs2/segment.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 829573cb6131..2f0e59847d02 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -1829,6 +1829,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err) list_for_each_entry(segbuf, logs, sb_list) { list_for_each_entry(bh, &segbuf->sb_segsum_buffers, b_assoc_buffers) { + clear_buffer_dirty(bh); clear_buffer_uptodate(bh); if (bh->b_folio != bd_folio) { if (bd_folio) @@ -1840,6 +1841,7 @@ static void nilfs_abort_logs(struct list_head *logs, int err) list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) { if (bh == segbuf->sb_super_root) { + clear_buffer_dirty(bh); clear_buffer_uptodate(bh); if (bh->b_folio != bd_folio) { folio_end_writeback(bd_folio);