[Devel] [PATCH rh7 1/3] ext4: add missing brelse() for bh2 in ext4_dx_add_entry()
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Mon Apr 20 12:34:07 MSK 2026
On 4/9/26 15:56, Konstantin Khorenko wrote:
> From: Kemeng Shi <shikemeng at huaweicloud.com>
>
> Add missing brelse() for bh2 in ext4_dx_add_entry().
>
> Fixes: ac27a0ec112a ("[PATCH] ext4: initial copy of files from ext3")
> Signed-off-by: Kemeng Shi <shikemeng at huaweicloud.com>
> Reviewed-by: Ojaswin Mujoo <ojaswin at linux.ibm.com>
> Reviewed-by: Zhang Yi <yi.zhang at huawei.com>
> Link: https://patch.msgid.link/20250123162050.2114499-2-shikemeng@huaweicloud.com
> Signed-off-by: Theodore Ts'o <tytso at mit.edu>
>
> [khorenko: backport to 3.10 - adapted to older ext4_dx_add_entry()
> code structure. Applied 3 of 4 upstream hunks:
>
> 1. ext4_journal_get_write_access(handle, frame->bh) error path:
> bh2 was just allocated via ext4_append() and not yet stored in
> any dx_frame, so dx_release() would not free it. Need explicit
> brelse(bh2).
>
> 2. ext4_journal_get_write_access(handle, frames[0].bh) error path
> inside "if (levels)" block:
> swap(frame->bh, bh2) has not executed yet, so bh2 is still not
> referenced by any frame - same situation as (1).
>
> 3. ext4_handle_dirty_dx_node(handle, dir, bh2) inside "if (levels)"
> block:
> Regardless of whether swap(frame->bh, bh2) happened, bh2 holds
> a buffer that dx_release() does not cover. Moved brelse(bh2)
> before the error check since it is needed on both success and
> error paths.
>
> Skipped the 4th upstream hunk (else branch - creating second level
> index): in our code frame->bh = bh2 is assigned and indirect_levels
> is set to 1 before the error path, so dx_release() calls
> brelse(frames[1].bh) which is bh2. Adding explicit brelse(bh2)
> there would cause a double-free.]
>
> https://virtuozzo.atlassian.net/browse/PSBM-161670
> (cherry picked from commit eb640af64db6e5b4b1263d59e4b7849e7fc29352)
Somehow incorrect hash here, should be:
commit eb640af64db6d4702a85ab001b9cc7f4c5dd6abb
Author: Kemeng Shi <shikemeng at huaweicloud.com>
Date: Fri Jan 24 00:20:48 2025 +0800
ext4: add missing brelse() for bh2 in ext4_dx_add_entry()
Except that:
Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
> ---
> fs/ext4/namei.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
> index 5279a83f4040..bacdd0630b2c 100644
> --- a/fs/ext4/namei.c
> +++ b/fs/ext4/namei.c
> @@ -2055,8 +2055,10 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
> sb->s_blocksize);
> BUFFER_TRACE(frame->bh, "get_write_access");
> err = ext4_journal_get_write_access(handle, frame->bh);
> - if (err)
> + if (err) {
> + brelse(bh2);
> goto journal_error;
> + }
> if (levels) {
> unsigned icount1 = icount/2, icount2 = icount - icount1;
> unsigned hash2 = dx_get_hash(entries + icount1);
> @@ -2066,8 +2068,10 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
> BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
> err = ext4_journal_get_write_access(handle,
> frames[0].bh);
> - if (err)
> + if (err) {
> + brelse(bh2);
> goto journal_error;
> + }
>
> memcpy((char *) entries2, (char *) (entries + icount1),
> icount2 * sizeof(struct dx_entry));
> @@ -2086,9 +2090,9 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
> dxtrace(dx_show_index("node",
> ((struct dx_node *) bh2->b_data)->entries));
> err = ext4_handle_dirty_dx_node(handle, dir, bh2);
> + brelse(bh2);
> if (err)
> goto journal_error;
> - brelse (bh2);
> } else {
> dxtrace(printk(KERN_DEBUG
> "Creating second level index...\n"));
--
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.
More information about the Devel
mailing list