btrfs: fix insert_reserved error handling
We were not handling the reserved byte accounting properly for data references. Metadata was fine, if it errored out the error paths would free the bytes_reserved count and pin the extent, but it even missed one of the error cases. So instead move this handling up into run_one_delayed_ref so we are sure that both cases are properly cleaned up in case of a transaction abort. CC: stable@vger.kernel.org # 4.18+ Reviewed-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
49940bdd57
commit
80ee54bfe8
|
@ -2366,6 +2366,9 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
|
|||
insert_reserved);
|
||||
else
|
||||
BUG();
|
||||
if (ret && insert_reserved)
|
||||
btrfs_pin_extent(trans->fs_info, node->bytenr,
|
||||
node->num_bytes, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -8004,21 +8007,14 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
|
|||
}
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path) {
|
||||
btrfs_free_and_pin_reserved_extent(fs_info,
|
||||
extent_key.objectid,
|
||||
fs_info->nodesize);
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
path->leave_spinning = 1;
|
||||
ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path,
|
||||
&extent_key, size);
|
||||
if (ret) {
|
||||
btrfs_free_path(path);
|
||||
btrfs_free_and_pin_reserved_extent(fs_info,
|
||||
extent_key.objectid,
|
||||
fs_info->nodesize);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue