btrfs: stripe_meta: allocate tree blocks by whole stripes
Metadata gets the placement rule data already has: tree blocks are handed
out from runs of fully free stripes, and a stripe is never revisited once
the transaction that filled it has written it. No separate mount option: the
chunk profile already decides it. raid56 metadata has the same write hole
as raid56 data, so it gets the same protection at the same time, and
metadata on any other profile has no write hole to close -- the policy's
RAID56_MASK test simply does not match it, so nothing changes there.
It does cost a stranded stripe tail per commit, and a metadata allocation
that fails aborts the transaction rather than failing one write. Those
are the price of covering raid56 metadata at all rather than a reason to
make it opt-in separately: a filesystem unwilling to pay them does not
want raid56 metadata, and converting it to raid1c3/raid1c4 removes both
the cost and the write hole.
Only system chunks are left uncovered: btrfs_is_stripe_meta_bg() tests the
METADATA flag and a system chunk does not carry it, so a raid56 system
chunk keeps the legacy read-modify-write. The mount-time warning is
narrowed to say exactly that instead of claiming metadata is uncovered,
which it no longer is.
The machinery is the data machinery, including the per-sector liveness
map the previous patch gave it. Metadata needed three things of its own:
- A completion report. A run drains when every byte allocated from it
has been accounted for, and metadata had no equivalent of ordered
extent completion, so its runs could never drain -- the deadlock that
mixed block groups hit. end_bbio_meta_write() now reports, and
btrfs_open_stripe_write_abandoned() covers a tree block freed before
it was ever written (COWed twice in one transaction, say).
- A two-phase closure. btrfs_retire_open_stripes() runs before the
commit writes tree blocks, so it skips metadata runs; they are closed
and drained afterwards by btrfs_retire_meta_stripes(), once every block
is on disk. Closing earlier would strand blocks the commit has not
allocated yet, draining earlier would wait for writes it has not
issued. Metadata runs are also freed there rather than when their
counter reaches zero: a stripe's columns can be written by separate
rbios, and freeing on the first completion leaves the second with no
run to pad or merge against.
- Whole stripes per writeback pass. The opportunistic writeback passes
do not know about stripes and will happily write three tree blocks now
and five later; btrfs_defer_stripe_meta_write() leaves the blocks
dirty for the commit (or a WB_SYNC_ALL waiter) instead, the same shape
as the zoned write-pointer deferral.
Two free paths bypass the usual completion reporting and must report the
block abandoned themselves: btrfs_free_tree_block() can send a
same-transaction unwritten block through the delayed-ref machinery when
check_ref_cleanup() finds its ref head already processed, and
clean_log_buffer() discards unwritten log tree blocks via
btrfs_pin_reserved_extent() without ever visiting btrfs_free_tree_block().
Either miss leaves the block counted as inflight forever: the run never
drains, the block group reference never drops, and unmount asserts. Both
were found by the dm-log-writes replay matrix, whose crash-recovery mounts
exercise both paths routinely.