Skip to content

Commit

Permalink
Btrfs: return free space in cow error path
Browse files Browse the repository at this point in the history
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: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
  • Loading branch information
Liu Bo authored and Josef Bacik committed May 6, 2013
1 parent 6463fe5 commit ace68ba
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,8 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
}

em = alloc_extent_map();
BUG_ON(!em); /* -ENOMEM */
if (!em)
goto out_reserve;
em->start = start;
em->orig_start = em->start;
ram_size = ins.offset;
Expand All @@ -947,19 +948,22 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
btrfs_drop_extent_cache(inode, start,
start + ram_size - 1, 0);
}
if (ret)
goto out_reserve;

cur_alloc_size = ins.offset;
ret = btrfs_add_ordered_extent(inode, start, ins.objectid,
ram_size, cur_alloc_size, 0);
BUG_ON(ret); /* -ENOMEM */
if (ret)
goto out_reserve;

if (root->root_key.objectid ==
BTRFS_DATA_RELOC_TREE_OBJECTID) {
ret = btrfs_reloc_clone_csums(inode, start,
cur_alloc_size);
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto out_unlock;
goto out_reserve;
}
}

Expand Down Expand Up @@ -988,6 +992,8 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
out:
return ret;

out_reserve:
btrfs_free_reserved_extent(root, ins.objectid, ins.offset);
out_unlock:
extent_clear_unlock_delalloc(inode,
&BTRFS_I(inode)->io_tree,
Expand Down

0 comments on commit ace68ba

Please sign in to comment.