public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: robbieko <robbieko@synology.com>,
	Johannes Thumshirn <johannes.thumshirn@wdc.com>,
	David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>,
	clm@fb.com, linux-btrfs@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 7.0-6.18] btrfs: fix wrong min_objectid in btrfs_previous_item() call
Date: Tue,  5 May 2026 05:51:39 -0400	[thread overview]
Message-ID: <20260505095149.512052-23-sashal@kernel.org> (raw)
In-Reply-To: <20260505095149.512052-1-sashal@kernel.org>

From: robbieko <robbieko@synology.com>

[ Upstream commit 1871ae78ffa5ce7c0458e9ba5867958c1753e425 ]

When found_start > start and slot == 0, btrfs_previous_item() is called
with min_objectid=start to find the previous stripe extent. However, the
previous stripe extent we are looking for has objectid < start (it starts
before our deletion range), so passing start as min_objectid prevents
finding it.

Fix by passing 0 as min_objectid to allow finding any preceding stripe
extent regardless of its objectid.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: robbieko <robbieko@synology.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit Message Forensics
Record 1.1: Subsystem `btrfs`; action verb `fix`; claimed intent is
correcting the `min_objectid` argument to `btrfs_previous_item()` in the
RAID stripe-tree deletion path.

Record 1.2: Tags found: `Reviewed-by: Johannes Thumshirn
<johannes.thumshirn@wdc.com>`, `Signed-off-by: robbieko
<robbieko@synology.com>`, `Reviewed-by: David Sterba
<dsterba@suse.com>`, `Signed-off-by: David Sterba <dsterba@suse.com>`.
No `Fixes:`, `Reported-by:`, `Tested-by:`, `Link:`, or `Cc:
stable@vger.kernel.org` tags were present.

Record 1.3: The commit describes a real lookup bug: when `found_start >
start` and `slot == 0`, the code tries to find the previous RAID stripe
extent, but passes `min_objectid=start`. `btrfs_previous_item()` stops
when it sees an item with `objectid < min_objectid`, so it cannot return
the previous extent that starts before `start`.

Record 1.4: This is not hidden cleanup. It is an explicit
logic/correctness fix for a failed previous-item lookup.

## Phase 2: Diff Analysis
Record 2.1: One file changed: `fs/btrfs/raid-stripe-tree.c`, 1 insertion
and 1 deletion. Modified function: `btrfs_delete_raid_extent()`. Scope:
single-file, one-line surgical fix.

Record 2.2: Before: `btrfs_previous_item(stripe_root, path, start,
BTRFS_RAID_STRIPE_KEY)` would reject any candidate with `objectid <
start`. After: `min_objectid=0` allows searching back to earlier stripe
extents.

Record 2.3: Bug category: logic/correctness bug in B-tree item lookup.
Mechanism verified in `btrfs_previous_item()`: it breaks when
`found_key.objectid < min_objectid` before returning a matching type, so
`min_objectid=start` prevents the intended previous extent from being
found.

Record 2.4: Fix quality is high: one argument change, no API changes, no
new feature. Regression risk is low, but not zero: the same series has
the immediately following patch `653361585d251` adding a proper overlap
check after this fallback, so stable backports should consider the
surrounding RAID stripe-tree deletion fixes too.

## Phase 3: Git History Investigation
Record 3.1: `git blame` shows the buggy call was introduced by
`76643119045ee` (`btrfs: fix deletion of a range spanning parts two RAID
stripe extents`), first contained around `v6.14-rc1`. The broader RAID
stripe tree code was introduced by `ca41504efda6`, first contained
around `v6.7-rc1`.

Record 3.2: No `Fixes:` tag is present, so there was no tag target to
follow.

Record 3.3: Recent file history shows this commit is patch 3 in a six-
patch RAID stripe-tree deletion bugfix series: `513f8a52eed88`,
`2aef5cb1dcf9b`, `1871ae78ffa5c`, `653361585d251`, `fe0cdfd7118d8`, and
`a8d58a7c02009`. This commit applies standalone to `v7.0.3`, but it is
part of a related correctness series.

