Skip to content

Commit 328a782

Browse files
zhangyi089tytso
authored andcommitted
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: 16e08b1 ("ext4: cleanup clean_bdev_aliases() calls") Cc: [email protected] Reported-by: Gao Xiang <[email protected]> Closes: https://lore.kernel.org/linux-ext4/[email protected]/ Signed-off-by: Zhang Yi <[email protected]> Reviewed-by: Jan Kara <[email protected]> Message-ID: <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 3c652c3 commit 328a782

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

fs/ext4/ext4_jbd2.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,16 @@ int __ext4_forget(const char *where, unsigned int line, handle_t *handle,
280280
bh, is_metadata, inode->i_mode,
281281
test_opt(inode->i_sb, DATA_FLAGS));
282282

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+
*/
284287
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+
}
286293
return 0;
287294
}
288295

0 commit comments

Comments
 (0)