]> git.hungrycats.org Git - linux/commitdiff
btrfs: stripe_alloc: relocate a queued stripe group even while it has reserved or...
authorZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Sun, 6 Sep 2026 05:14:31 +0000 (01:14 -0400)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Mon, 7 Sep 2026 06:20:56 +0000 (02:20 -0400)
The reclaim worker defers any group that has bytes reserved or pinned,
on the theory that it was queued for falling below the used threshold
and may be about to go empty on its own.  A stripe_alloc or stripe_meta
group is queued for the opposite reason -- free space trapped in
partially used stripes, which no amount of waiting frees -- and under
COW churn a metadata group has blocks reserved or pinned at every
moment, so the worker skipped every one of seven queued metadata
groups for the whole of a fill-to-the-edge test and relocated none.
Relocation already waits for in-flight allocations and writers on its
own; take the group.

Assisted-by: Claude:claude-fable-5
fs/btrfs/block-group.c

index 2de9d007456cb9ae038dada66d699f765a2b390b..71f5129f3f4fdc5e700d690bea77749e5d9f21df 100644 (file)
@@ -4297,12 +4297,21 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
 
                spin_lock(&space_info->lock);
                spin_lock(&bg->lock);
-               if (bg->reserved || bg->pinned || bg->ro) {
+               if (bg->ro ||
+                   ((bg->reserved || bg->pinned) &&
+                    !btrfs_is_stripe_alloc_bg(bg) &&
+                    !btrfs_is_stripe_meta_bg(bg))) {
                        /*
                         * We want to bail if we made new allocations or have
                         * outstanding allocations in this block group.  We do
                         * the ro check in case balance is currently acting on
                         * this block group.
+                        *
+                        * Not for a stripe_alloc or stripe_meta group: under
+                        * COW churn it always has blocks reserved or pinned,
+                        * so the bail-out would defer it forever, while the
+                        * trapped free space it was queued for only grows.
+                        * Relocation waits for in-flight allocations itself.
                         */
                        spin_unlock(&bg->lock);
                        spin_unlock(&space_info->lock);