From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 0/2] btrfs: de-couple subpage locked and delalloc range
Date: Mon, 16 Sep 2024 08:41:28 +0930 [thread overview]
Message-ID: <cover.1726441226.git.wqu@suse.com> (raw)
Since commit d034cdb4cc8a ("btrfs: lock subpage ranges in one go for
writepage_delalloc()") btrfs uses subpage locked bitmap to trace all the
locked delalloc ranges, and that commits provides the basis for mixing
async and non-async submission inside the same page.
But that locked bitmap is not a perfect match to trace delalloc ranges,
as we can have the following case: (64K page size)
0 32K 64K 96K 128K
| |////////||///////| |////|
120K
In above case, writepage_delalloc() for page 0 will find
and lock the delalloc range [32K, 96K), which is beyond the page
boundary.
Then when writepage_delalloc() is called for the page 64K, since [64K,
96K) is already locked, only [120K, 128K) will be locked.
This means, although range [64K, 96K) is dirty and will be submitted
later by extent_writepage_io(), it will not be marked as locked.
This is fine for now, as we call btrfs_folio_end_writer_lock_bitmap() to
free every non-compressed sector, and compression is only allowed for
full page range.
But this is not safe for future sector perfect compression support, as
this can lead to double folio unlock, if [32K, 96K) is submitted without
compression but [120K, 128K) is.
Thread A | Thread B
---------------------------------------+--------------------------------
| submit_one_async_extent()
| |- extent_clear_unlock_delalloc()
extent_writepage() | |- btrfs_folio_end_writer_lock()
|- btrfs_folio_edn_writer_lock_bitmap()| |- btrfs_subpage_end_and_test_writer()
| | | |- atomic_sub_and_test()
| | | /* Now the atomic value is 0 */
|- if (atomic_read() == 0) | |
|- folio_unlock() | |- folio_unlock()
The root cause is the above range [64K, 96K) is dirtied and should also
be locked but it isn't.
So to make everything more consistent and prepare for the incoming
sector perfect compression, mark all dirty sectors as locked.
The first patch is to introduce a new bitmap locally inside
writepage_delalloc().
The second patch is to fully de-couple locked bitmap from delalloc
range, and lock all dirty sectors.
Qu Wenruo (2):
btrfs: move the delalloc range bitmap search into extent_io.c
btrfs: mark all dirty sectors as locked inside writepage_delalloc()
fs/btrfs/extent_io.c | 54 ++++++++++++++++++++++++++++++++++++++++----
fs/btrfs/subpage.c | 47 --------------------------------------
fs/btrfs/subpage.h | 4 ----
3 files changed, 50 insertions(+), 55 deletions(-)
--
2.46.0
next reply other threads:[~2024-09-15 23:12 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-15 23:11 Qu Wenruo [this message]
2024-09-15 23:11 ` [PATCH 1/2] btrfs: move the delalloc range bitmap search into extent_io.c Qu Wenruo
2024-09-15 23:11 ` [PATCH 2/2] btrfs: mark all dirty sectors as locked inside writepage_delalloc() 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=cover.1726441226.git.wqu@suse.com \
--to=wqu@suse.com \
--cc=linux-btrfs@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 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.