Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -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;
@@ -947,11 +948,14 @@ 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) {
@@ -959,7 +963,7 @@ static noinline int __cow_file_range(struct btrfs_trans_handle *trans,
						      cur_alloc_size);
			if (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,
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,