[Devel] [PATCH rh7 v2 1/3] ext4: add missing brelse() for bh2 in ext4_dx_add_entry()
Konstantin Khorenko
khorenko at virtuozzo.com
Tue Apr 21 17:23:42 MSK 2026
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 eb640af64db6d4702a85ab001b9cc7f4c5dd6abb)
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov 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 5279a83f4040f..bacdd0630b2c0 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"));
--
2.24.3
More information about the Devel
mailing list