Record 3.4: Author `robbieko` had several same-day Btrfs RAID stripe-
tree fixes in `fs/btrfs`. Committer/reviewer David Sterba is the Btrfs
maintainer.

Record 3.5: No hard prerequisite is needed for this one-line change to
apply. `git apply --check` against the current `stable/linux-7.0.y`
checkout succeeded. Semantic companion patches exist and should be
considered, especially the next ASSERT-to-error-handling fix.

## Phase 4: Mailing List And External Research
Record 4.1: `b4 dig -c 1871ae78ffa5c` found the original submission at `
https://patch.msgid.link/20260413065249.2320122-4-
robbieko@synology.com`, titled `[PATCH 3/6] btrfs: fix wrong
min_objectid in btrfs_previous_item() call`.

Record 4.2: `b4 dig -w` showed original recipients: `robbieko
<robbieko@synology.com>` and `linux-btrfs@vger.kernel.org`. The mbox
shows Johannes Thumshirn reviewed patch 3 with “Looks good” and
`Reviewed-by`.

Record 4.3: No external bug report, syzbot report, or user report was
linked.

Record 4.4: The cover letter says the series fixes six bugs in
`fs/btrfs/raid-stripe-tree.c`, all in stripe extent deletion and partial
deletion paths. Patch 3 is specifically this wrong `min_objectid` fix.

Record 4.5: `WebFetch` for lore and stable searches was blocked by
Anubis. Local `b4` mbox inspection found no stable-specific nomination
or objection.

## Phase 5: Code Semantic Analysis
Record 5.1: Modified function: `btrfs_delete_raid_extent()`.

Record 5.2: Verified callers: production caller is
`do_free_extent_accounting()` in `fs/btrfs/extent-tree.c`; tests also
call it from `fs/btrfs/tests/raid-stripe-tree-tests.c`.

Record 5.3: Key callees include `btrfs_search_slot()`,
`btrfs_previous_item()`, `btrfs_partially_delete_raid_extent()`, and
`btrfs_del_item()`. The affected path is the stripe extent deletion path
for Btrfs RAID stripe tree.

Record 5.4: Verified call chain: `__btrfs_free_extent()` calls
`do_free_extent_accounting()` when data extent refs drop to zero; that
calls `btrfs_delete_raid_extent()`. If `btrfs_delete_raid_extent()`
returns an error, `do_free_extent_accounting()` aborts the transaction.
I did not fully trace from VFS syscall entry, so unprivileged
triggerability is not relied on for the decision.

Record 5.5: Similar nearby bugfixes were found in the same series,
indicating this area had multiple deletion-path correctness bugs.

## Phase 6: Stable Tree Analysis
Record 6.1: The buggy `btrfs_previous_item(..., start, ...)` call exists
in release tags `v6.14`, `v6.14.11`, `v6.15`, `v6.15.11`, `v6.16`,
`v6.17`, `v6.18`, `v6.19`, `v7.0`, and current `v7.0.3`. It is absent
from `v6.13`, `v6.12`, `v6.6`, and `v6.1`.

Record 6.2: Backport difficulty is low for `v7.0.3`; `git apply --check`
succeeded. Older affected stable trees likely need only minor context
adjustment if their surrounding code differs.

Record 6.3: I did not find an alternate already-applied fix in the
checked release tags; `master` contains the corrected `min_objectid=0`
call.

## Phase 7: Subsystem And Maintainer Context
Record 7.1: Subsystem: Btrfs filesystem, specifically RAID stripe-tree
support. Criticality: important but feature-specific, not universal.

Record 7.2: `fs/btrfs` is actively maintained. Recent history shows
multiple April 2026 Btrfs fixes and the RAID stripe-tree deletion series
merged by David Sterba.

## Phase 8: Impact And Risk
Record 8.1: Affected users are Btrfs users with the `RAID_STRIPE_TREE`
incompat feature enabled and data block group profiles covered by
`BTRFS_RST_SUPP_BLOCK_GROUP_MASK` (`DUP`, `RAID0`, `RAID1` variants,
`RAID10`).

