]> git.hungrycats.org Git - linux/commit
btrfs: stripe_meta: carry raid56 metadata groups through a runtime enable or disable
authorZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Wed, 16 Sep 2026 04:47:30 +0000 (00:47 -0400)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Fri, 18 Sep 2026 21:36:30 +0000 (17:36 -0400)
commitfdd90b17a5f6f34e8e340d67e99dc3d81a22a417
treedfbbec1d161b561acb09d7ef65e4c43762b59c96
parent9a607a2b5aeb84a10b74a0f6e95663ef92c8a541
btrfs: stripe_meta: carry raid56 metadata groups through a runtime enable or disable

The property path arms and disarms the trapped-space accounting of the
cached block groups, but stripe_alloc_sweep_groups() walked only DATA
space_infos: a runtime enable left already-cached raid56 metadata groups
unarmed until something else (a new chunk, a read-write transition)
initialised them, so their trapped and claimable bytes were missing from
metadata admission; a runtime disable left armed metadata groups' bytes
in the space_info after the option was gone.  Walk METADATA space_infos
too, for both directions.

Two more things a runtime toggle needs under raid56 metadata:

The metadata retirement at commit returned at once without the option,
so after a disable the running transaction's open metadata runs were
never closed or drained and their block group references were held
until unmount, where btrfs_free_block_groups() asserts on them.  Retire
unconditionally; the walk is over the list of groups with open runs and
is empty when there is nothing to do.

And the enable-time drain that keeps the write-hole check quiet until the
legacy allocator's writes have landed only waited for data (delalloc and
ordered extents).  Tree blocks the legacy allocator placed in the
transaction that was running at the flip are written by that
transaction's commit, into the partly used stripes they were allocated
in -- under raid56 metadata that commit is the last legacy
read-modify-write, and the metadata RMW reporter says so:

  read-modify-write of stripe 42860544 rewrites parity over committed
  tree block 42860544 at generation 10 ... while writing generation 11:
  write hole
  btrfs: sub-stripe write to stripe 42860544 (block group 34603008)
  outside any live stripe run: write hole window violated
  WARNING: CPU: 1 PID: 408294 at fs/btrfs/block-group.c:2889
  btrfs_stripe_check_write+0x109/0x150

Commit that transaction from the drain worker before arming the check.
The exposure of the enabling transaction itself is inherent -- its
blocks are already placed -- and bounded to that one commit.

Found by stripe-meta-toggle-test.sh (runtime enable with a fill to the
metadata edge, then a property-enabled filesystem disabled and
unmounted), on raid5 and raid6 metadata.

Assisted-by: Claude:claude-fable-5-1
fs/btrfs/block-group.c