]> git.hungrycats.org Git - linux/commit
btrfs: add open stripe run tracking for stripe-exclusive allocation
authorZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Sat, 25 Jul 2026 04:01:17 +0000 (00:01 -0400)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Fri, 18 Sep 2026 21:36:20 +0000 (17:36 -0400)
commit6c2423d43e544eb7e0bbd33bace05936258b3198
tree31ceae6e7d4d252cdb2dd9c93c4646557de3b208
parent751bedf11ac5bea51b9ac141d3123100652ecc0b
btrfs: add open stripe run tracking for stripe-exclusive allocation

Add the in-memory state and lifecycle for "open stripe runs", the
allocation windows of the raid56 stripe-exclusive allocation policy.  A
run is a contiguous stripe-aligned region claimed whole from the free
space cache via btrfs_claim_free_stripe_run() and filled strictly
sequentially by btrfs_alloc_from_open_stripe().  A run closes when it is
exhausted, when an allocation does not fit its remainder, or when the
transaction commit retires it; closed runs are never reopened and their
unallocated tails return to the free space cache, where the fully-free
claim rule makes them unallocatable until the whole stripe frees.  This
is what will guarantee that a full stripe only receives writes within
one commit window, closing the raid56 write hole for these block groups.

Each run counts reserved bytes whose data IO has not completed yet,
maintained under the block group lock and reported back through
btrfs_open_stripe_write_done().  btrfs_retire_open_stripes() implements
commit-time retirement: bump the retire sequence, close every run opened
before it, and wait for their inflight bytes to drain.  It is a pure
data-IO wait, deliberately not an ordered extent wait: it is designed to
run after the committing transaction stops accepting joins
(TRANS_STATE_COMMIT_DOING with a single writer), where waiting for
ordered extent completion would deadlock on the blocked transaction
join, and where every extent the transaction references already has its
own data on disk.  Allocations racing with the commit open runs stamped
with a newer sequence and are neither retired nor waited for; their
extents can only be referenced by the next transaction.  Block groups
with runs are tracked on an fs_info list whose membership is
established before an allocation returns, which is what lets the retire
walk rely on the sequence stamp.

Exercised by a new sanity self-test; the raid56 stripe allocation
policy and the commit hook will be the first non-test users.

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