From: Qu Wenruo <wqu@suse.com>
To: Teng Liu <27rabbitlt@gmail.com>
Cc: linux-btrfs@vger.kernel.org, dsterba@suse.com, clm@fb.com,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] btrfs: wait for in-flight readahead BIOs on open_ctree() error
Date: Tue, 31 Mar 2026 08:18:37 +1030 [thread overview]
Message-ID: <6564fe96-ead0-45d4-9655-cd14f13bdc9a@suse.com> (raw)
In-Reply-To: <acq5Y9VuDI9htA-I@rabbitArch>
在 2026/3/31 04:30, Teng Liu 写道:
> On 2026-03-30 08:51, Qu Wenruo wrote:
>>
>>
>> 在 2026/3/30 08:36, Qu Wenruo 写道:
>>>
>>>
>>> Even you wait for all bios, it can still cause problems.
>>>
>>> As the bio counter is only for btrfs bio layer, we still have
>>> btrfs_bio::end_io called after btrfs_bio_counter_dec().
>>>
>>> And if the full fs_info has been freed, then at end_bbio_meta_read(), we
>>> can still have problems as btrfs_validate_extent_buffer() will access eb
>>> (bbio->private) and fs_info (eb->fs_info), which triggers use after
>>> free.
>>>
>>> So using that bio counter is not going to solve all problems, but only
>>> reducing the race window thus masking the problem.
>>>
>>>
>>> The following ideas come up to me, but neither seems as simple as your
>>> current one:
>>>
>>> 1) Introduce a dedicated counter for metadata readahead/reads
>>> This seems to be the simplest one among all.
>>> But the only usage is only the error handling, thus may not be
>>> worthy.
>>>
>>> 2) Disable metadata readahead during open_ctree()
>>> Which will delay the mount, especially for large extent tree without
>>> bgt feature.
>>>
>>> 3) Use buffer_tree xarray to iterate through all ebs
>>> Since this is only for error handling of open_ctree(), we're fine to
>>> do the full xarray iteration, and wait for any eb that has
>>> EXTENT_BUFFER_READING flag.
>>>
>>> The problem is, we do not have a dedicated tag like
>>> PAGECACHE_TAG_(TOWRITE|DIRTY) to easily catch all dirty/writeback
>>> ebs.
>>> So the only option is to go through each eb and check their flags.
>>>
>>> I think this is the one with minimal impact, but may cause much
>>> longer runtime during this error handling path.
>>>
>>> My personal preference is option 3).
>>
>> Or the 4th one, which is only an idea and I haven't yet verified:
>>
>> 4) Handle error from invalidate_inode_pages2()
>> Currently we just call invalidate_inode_pages2() on btree inode and
>> expect it to return 0.
>>
>> But if there is still an eb reading pending, it will make that
>> function to return -EBUSY, as try_release_extent_buffer() will
>> find a eb whose refs is not 0, and refuse the release that eb which
>> belongs to a folio.
>>
>> That should be a good indicator of any pending metadata reads.
>>
>> So if that invalidate_inode_pages2() returned -EBUSY, we should wait
>> retry until it returns 0.
>>
>>
>
> Thanks! Yes, it makes sense, simply waiting on the bio counter doesnt
> fix the problem here.
>
> Among the options, I prefer option 3. Although it may be slower, but it
> only happens in mount failure path so extra cost seems acceptable.
The problem is not limited to mount failure, but also affects
close_ctree() too.
As it shares the same root problem, we have nothing to trace nor wait
for any pending metadata read.
>
> I am quite new to btrfs codebase so I dont know whether
> `invalidate_inode_pages2()` would be a reliable solution so maybe I
> should start with option 3?
Sure. Although iterating through xarray may not be that simple either,
as you may still need to look into all kinds of extra locks/rcu lock
etc, and if you apply that to the callsite of close_ctree(), it may be a
much bigger problem, as we have a lot of more ebs compared to mount time.
You can even mix option 3 and 4, e.g. only after
invalidate_inode_pages2() failed with -EBUSY then switch to xarray
iteration.
This should greatly reduce the number of ebs that are still inside the
xarray, thus makes the iteration much faster.
next prev parent reply other threads:[~2026-03-30 21:48 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-29 6:31 Teng Liu
2026-03-29 7:03 ` Qu Wenruo
2026-03-29 17:23 ` Teng Liu
2026-03-29 22:06 ` Qu Wenruo
2026-03-29 22:21 ` Qu Wenruo
2026-03-30 18:00 ` Teng Liu
2026-03-30 21:48 ` Qu Wenruo [this message]
2026-03-30 22:14 ` 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=6564fe96-ead0-45d4-9655-cd14f13bdc9a@suse.com \
--to=wqu@suse.com \
--cc=27rabbitlt@gmail.com \
--cc=clm@fb.com \
--cc=dsterba@suse.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/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
all inboxes | Powered by JetHome®