[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