Commit ace68bac authored by Liu Bo's avatar Liu Bo Committed by Josef Bacik

Btrfs: return free space in cow error path

Replace some BUG_ONs with proper handling and take allocated space back to
free space cache for later use.

We don't have to worry about extent maps since they'd be freed in releasepage
path.
Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
parent 6463fe58
...@@ -920,7 +920,8 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans, ...@@ -920,7 +920,8 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
} }
em = alloc_extent_map(); em = alloc_extent_map();
BUG_ON(!em); /* -ENOMEM */ if (!em)
goto out_reserve;
em->start = start; em->start = start;
em->orig_start = em->start; em->orig_start = em->start;
ram_size = ins.offset; ram_size = ins.offset;
...@@ -947,11 +948,14 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans, ...@@ -947,11 +948,14 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
btrfs_drop_extent_cache(inode, start, btrfs_drop_extent_cache(inode, start,
start + ram_size - 1, 0); start + ram_size - 1, 0);
} }
if (ret)
goto out_reserve;
cur_alloc_size = ins.offset; cur_alloc_size = ins.offset;
ret = btrfs_add_ordered_extent(inode, start, ins.objectid, ret = btrfs_add_ordered_extent(inode, start, ins.objectid,
ram_size, cur_alloc_size, 0); ram_size, cur_alloc_size, 0);
BUG_ON(ret); /* -ENOMEM */ if (ret)
goto out_reserve;
if (root->root_key.objectid == if (root->root_key.objectid ==
BTRFS_DATA_RELOC_TREE_OBJECTID) { BTRFS_DATA_RELOC_TREE_OBJECTID) {
...@@ -959,7 +963,7 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans, ...@@ -959,7 +963,7 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
cur_alloc_size); cur_alloc_size);
if (ret) { if (ret) {
btrfs_abort_transaction(trans, root, ret); btrfs_abort_transaction(trans, root, ret);
goto out_unlock; goto out_reserve;
} }
} }
...@@ -988,6 +992,8 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans, ...@@ -988,6 +992,8 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
out: out:
return ret; return ret;
out_reserve:
btrfs_free_reserved_extent(root, ins.objectid, ins.offset);
out_unlock: out_unlock:
extent_clear_unlock_delalloc(inode, extent_clear_unlock_delalloc(inode,
&BTRFS_I(inode)->io_tree, &BTRFS_I(inode)->io_tree,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment