]> git.hungrycats.org Git - linux/commit
btrfs: stripe_alloc: drain the legacy allocator's writes before arming the write...
authorZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Sat, 12 Sep 2026 21:22:55 +0000 (17:22 -0400)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Wed, 16 Sep 2026 21:40:05 +0000 (17:40 -0400)
commitfc42dafa6085a50b96a4f2755d91c1d477c64ba4
tree6f876faa19f65f7345ec27b840eee2e1357f5849
parenta8bbf889b9627ec597686ce3f4703dcc02a18681
btrfs: stripe_alloc: drain the legacy allocator's writes before arming the write-hole check at a runtime enable

Enabling stripe_alloc on a live filesystem (the btrfs.stripe_alloc property)
flips the mount option while the legacy allocator may still have writes in
flight.  Those extents sit in partly used stripes that no stripe run covers,
so the first of them to reach rmw_rbio() after the flip trips
btrfs_stripe_check_write()'s "write to stripe outside any live stripe run"
WARN_ONCE and taints the kernel, although nothing violated the policy: the
data was placed before the policy existed.  punch-hole-warn-repro.sh hits it
on the switch when its killed writers still have dirty data (bhive, 7.3-rc2
lane, 2026-09-12); the same code on 6.18 escaped only by timing.

Keep the check off from the flip until every ordered extent that could have
been allocated before it has completed.  The property is applied inside a
transaction, where flushing delalloc cannot wait, so the drain runs in a
worker: start delalloc on all roots, wait for all ordered extents, clear the
flag.  Extents allocated after the flip have stripe runs and are unaffected;
a mount-time enable (the root directory's property) has nothing in flight and
does not queue the drain.  close_ctree() flushes the worker so it cannot
outlive the filesystem.

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