]> 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>
Wed, 16 Sep 2026 21:40:05 +0000 (17:40 -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 ec66d61c0c4c450307eb3b2042e43a4c974c554b..8521c1ac8cf6681946529e3725f07f7065f1b9ec 100644 (file)
@@ -4362,12 +4362,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);