mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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: 68142cb628 ("nilfs2: do not call inode_attach_wb() directly")
Cc: stable@vger.kernel.org
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
This commit is contained in:
parent
ff1227f70e
commit
6faad04a00
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user