mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Joseph Qi <joseph.qi@linux.alibaba.com>
To: Sasha Levin <sashal@kernel.org>, David Sterba <dsterba@suse.com>
Cc: Chris Mason <mason@kernel.org>,
	stable@vger.kernel.org, linux-btrfs@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Joseph Qi <joseph.qi@linux.alibaba.com>
Subject: [PATCH 6.6.y] btrfs: fix unfinished ordered extent when cow_file_range() fails
Date: Mon,  9 Nov 2026 20:47:50 +0800	[thread overview]
Message-ID: <20261109124750.64205-1-joseph.qi@linux.alibaba.com> (raw)

Commit 4ace6fb49c8b ("btrfs: do proper folio cleanup when cow_file_range()
failed") moved the extent and folio unlock out of the allocation loop.
The per-iteration PAGE_SET_ORDERED went with it, and the replacement
after the loop only runs on success, so the range that already has
ordered extents is now cleaned up with PAGE_UNLOCK, PAGE_START_WRITEBACK
and PAGE_END_WRITEBACK only.

Upstream can do that because btrfs_run_delalloc_range() passes NULL to
btrfs_cleanup_ordered_extents(), which then accounts the whole range
without consulting any page bit.  Where that function still takes
@locked_page it skips it instead, leaving its share of the ordered
extent to the caller, which finishes it through
btrfs_mark_ordered_io_finished() with the page argument.
can_finish_ordered_extent() returns early when the Ordered bit is not
set, so that share is never accounted and bytes_left never reaches zero.
btrfs_wait_ordered_range() then waits forever, and a later write to the
same offset can reach the -EEXIST btrfs_panic() in
insert_ordered_extent().

Both callers that rely on this are affected: __extent_writepage(), and
submit_uncompressed_range(), the compression fallback, which reaches
cow_file_range() through run_delalloc_cow().

Set PAGE_SET_ORDERED again for that range.  The cleanup still skips
@locked_page and accounts the rest with a NULL page, so the two ranges
do not overlap and nothing is accounted twice.

Upstream fixed this differently, in "btrfs: fix double accounting race
when btrfs_run_delalloc_range() failed", which is earlier in the same
series.  That commit depends on the writepage_delalloc() rework and the
folio conversion of extent_io.c, so restore the flag here instead.

Fixes: 4ace6fb49c8b ("btrfs: do proper folio cleanup when cow_file_range() failed")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
---
 fs/btrfs/inode.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index c8034d86f844f..a40201596b80f 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1532,10 +1532,16 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
 	 *
 	 * So here we only clear EXTENT_LOCKED and EXTENT_DELALLOC flag, and
 	 * finish the writeback of the involved folios, which will be never submitted.
+	 *
+	 * PAGE_SET_ORDERED is still needed here:
+	 * btrfs_cleanup_ordered_extents() skips @locked_page and leaves
+	 * its share of the ordered extent to the caller, which can only
+	 * account for it while the Ordered bit is set.
 	 */
 	if (orig_start < start) {
 		clear_bits = EXTENT_LOCKED | EXTENT_DELALLOC;
-		page_ops = PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK;
+		page_ops = PAGE_UNLOCK | PAGE_SET_ORDERED |
+			   PAGE_START_WRITEBACK | PAGE_END_WRITEBACK;
 
 		if (!locked_page)
 			mapping_set_error(inode->vfs_inode.i_mapping, ret);
-- 
2.39.3


                 reply	other threads:[~2026-11-09 12:47 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20261109124750.64205-1-joseph.qi@linux.alibaba.com \
    --to=joseph.qi@linux.alibaba.com \
    --cc=dsterba@suse.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mason@kernel.org \
    --cc=sashal@kernel.org \
    --cc=stable@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®