aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.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/inode.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/inode.c')
-rw-r--r--fs/btrfs/inode.c12
1 files changed, 4 insertions, 8 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 6f030c299de8..4439fbb4ff45 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2127,17 +2127,13 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
2127 ins.type = BTRFS_EXTENT_ITEM_KEY; 2127 ins.type = BTRFS_EXTENT_ITEM_KEY;
2128 ret = btrfs_alloc_reserved_file_extent(trans, root, 2128 ret = btrfs_alloc_reserved_file_extent(trans, root,
2129 root->root_key.objectid, 2129 root->root_key.objectid,
2130 btrfs_ino(inode), file_pos, &ins); 2130 btrfs_ino(inode), file_pos,
2131 if (ret < 0) 2131 ram_bytes, &ins);
2132 goto out;
2133 /* 2132 /*
2134 * Release the reserved range from inode dirty range map, and 2133 * Release the reserved range from inode dirty range map, as it is
2135 * move it to delayed ref codes, as now accounting only happens at 2134 * already moved into delayed_ref_head
2136 * commit_transaction() time.
2137 */ 2135 */
2138 btrfs_qgroup_release_data(inode, file_pos, ram_bytes); 2136 btrfs_qgroup_release_data(inode, file_pos, ram_bytes);
2139 ret = btrfs_add_delayed_qgroup_reserve(root->fs_info, trans,
2140 root->objectid, disk_bytenr, ram_bytes);
2141out: 2137out:
2142 btrfs_free_path(path); 2138 btrfs_free_path(path);
2143 2139