Skip to content

Commit a6d8654

Browse files
fdmananakdave
authored andcommitted
Btrfs: fix deadlock when using free space tree due to block group creation
When modifying the free space tree we can end up COWing one of its extent buffers which in turn might result in allocating a new chunk, which in turn can result in flushing (finish creation) of pending block groups. If that happens we can deadlock because creating a pending block group needs to update the free space tree, and if any of the updates tries to modify the same extent buffer that we are COWing, we end up in a deadlock since we try to write lock twice the same extent buffer. So fix this by skipping pending block group creation if we are COWing an extent buffer from the free space tree. This is a case missed by commit 5ce5555 ("Btrfs: fix deadlock when writing out free space caches"). Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202173 Fixes: 5ce5555 ("Btrfs: fix deadlock when writing out free space caches") CC: stable@vger.kernel.org # 4.18+ Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent d8b5524 commit a6d8654

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

fs/btrfs/ctree.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,19 +1016,21 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
10161016
parent_start = parent->start;
10171017

10181018
/*
1019-
* If we are COWing a node/leaf from the extent, chunk or device trees,
1020-
* make sure that we do not finish block group creation of pending block
1021-
* groups. We do this to avoid a deadlock.
1019+
* If we are COWing a node/leaf from the extent, chunk, device or free
1020+
* space trees, make sure that we do not finish block group creation of
1021+
* pending block groups. We do this to avoid a deadlock.
10221022
* COWing can result in allocation of a new chunk, and flushing pending
10231023
* block groups (btrfs_create_pending_block_groups()) can be triggered
10241024
* when finishing allocation of a new chunk. Creation of a pending block
1025-
* group modifies the extent, chunk and device trees, therefore we could
1026-
* deadlock with ourselves since we are holding a lock on an extent
1027-
* buffer that btrfs_create_pending_block_groups() may try to COW later.
1025+
* group modifies the extent, chunk, device and free space trees,
1026+
* therefore we could deadlock with ourselves since we are holding a
1027+
* lock on an extent buffer that btrfs_create_pending_block_groups() may
1028+
* try to COW later.
10281029
*/
10291030
if (root == fs_info->extent_root ||
10301031
root == fs_info->chunk_root ||
1031-
root == fs_info->dev_root)
1032+
root == fs_info->dev_root ||
1033+
root == fs_info->free_space_root)
10321034
trans->can_flush_pending_bgs = false;
10331035

10341036
cow = btrfs_alloc_tree_block(trans, root, parent_start,

0 commit comments

Comments
 (0)