From a87911c26a1c98868f19642e324e863d81ca8cfd Mon Sep 17 00:00:00 2001 From: Nikolay Borisov Date: Tue, 23 Feb 2021 15:20:42 +0200 Subject: [PATCH] btrfs: unlock extents in btrfs_zero_range in case of quota reservation errors commit 4f6a49de64fd1b1dba5229c02047376da7cf24fd upstream. If btrfs_qgroup_reserve_data returns an error (i.e quota limit reached) the handling logic directly goes to the 'out' label without first unlocking the extent range between lockstart, lockend. This results in deadlocks as other processes try to lock the same extent. Fixes: a7f8b1c2ac21 ("btrfs: file: reserve qgroup space after the hole punch range is locked") CC: stable@vger.kernel.org # 5.10+ Reviewed-by: Qu Wenruo Signed-off-by: Nikolay Borisov Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/file.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 4126513e2429c..f8e5c47b95e40 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -3151,8 +3151,11 @@ reserve_space: goto out; ret = btrfs_qgroup_reserve_data(inode, &data_reserved, alloc_start, bytes_to_reserve); - if (ret) + if (ret) { + unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, + lockend, &cached_state); goto out; + } ret = btrfs_prealloc_file_range(inode, mode, alloc_start, alloc_end - alloc_start, i_blocksize(inode), -- 2.47.3