Record 8.2: Trigger condition is freeing/deleting a data extent range
that spans stripe extents where the next found stripe extent is at slot
0 and the needed previous stripe extent starts before `start`. Verified
from code flow; frequency in real workloads is not quantified.

Record 8.3: Failure mode: the old code can fail to find the needed
previous stripe extent, return `-ENOENT`, and cause
`do_free_extent_accounting()` to abort the transaction. Severity: high
for affected filesystems, because transaction abort is a serious
filesystem failure.

Record 8.4: Benefit is high for affected Btrfs RAID stripe-tree users.
Risk is low: one-line contained fix, reviewed by Btrfs developers, no
API change. Main concern is that this is part of a six-patch correctness
series, so stable maintainers should evaluate adjacent fixes as well.

## Phase 9: Final Synthesis
Record 9.1: Evidence for backporting: real Btrfs deletion-path bug;
verified wrong argument against `btrfs_previous_item()` semantics; bug
exists in `v6.14+` release lines; failure can abort Btrfs transactions;
fix is one line and reviewed by Johannes Thumshirn and David Sterba.
Evidence against: no reported user/syzbot case and feature-specific
impact; companion patches in same area should be considered. Unresolved:
exact real-world frequency and exact backport conflicts for every
affected stable branch were not fully checked.

Record 9.2 stable rules: obviously correct: yes, verified by code
semantics and reviews. Fixes a real bug: yes, incorrect lookup bound.
Important issue: yes for affected Btrfs filesystems, because it can
abort transactions. Small and contained: yes, one line in one function.
No new features/APIs: yes. Applies to stable: verified clean on current
`v7.0.3`; likely low difficulty for affected `v6.14+`.

Record 9.3: No exception category applies; this is a filesystem bug fix,
not a device ID, quirk, DT, build, or documentation change.

Record 9.4: Decision: backport. The patch is small, technically
justified, and fixes a serious correctness problem in a stable-visible
Btrfs feature. Prefer reviewing/backporting the surrounding RAID stripe-
tree deletion fixes too, but this commit itself is stable material.

## Verification
- Phase 1: Parsed commit `1871ae78ffa5c`; confirmed tags and absence of
  `Fixes:`, `Reported-by:`, `Tested-by`, `Link`, and stable Cc.
- Phase 2: Inspected diff; confirmed exactly 1-line argument change in
  `btrfs_delete_raid_extent()`.
- Phase 2: Read `btrfs_previous_item()`; confirmed it stops once
  `found_key.objectid < min_objectid`.
- Phase 3: Ran `git blame`; confirmed buggy call introduced by
  `76643119045ee`.
- Phase 3: Ran `git describe --contains`; confirmed `76643119045ee` is
  first contained around `v6.14-rc1`.
- Phase 3: Reviewed recent file history; confirmed this commit is part
  of a six-patch RAID stripe-tree deletion fix series.
- Phase 3: Ran `git apply --check`; confirmed the patch applies to
  current `v7.0.3` checkout.
- Phase 4: Ran `b4 dig -c`, `-a`, and `-w`; confirmed lore message ID,
  series context, and original recipients.
- Phase 4: Saved/read the `b4` mbox; confirmed cover letter says six
  bugs are fixed and patch 3 fixes this `min_objectid` issue.
- Phase 4: Read mbox reply; confirmed Johannes Thumshirn gave `Reviewed-
  by` for patch 3.
- Phase 4: `WebFetch` to lore/stable was blocked by Anubis; no web-
  search result was used as evidence.
- Phase 5: Searched callers; confirmed production caller path through
  `do_free_extent_accounting()` and tests.
- Phase 5: Read `do_free_extent_accounting()`; confirmed nonzero return
  from `btrfs_delete_raid_extent()` aborts the transaction.
