Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ext4: wait for ongoing I/O to complete before freeing blocks

When freeing metadata blocks in nojournal mode, ext4_forget() calls
bforget() to clear the dirty flag on the buffer_head and remvoe
associated mappings. This is acceptable if the metadata has not yet
begun to be written back. However, if the write-back has already started
but is not yet completed, ext4_forget() will have no effect.
Subsequently, ext4_mb_clear_bb() will immediately return the block to
the mb allocator. This block can then be reallocated immediately,
potentially causing an data corruption issue.

Fix this by clearing the buffer's dirty flag and waiting for the ongoing
I/O to complete, ensuring that no further writes to stale data will
occur.

Fixes: 16e08b14a455 ("ext4: cleanup clean_bdev_aliases() calls")
Cc: stable@kernel.org
Reported-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Closes: https://lore.kernel.org/linux-ext4/a9417096-9549-4441-9878-b1955b899b4e@huaweicloud.com/
Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Message-ID: <20250916093337.3161016-3-yi.zhang@huaweicloud.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>

authored by

Zhang Yi and committed by
Theodore Ts'o
328a782c 3c652c3a

+9 -2
+9 -2
fs/ext4/ext4_jbd2.c
··· 280 280 bh, is_metadata, inode->i_mode, 281 281 test_opt(inode->i_sb, DATA_FLAGS)); 282 282 283 - /* In the no journal case, we can just do a bforget and return */ 283 + /* 284 + * In the no journal case, we should wait for the ongoing buffer 285 + * to complete and do a forget. 286 + */ 284 287 if (!ext4_handle_valid(handle)) { 285 - bforget(bh); 288 + if (bh) { 289 + clear_buffer_dirty(bh); 290 + wait_on_buffer(bh); 291 + __bforget(bh); 292 + } 286 293 return 0; 287 294 } 288 295