From patchwork Wed Dec 31 22:29:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1148 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767220275; bh=179rUNxeOghgYhKIC0OFBikzmuRL2EJntGQbyZUixDc=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=Y9eT5ib6/QCxy8T3MsQLf19uZOR4j6CORjq1LY+4b+GlMB7iDziYjmjE4So/oqijx Rb+sKwtAyLXUovtxTC2Bk9I8UuoGQ1EZ5cxOWT7X8JGnZqFI6O3qOIlsa40amZAmGC YxTNKNbfmBifk8fxntW9w2PbjmDKQEHWA7wFQsH6fiZhD29g6ogNwgA6Vs/VBhLbpJ 0YJYD1WmqHtl+SLlqxEKLJhP1okJtxD89YTp10Pn81l36Jx0L8iTo/OWGw2pnsoIYF lIKdh+8RiK3d3q7jlaMrO9Hx9GoImwPSNY0Hz5FRXdLlMnY5lXWWpmpWMCgFXcNjEA il9ZB/nkDtzCQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 3540868FD3 for ; Wed, 31 Dec 2025 15:31:15 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 7FgN_g5oIAeK for ; Wed, 31 Dec 2025 15:31:15 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767220273; bh=179rUNxeOghgYhKIC0OFBikzmuRL2EJntGQbyZUixDc=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=kCrK+e27UcSBpsiwoOvKle5bG6IMmjQkk5xBeOl/pdkmTpeddrcjldOmnFEWTCnml akkUF9VTxakfWS8QzURpRSf1A3gL9RN65yYzyxnbybs2+S4bzl7PhbBbYpn9w5nINg o5eB4TR05Lt2aQXHHHqIf0vv5QKX6wlYXF6yFYBLHa4k7tbKrYuLaVYuOUDnZAwCwn Wf8E3DWWB49VeTtG7oeBTU7ZyfKm7L4j1NjGZ6snoROnOn2+2RdEsrDoen1ntVbcWa QE8pCRKqZL5QeT6BiW2n5ZKNbEHy9AO/C+7reRFbpcAc0vm8RTsptjwov8SAFHjT4w 1wi7vYy+v6jRA== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 38CA368F61 for ; Wed, 31 Dec 2025 15:31:13 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767220270; bh=IlBijvSFUSLa6oZEdWHJ8L/Z/DEgmFJ3U3n3cPya5Po=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lT0Oy/H79r7BAOvedDaBZZo4nKry1hAvqSpNcxi5OphyFwa7quAwgM5KHp+EFtdsE Z9vX2MFU1OIjiKZis6irrKwdFrvcJDShSUgugWTmFtUoIrpJEV83YKR3FDjMEKlyO2 0+8kTtFcLqkw1FReNIksffQjZq40Q+Uhh7g5MegXYiRGNpr/4CYr/dIYSVQ21E+wqy TUtDpXxKL7oglidJsolmqo6RrMFF9OZW+stF6FWMefwGPmUD3J/TadQXTysQytox4O Tl9O9PFg8pJ3gqMEvW9gy9vFXXLj2DOlZ5msGRblzdNK3nttemMOSnyX0qrwmIWrIq ZLcdKseLne5og== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id E917268FD3; Wed, 31 Dec 2025 15:31:10 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id yOPH_HySSiA5; Wed, 31 Dec 2025 15:31:10 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767220270; bh=jQ1x1xzdGGIkKIklF8R67MBQ/EeAn0IVP49IToPce94=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=THjNPQhKEuTw31XLr2kXEfcKUdCTGbrkcqCevMl5qK1GUjXsM3AuaOXtSmLNt4n00 mkqmVGUeY23qAXNU/JAvhtyLZY9yZKfN8jf/tPmi8crJ351fhsvnK1uyTHMV2YiQhC aeIbGAl/GwXURiuqThsz0/ajNsMhCuIQLkPSLAnAIwgR42VDnYIpSYwOTF/3INOt+Y I8AK25fdL8ztxoE0KYr8pUKgJMuRiC52iqJbcoxMEO1CHnzwe8Z/2A1/AJInYivgIw BqP2gIuNj/P2S4E0OdTUtJOHBgW/FSjBEMRxfEoL8N3TAf2f/qaUPSlo6fJM1iCrGU LvHhpwKml9fMA== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 0EC5268C5D; Wed, 31 Dec 2025 15:31:10 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Wed, 31 Dec 2025 15:29:43 -0700 Message-ID: <20251231223008.3251711-11-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251231223008.3251711-1-sjg@u-boot.org> References: <20251231223008.3251711-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: GSMVC6RPYNJMS2DAUIGAZVM6E5H7XU4N X-Message-ID-Hash: GSMVC6RPYNJMS2DAUIGAZVM6E5H7XU4N X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass , Claude X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 10/26] ext4l: Fix a few problems with handling bh_cache List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Several buffer cache issues cause problems when remounting: 1. bh_cache_insert() only checks block number, but the same block can be read with different sizes (e.g. superblock at 1K vs 4K). Check both block number and size when determining if already cached. 2. bh_cache_clear() leaves stale buffer references, causing memory leaks. Force the reference count to 1 before releasing since ext4 code won't access these buffers after unmount. 3. brelse() calls free_buffer_head() when the reference count reaches zero. However, buffer heads remain in the cache and are freed by bh_cache_clear() during unmount. This causes a double-free. Fix this by having brelse() only decrement the count, without freeing. Co-developed-by: Claude Signed-off-by: Simon Glass --- fs/ext4l/support.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/fs/ext4l/support.c b/fs/ext4l/support.c index 7f2bea4ca06..3133a4ebead 100644 --- a/fs/ext4l/support.c +++ b/fs/ext4l/support.c @@ -258,9 +258,10 @@ static void bh_cache_insert(struct buffer_head *bh) unsigned int hash = bh_cache_hash(bh->b_blocknr); struct bh_cache_entry *entry; - /* Check if already in cache */ + /* Check if already in cache - must match block AND size */ for (entry = bh_cache[hash]; entry; entry = entry->next) { - if (entry->bh && entry->bh->b_blocknr == bh->b_blocknr) + if (entry->bh && entry->bh->b_blocknr == bh->b_blocknr && + entry->bh->b_size == bh->b_size) return; /* Already cached */ } @@ -316,7 +317,12 @@ void bh_cache_clear(void) struct buffer_head *bh = entry->bh; bh_clear_stale_jbd(bh); - /* Release the cache's reference */ + /* + * Force count to 1 so the buffer will be freed. + * On unmount, ext4 code won't access these + * buffers again, so extra references are stale. + */ + atomic_set(&bh->b_count, 1); if (atomic_dec_and_test(&bh->b_count)) free_buffer_head(bh); } @@ -629,14 +635,24 @@ struct buffer_head *sb_bread(struct super_block *sb, sector_t block) /** * brelse() - Release a buffer_head * @bh: Buffer head to release + * + * Decrements the reference count on the buffer. Buffer heads are cached + * and only freed by bh_cache_clear() on unmount, so this just decrements + * the count without freeing. */ void brelse(struct buffer_head *bh) { if (!bh) return; - if (atomic_dec_and_test(&bh->b_count)) - free_buffer_head(bh); + /* + * If buffer has JBD attached, don't let ref count go to zero. + * The journal owns a reference and will clean up properly. + */ + if (buffer_jbd(bh) && atomic_read(&bh->b_count) <= 1) + return; + + atomic_dec(&bh->b_count); } /**