mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
udf: Mark LVID buffer as uptodate before marking it dirty
When an I/O error occurs while writing the Logical Volume Integrity Descriptor (LVID) buffer to the block device, the block layer's completion handler (`end_buffer_write_sync()`) clears the `BH_Uptodate` flag on the buffer. However, the buffer still contains valid LVID data in memory. If the filesystem is subsequently remounted read-write or synced, `udf_open_lvid()` or `udf_sync_fs()` will modify the LVID buffer and call `mark_buffer_dirty()`. This triggers a spurious `WARN_ON_ONCE(!buffer_uptodate(bh))` warning in `mark_buffer_dirty()` because the buffer is not marked uptodate, even though its in-memory contents are valid and are about to be overwritten. To prevent this spurious warning, unconditionally set the `BH_Uptodate` flag before calling `mark_buffer_dirty()` in `udf_open_lvid()` and `udf_sync_fs()`. This acknowledges that the in-memory buffer is valid and matches the workaround previously applied to `udf_close_lvid()` in commit853a0c25ba("udf: Mark LVID buffer as uptodate before marking it dirty"). Extending this workaround ensures consistent behavior across all LVID updates. Buffer I/O error on dev loop0, logical block 128, lost sync page write ------------[ cut here ]------------ !buffer_uptodate(bh) WARNING: fs/buffer.c:1087 at mark_buffer_dirty+0x299/0x410 fs/buffer.c:1087 ... Call Trace: <TASK> udf_open_lvid+0x369/0x5b0 fs/udf/super.c:2078 udf_reconfigure+0x336/0x540 fs/udf/super.c:679 reconfigure_super+0x232/0x8f0 fs/super.c:1080 vfs_cmd_reconfigure fs/fsopen.c:268 [inline] vfs_fsconfig_locked+0x171/0x320 fs/fsopen.c:297 __do_sys_fsconfig fs/fsopen.c:463 [inline] __se_sys_fsconfig+0x6b9/0x810 fs/fsopen.c:350 do_syscall_64+0x174/0x580 arch/x86/entry/syscall_64.c:94 </TASK> Fixes:853a0c25ba("udf: Mark LVID buffer as uptodate before marking it dirty") Assisted-by: Gemini:gemini-3.1-pro-preview Gemini:gemini-3-flash-preview syzbot Reported-by: syzbot+0306b38d9ed6ef71467d@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=0306b38d9ed6ef71467d Link: https://syzkaller.appspot.com/ai_job?id=05f8e20f-f080-4c7f-a206-08dbc15cb4a1 Signed-off-by: Aleksandr Nogikh <nogikh@google.com> Link: https://patch.msgid.link/6ffb2ca8-e22f-4fd6-9f37-7202ec0878bd@mail.kernel.org Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
parent
31e5e0c8c8
commit
fb0601134c
|
|
@ -2054,6 +2054,17 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void udf_mark_buffer_dirty(struct buffer_head *bh)
|
||||
{
|
||||
/*
|
||||
* We set buffer uptodate unconditionally here to avoid spurious
|
||||
* warnings from mark_buffer_dirty() when previous EIO has marked
|
||||
* the buffer as !uptodate
|
||||
*/
|
||||
set_buffer_uptodate(bh);
|
||||
mark_buffer_dirty(bh);
|
||||
}
|
||||
|
||||
static void udf_finalize_lvid(struct logicalVolIntegrityDesc *lvid)
|
||||
{
|
||||
struct timespec64 ts;
|
||||
|
|
@ -2089,7 +2100,7 @@ static void udf_open_lvid(struct super_block *sb)
|
|||
UDF_SET_FLAG(sb, UDF_FLAG_INCONSISTENT);
|
||||
|
||||
udf_finalize_lvid(lvid);
|
||||
mark_buffer_dirty(bh);
|
||||
udf_mark_buffer_dirty(bh);
|
||||
sbi->s_lvid_dirty = 0;
|
||||
mutex_unlock(&sbi->s_alloc_mutex);
|
||||
/* Make opening of filesystem visible on the media immediately */
|
||||
|
|
@ -2122,14 +2133,8 @@ static void udf_close_lvid(struct super_block *sb)
|
|||
if (!UDF_QUERY_FLAG(sb, UDF_FLAG_INCONSISTENT))
|
||||
lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
|
||||
|
||||
/*
|
||||
* We set buffer uptodate unconditionally here to avoid spurious
|
||||
* warnings from mark_buffer_dirty() when previous EIO has marked
|
||||
* the buffer as !uptodate
|
||||
*/
|
||||
set_buffer_uptodate(bh);
|
||||
udf_finalize_lvid(lvid);
|
||||
mark_buffer_dirty(bh);
|
||||
udf_mark_buffer_dirty(bh);
|
||||
sbi->s_lvid_dirty = 0;
|
||||
mutex_unlock(&sbi->s_alloc_mutex);
|
||||
/* Make closing of filesystem visible on the media immediately */
|
||||
|
|
@ -2411,7 +2416,7 @@ static int udf_sync_fs(struct super_block *sb, int wait)
|
|||
* Blockdevice will be synced later so we don't have to submit
|
||||
* the buffer for IO
|
||||
*/
|
||||
mark_buffer_dirty(bh);
|
||||
udf_mark_buffer_dirty(bh);
|
||||
sbi->s_lvid_dirty = 0;
|
||||
}
|
||||
mutex_unlock(&sbi->s_alloc_mutex);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user