[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <62fpgbfco7nb5sy5shkix27aarsc4tuyg6pit4af6xbgojgvjc@v6dnu33wd4jb>
Date: Tue, 16 Sep 2025 12:57:57 +0200
From: Jan Kara <jack@...e.cz>
To: Zhang Yi <yi.zhang@...weicloud.com>
Cc: linux-ext4@...r.kernel.org, linux-fsdevel@...r.kernel.org,
linux-kernel@...r.kernel.org, tytso@....edu, adilger.kernel@...ger.ca, jack@...e.cz,
hsiangkao@...ux.alibaba.com, yi.zhang@...wei.com, libaokun1@...wei.com, yukuai3@...wei.com,
yangerkun@...wei.com
Subject: Re: [PATCH 2/2] ext4: wait for ongoing I/O to complete before
freeing blocks
On Tue 16-09-25 17:33:37, Zhang Yi wrote:
> From: Zhang Yi <yi.zhang@...wei.com>
>
> 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")
> Reported-by: Gao Xiang <hsiangkao@...ux.alibaba.com>
> Closes: https://lore.kernel.org/linux-ext4/a9417096-9549-4441-9878-b1955b899b4e@huaweicloud.com/
> Signed-off-by: Zhang Yi <yi.zhang@...wei.com>
Looks good. Feel free to add:
Reviewed-by: Jan Kara <jack@...e.cz>
Honza
> ---
> fs/ext4/ext4_jbd2.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
> index b3e9b7bd7978..a0e66bc10093 100644
> --- a/fs/ext4/ext4_jbd2.c
> +++ b/fs/ext4/ext4_jbd2.c
> @@ -280,9 +280,16 @@ int __ext4_forget(const char *where, unsigned int line, handle_t *handle,
> bh, is_metadata, inode->i_mode,
> test_opt(inode->i_sb, DATA_FLAGS));
>
> - /* In the no journal case, we can just do a bforget and return */
> + /*
> + * In the no journal case, we should wait for the ongoing buffer
> + * to complete and do a forget.
> + */
> if (!ext4_handle_valid(handle)) {
> - bforget(bh);
> + if (bh) {
> + clear_buffer_dirty(bh);
> + wait_on_buffer(bh);
> + __bforget(bh);
> + }
> return 0;
> }
>
> --
> 2.46.1
>
--
Jan Kara <jack@...e.com>
SUSE Labs, CR
Powered by blists - more mailing lists