aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorQu Wenruo <quwenruo@cn.fujitsu.com>2015-10-26 02:11:18 -0400
committerChris Mason <clm@fb.com>2015-10-26 22:44:39 -0400
commit5846a3c26873e86b034c702a8bc202aa76082369 (patch)
tree8495bf1ae8236d363579751a63414ba31c498a0d /fs/btrfs/extent-tree.c
parent696249132158014d594896df3a81390616069c5c (diff)
btrfs: qgroup: Fix a race in delayed_ref which leads to abort trans
Between btrfs_allocerved_file_extent() and btrfs_add_delayed_qgroup_reserve(), there is a window that delayed_refs are run and delayed ref head maybe freed before btrfs_add_delayed_qgroup_reserve(). This will cause btrfs_dad_delayed_qgroup_reserve() to return -ENOENT, and cause transaction to be aborted. This patch will record qgroup reserve space info into delayed_ref_head at btrfs_add_delayed_ref(), to eliminate the race window. Reported-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index c1f8c7e27a6d..f50c7c2e2b59 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2087,8 +2087,8 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
2087 BTRFS_ADD_DELAYED_REF, NULL); 2087 BTRFS_ADD_DELAYED_REF, NULL);
2088 } else { 2088 } else {
2089 ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, 2089 ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
2090 num_bytes, 2090 num_bytes, parent, root_objectid,
2091 parent, root_objectid, owner, offset, 2091 owner, offset, 0,
2092 BTRFS_ADD_DELAYED_REF, NULL); 2092 BTRFS_ADD_DELAYED_REF, NULL);
2093 } 2093 }
2094 return ret; 2094 return ret;
@@ -6832,8 +6832,8 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root,
6832 ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, 6832 ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
6833 num_bytes, 6833 num_bytes,
6834 parent, root_objectid, owner, 6834 parent, root_objectid, owner,
6835 offset, BTRFS_DROP_DELAYED_REF, 6835 offset, 0,
6836 NULL); 6836 BTRFS_DROP_DELAYED_REF, NULL);
6837 } 6837 }
6838 return ret; 6838 return ret;
6839} 6839}
@@ -7759,7 +7759,8 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
7759int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans, 7759int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
7760 struct btrfs_root *root, 7760 struct btrfs_root *root,
7761 u64 root_objectid, u64 owner, 7761 u64 root_objectid, u64 owner,
7762 u64 offset, struct btrfs_key *ins) 7762 u64 offset, u64 ram_bytes,
7763 struct btrfs_key *ins)
7763{ 7764{
7764 int ret; 7765 int ret;
7765 7766
@@ -7768,7 +7769,8 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
7768 ret = btrfs_add_delayed_data_ref(root->fs_info, trans, ins->objectid, 7769 ret = btrfs_add_delayed_data_ref(root->fs_info, trans, ins->objectid,
7769 ins->offset, 0, 7770 ins->offset, 0,
7770 root_objectid, owner, offset, 7771 root_objectid, owner, offset,
7771 BTRFS_ADD_DELAYED_EXTENT, NULL); 7772 ram_bytes, BTRFS_ADD_DELAYED_EXTENT,
7773 NULL);
7772 return ret; 7774 return ret;
7773} 7775}
7774 7776