diff options
author | Qu Wenruo <quwenruo@cn.fujitsu.com> | 2015-10-26 02:11:18 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-10-26 22:44:39 -0400 |
commit | 5846a3c26873e86b034c702a8bc202aa76082369 (patch) | |
tree | 8495bf1ae8236d363579751a63414ba31c498a0d /fs/btrfs/inode.c | |
parent | 696249132158014d594896df3a81390616069c5c (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.c | 12 |
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); | ||
2141 | out: | 2137 | out: |
2142 | btrfs_free_path(path); | 2138 | btrfs_free_path(path); |
2143 | 2139 | ||