- Phase 6: Checked release tags; confirmed buggy code exists in `v6.14+`
  through `v7.0.3`, absent in `v6.13`, `v6.12`, `v6.6`, and `v6.1`.
- Phase 7: Reviewed `fs/btrfs` recent history; confirmed active
  subsystem and maintainer merge context.
- Phase 8: Read `btrfs_need_stripe_tree_update()`; confirmed affected
  configurations are RAID stripe-tree data block groups with supported
  profiles.
- UNVERIFIED: Exact real-world frequency of the trigger.
- UNVERIFIED: Full VFS syscall-to-trigger trace and unprivileged
  triggerability.
- UNVERIFIED: Clean application to every affected stable branch older
  than current `v7.0.3`.

**YES**

 fs/btrfs/raid-stripe-tree.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c
index 2987cb7c686ea..d2b8995febec9 100644
--- a/fs/btrfs/raid-stripe-tree.c
+++ b/fs/btrfs/raid-stripe-tree.c
@@ -123,7 +123,7 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, u64 le
 		 */
 		if (found_start > start) {
 			if (slot == 0) {
-				ret = btrfs_previous_item(stripe_root, path, start,
+				ret = btrfs_previous_item(stripe_root, path, 0,
 							  BTRFS_RAID_STRIPE_KEY);
 				if (ret) {
 					if (ret > 0)
-- 
2.53.0


  parent reply	other threads:[~2026-05-05  9:53 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-05  9:51 [PATCH AUTOSEL 7.0-5.10] ALSA: hda: Avoid WARN_ON() for HDMI chmap slot checks Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.1] nvmet-tcp: check INIT_FAILED before nvmet_req_uninit in digest error path Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0] drm/amd/pm: Update emit clock logic Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0] smb: client: change allocation requirements in smb2_compound_op Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.18] btrfs: handle -EAGAIN from btrfs_duplicate_item and refresh stale leaf pointer Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-5.10] nvme: add missing MODULE_ALIAS for fabrics transports Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0] dpll: export __dpll_pin_change_ntf() for use under dpll_lock Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-5.10] nvme-core: fix parameter name in comment Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-5.10] nvme: add quirk NVME_QUIRK_IGNORE_DEV_SUBNQN for 144d:a808 (Samsung PM981/983/970 EVO Plus ) Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0] ASoC: spacemit: move hw constraints from hw_params to startup Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-5.10] ALSA: usb-audio: apply quirk for Playstation PDP Riffmaster Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.18] nvmet-tcp: Don't clear tls_key when freeing sq Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-5.10] rculist: add list_splice_rcu() for private lists Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0] ALSA: hda/realtek: enable mute LED support on ThinkBook 16p Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.18] mailbox: cix: Add IRQF_NO_SUSPEND to mailbox interrupt Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.12] ASoC: codecs: wcd937x: fix AUX PA sequencing and mixer controls Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.18] btrfs: replace ASSERT with proper error handling in stripe lookup fallback Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-5.10] btrfs: handle unexpected free-space-tree key types Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.18] md/raid5: Fix UAF on IO across the reshape position Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.6] btrfs: apply first key check for readahead when possible Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.6] ASoC: aw88395: Fix kernel panic caused by invalid GPIO error pointer Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.12] nvme-tcp: teardown circular locking fixes Sasha Levin
2026-05-05  9:51 ` Sasha Levin [this message]
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.18] btrfs: check return value of btrfs_partially_delete_raid_extent() Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.18] btrfs: fix raid stripe search missing entries at leaf boundaries Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.18] btrfs: copy devid in btrfs_partially_delete_raid_extent() Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0-6.18] nvme-multipath: put module reference when delayed removal work is canceled Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0] btrfs: abort transaction in do_remap_reloc_trans() on failure Sasha Levin
2026-05-05  9:51 ` [PATCH AUTOSEL 7.0] drm/amdkfd: check if vm ready in svm map and unmap to gpu Sasha Levin

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=20260505095149.512052-23-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=clm@fb.com \
    --cc=dsterba@suse.com \
    --cc=johannes.thumshirn@wdc.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=robbieko@synology.com \
    --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