diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-01 12:48:28 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-01 12:48:28 -0700 |
commit | cfbc0ffea88c764d23f69efe6ecb74918e0f588e (patch) | |
tree | 8e5bf6b50da3d7b60c57b61fc451a5f1c9e21200 | |
parent | 9903efbddba0d14133b5a3c75088b558d2e34ac3 (diff) | |
parent | 48f091fd50b2eb33ae5eaea9ed3c4f81603acf38 (diff) | |
download | linux-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
-rw-r--r-- | fs/btrfs/block-group.c | 13 |
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); |