The read-only guard keeps admitted bytes placeable by refusing to take a
group's usable free space out of the supply when the space_info could
not absorb it. With the whole-stripe reserve counted as used, that
refusal comes by the width of the reserve at the fill edge: two
eligible metadata groups sat marked for reclaim through a 300 second
wait and the worker dropped each on inc_block_group_ro() -- the
space_info was 7 MiB short of the check with 376 MiB of whole stripes
claimable, 352 MiB of them the reserve that exists for this move.
Going read-only is the first step of relocation, so let the guard draw
on the reserve the way relocation's own reservations do.
Assisted-by: Claude:claude-fable-5
if (READ_ONCE(cache->stripe_unusable_ready))
trapped = min(READ_ONCE(cache->stripe_unusable), num_bytes);
+ /*
+ * The stripe_meta reserve is the room a group's live blocks
+ * move into when it is relocated, and going read-only is the
+ * first step of exactly that: count the reserve as available
+ * here, or the guard refuses every relocation at the edge by
+ * the width of the reserve.
+ */
if (btrfs_can_overcommit(cache->fs_info, sinfo, num_bytes - trapped,
- BTRFS_RESERVE_NO_FLUSH, false))
+ BTRFS_RESERVE_NO_FLUSH, true))
ret = 0;
}