summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolay Borisov <nborisov@suse.com>2021-02-23 16:20:42 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-03-11 16:04:59 +0300
commitab28b0886498819816766c1f412443a9eecbd3c3 (patch)
tree87e7fee9a87abc9024bab4fffc7bbb27b78cf84a
parentdb1dde1bf1c98aa4a5c80ae453fd9c82fe032926 (diff)
downloadlinux-ab28b0886498819816766c1f412443a9eecbd3c3.tar.xz
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 <wqu@suse.com> Signed-off-by: Nikolay Borisov <nborisov@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/btrfs/file.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 646152f30584..a202f2f12b1c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -3016,8 +3016,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),