]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: delete unused BGs while reclaiming BGs
authorNaohiro Aota <naota@elisp.net>
Tue, 6 Jun 2023 05:36:33 +0000 (14:36 +0900)
committerDavid Sterba <dsterba@suse.com>
Mon, 19 Jun 2023 11:59:37 +0000 (13:59 +0200)
The reclaiming process only starts after the filesystem volumes are
allocated to a certain level (75% by default). Thus, the list of
reclaiming target block groups can build up so huge at the time the
reclaim process kicks in. On a test run, there were over 1000 BGs in the
reclaim list.

As the reclaim involves rewriting the data, it takes really long time to
reclaim the BGs. While the reclaim is running, btrfs_delete_unused_bgs()
won't proceed because the reclaim side is holding
fs_info->reclaim_bgs_lock. As a result, we will have a large number of
unused BGs kept in the unused list. On my test run, I got 1057 unused BGs.

Since deleting a block group is relatively easy and fast work, we can call
btrfs_delete_unused_bgs() while it reclaims BGs, to avoid building up
unused BGs.

Fixes: 18bb8bbf13c1 ("btrfs: zoned: automatically reclaim zones")
CC: stable@vger.kernel.org # 5.15+
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/block-group.c

index 618ba7670e66d982b5bd8584efbe5f98bb2aece3..18305f5c74c9318279d965a302b5f4279aa881d2 100644 (file)
@@ -1824,10 +1824,24 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
 
 next:
                btrfs_put_block_group(bg);
+
+               mutex_unlock(&fs_info->reclaim_bgs_lock);
+               /*
+                * Reclaiming all the block groups in the list can take really
+                * long.  Prioritize cleaning up unused block groups.
+                */
+               btrfs_delete_unused_bgs(fs_info);
+               /*
+                * If we are interrupted by a balance, we can just bail out. The
+                * cleaner thread restart again if necessary.
+                */
+               if (!mutex_trylock(&fs_info->reclaim_bgs_lock))
+                       goto end;
                spin_lock(&fs_info->unused_bgs_lock);
        }
        spin_unlock(&fs_info->unused_bgs_lock);
        mutex_unlock(&fs_info->reclaim_bgs_lock);
+end:
        btrfs_exclop_finish(fs_info);
        sb_end_write(fs_info->sb);
 }