On 30.08.2018 20:42, Josef Bacik wrote:
> 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.
>
> Signed-off-by: Josef Bacik <jo...@toxicpanda.com>
Reviewed-by: Nikolay Borisov <nbori...@suse.com>
> ---
> fs/btrfs/extent-tree.c | 12 ++++--------
> 1 file changed, 4 insertions(+), 8 deletions(-)
>
> diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
> index 132a1157982c..fd9169f80de0 100644
> --- a/fs/btrfs/extent-tree.c
> +++ b/fs/btrfs/extent-tree.c
> @@ -2405,6 +2405,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;
> }
>
> @@ -8227,21 +8230,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;
> }
>
>