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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.