]> git.hungrycats.org Git - linux/commit
btrfs: stripe_alloc: admit data reservations by whole stripes
authorZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Fri, 11 Sep 2026 22:25:09 +0000 (18:25 -0400)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Fri, 18 Sep 2026 21:36:29 +0000 (17:36 -0400)
commit94d5cda6cdb7e72d46478c669130edffa587903b
tree272caa3cc94d4a3d586bdbfe77ca485d9c2e75fe
parent45c5aa6a46516ee69c6615565a6a128f518c35e1
btrfs: stripe_alloc: admit data reservations by whole stripes

An allocation of N bytes that has to open a stripe run claims
round_up(N, full stripe) whole stripes.  A delalloc write is admitted
with a full-stripe margin per outstanding extent, which covers that
roundup for itself, and relocation is admitted for round_up(N) + 1
stripe.  A preallocation was admitted for N alone: fallocate() has no
outstanding extent and holds no margin, so each one short of a stripe
took up to a stripe more from the whole-stripe supply than the gate had
charged.  The supply behind writes admitted earlier shrank by that much
and at the fill edge their claims found nothing.

With the stranded-stripe accounting and the relocation margin in place,
the failure-time dump on a degraded fsstress fill showed exactly this:
every failed write had bytes_stripe_claimable 0, bytes_may_use equal to
its own size, one stripe of margin per outstanding extent, nothing
stranded, no group read-only and no relocation group dedicated -- the
gate's arithmetic was consistent and still the stripes were gone, with
a preallocation's reservation in flight in the dump.

Charge every non-relocation admission the roundup to whole stripes.  The
excess is not held past admission (a preallocation allocates in the same
call), so a concurrent admission in that window can still overrun by a
stripe; holding it would need the reservation to carry the roundup until
the allocation lands, a later refinement.

Assisted-by: Claude:claude-fable-5
fs/btrfs/space-info.c