From: Su Yue <l@damenly.org>
To: Qu Wenruo <wqu@suse.com>
Cc: linux-btrfs@vger.kernel.org, Glass Su <glass.su@suse.com>
Subject: Re: [PATCH] btrfs: do not check eb->refs to determine if the eb is still held
Date: Sat, 20 Jun 2026 10:46:21 +0800 [thread overview]
Message-ID: <cxxmszcy.fsf@damenly.org> (raw)
In-Reply-To: <8b5fd5214014615765dfdc66f89347c4ea8b2654.1781921185.git.wqu@suse.com> (Qu Wenruo's message of "Sat, 20 Jun 2026 11:37:01 +0930")
On Sat 20 Jun 2026 at 11:37, Qu Wenruo <wqu@suse.com> wrote:
> [FALSE ALERTS]
> There is a bug report that the warning inside
> invalidate_and_check_btree_folios() got triggered duriong
> btrfs/298:
>
> BTRFS info (device sdd): first mount of filesystem
> f9bf732a-a19b-44b9-99a7-614ddff168e2
> BTRFS info (device sdd): using crc32c checksum algorithm
> BTRFS error (device sdd): failed to find fsid
> cb2fdb42-b638-4f2f-badd-4127467ba674 when attempting to open
> seed devices
> BTRFS error (device sdd): failed to read chunk tree: -2
> ------------[ cut here ]------------
> WARNING: disk-io.c:3342 at
> invalidate_and_check_btree_folios+0x260/0x3c0 [btrfs], CPU#4:
> mount/125993
> CPU: 4 UID: 0 PID: 125993 Comm: mount Tainted: G W OE
> 7.1.0-rc7-custom+ #1 PREEMPT(full)
> Hardware name: QEMU KVM Virtual Machine, BIOS
> edk2-20250812-19.fc42 08/12/2025
> Call trace:
> invalidate_and_check_btree_folios+0x260/0x3c0 [btrfs] (P)
> open_ctree+0x1f50/0x23b0 [btrfs]
> btrfs_get_tree+0x89c/0xc48 [btrfs]
> vfs_get_tree+0x30/0x110
> vfs_cmd_create+0x58/0xe8
> __arm64_sys_fsconfig+0x39c/0x518
> invoke_syscall.constprop.0+0x48/0x120
> el0_svc_common.constprop.0+0x40/0xe8
> do_el0_svc+0x24/0x38
> el0_svc+0x50/0x310
> el0t_64_sync_handler+0xa0/0xe8
> el0t_64_sync+0x198/0x1a0
> ---[ end trace 0000000000000000 ]---
> BTRFS warning (device sdd): unable to release extent buffer
> 365985792 owner 3 gen 17 refs 3 flags 0x5
>
> [CAUSE]
> In that invalidate_and_check_btree_folios() we wait for the eb
> to finish
> its read, then check if it's only held by us and the btree
> inode.
>
> If not, then do a warning as it may be still held, and could
> cause
> problems.
>
> But there is a small window where the check can lead to false
> alerts:
>
> Thread A (Read endio) | Thread B (Unmount)
> ----------------------------------+-------------------------------------
> end_bbio_meta_read() |
> | The eb has one extra ref held |
> | by the reader, and has |
> | EXTENT_BUFFER_READING flag set |
> invalidate_and_check_btree_folios()
> | | |
> |- clear_extent_buffer_reading() | |
> | | |- wait_on_bit_io();
> | | | The EXTENT_BUFFER_READING
> flag is
> | | | cleared
> | | |- if
> (refcount_read(eb->refs) > 2)
> | | The eb is held by the
> read, us
> | | and btree inode, thus it
> | | will trigger the warning
> |- free_extent_buffer() |
>
> [WORKAROUND]
> Unfortunately EXTENT_BUFFER_READING flag clearing is always
> before
> extent buffer put, thus there is no simple way to make sure the
> read is
> finished along with eb put.
>
> For now just remove the eb->refs check until a proper protection
> is
> introduced for clearing EXTENT_BUFFER_READING and updates of
> eb->refs.
>
> Reported-by: Glass Su <glass.su@suse.com>
>
Reported-by: Su Yue <glass.su@suse.com>
Also for this patch:
Reviewed-by: Su Yue <glass.su@suse.com>
> Link:
> https://lore.kernel.org/linux-btrfs/DC0C775E-13B3-47D9-9AB2-895BB11C029D@suse.com/
> Fixes: 83f7e52b7ed1 ("btrfs: warn about extent buffer that can
> not be released")
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
> fs/btrfs/disk-io.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> index 0a7d80da9c94..39a389cdbdd4 100644
> --- a/fs/btrfs/disk-io.c
> +++ b/fs/btrfs/disk-io.c
> @@ -3328,10 +3328,14 @@ static void
> invalidate_and_check_btree_folios(struct btrfs_fs_info *fs_info)
> wait_on_bit_io(&eb->bflags, EXTENT_BUFFER_READING,
> TASK_UNINTERRUPTIBLE);
> /*
> - * The refs threshold is 2, one held by us at the
> beginning
> - * of the loop, one for the ownership in the buffer tree.
> + * EXTENT_BUFFER_READING is cleared then the eb refs is
> put during
> + * end_bbio_meta_read(), which leaves a window where above
> wait
> + * finished but eb ref is still hold by endio.
> + *
> + * Thus we can not use eb->refs to determine if the eb is
> hold
> + * by someone else. Just check if the eb is still under
> IO.
> */
> - if (unlikely(refcount_read(&eb->refs) > 2 ||
> extent_buffer_under_io(eb))) {
> + if (unlikely(extent_buffer_under_io(eb))) {
> WARN_ON_ONCE(IS_ENABLED(CONFIG_BTRFS_DEBUG));
> btrfs_warn(fs_info,
> "unable to release extent buffer %llu owner %llu gen
> %llu refs %u flags 0x%lx",
next prev parent reply other threads:[~2026-06-20 2:51 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-20 2:07 [PATCH] btrfs: do not check eb->refs to determine if the eb is still held Qu Wenruo
2026-06-20 2:46 ` Su Yue [this message]
2026-06-20 3:01 ` Qu Wenruo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cxxmszcy.fsf@damenly.org \
--to=l@damenly.org \
--cc=glass.su@suse.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=wqu@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox