summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-07-01 12:48:28 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-07-01 12:48:28 -0700
commitcfbc0ffea88c764d23f69efe6ecb74918e0f588e (patch)
tree8e5bf6b50da3d7b60c57b61fc451a5f1c9e21200 /fs
parent9903efbddba0d14133b5a3c75088b558d2e34ac3 (diff)
parent48f091fd50b2eb33ae5eaea9ed3c4f81603acf38 (diff)
downloadlinux-stable-cfbc0ffea88c764d23f69efe6ecb74918e0f588e.tar.gz
linux-stable-cfbc0ffea88c764d23f69efe6ecb74918e0f588e.tar.bz2
linux-stable-cfbc0ffea88c764d23f69efe6ecb74918e0f588e.zip
Merge tag 'for-6.10-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fix from David Sterba: "A fixup for a recent fix that prevents an infinite loop during block group reclaim. Unfortunately it introduced an unsafe way of updating block group list and could race with relocation. This could be hit on fast devices when relocation/balance does not have enough space" * tag 'for-6.10-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: fix adding block group to a reclaim list and the unused list during reclaim
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/block-group.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 1a66be33bb04..60066822b532 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -1924,8 +1924,17 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
next:
if (ret) {
/* Refcount held by the reclaim_bgs list after splice. */
- btrfs_get_block_group(bg);
- list_add_tail(&bg->bg_list, &retry_list);
+ spin_lock(&fs_info->unused_bgs_lock);
+ /*
+ * This block group might be added to the unused list
+ * during the above process. Move it back to the
+ * reclaim list otherwise.
+ */
+ if (list_empty(&bg->bg_list)) {
+ btrfs_get_block_group(bg);
+ list_add_tail(&bg->bg_list, &retry_list);
+ }
+ spin_unlock(&fs_info->unused_bgs_lock);
}
btrfs_put_block_group(bg);