int remove_from_free_space_tree(struct btrfs_trans_handle *trans, u64 start, u64 size) { struct btrfs_block_group_cache *block_group; struct btrfs_path *path; int ret; if (!btrfs_fs_compat_ro(trans->fs_info, FREE_SPACE_TREE)) return 0; path = btrfs_alloc_path(); if (!path) { ret = -ENOMEM; goto out; } block_group = btrfs_lookup_block_group(trans->fs_info, start); if (!block_group) { ASSERT(0); ret = -ENOENT; goto out; } mutex_lock(&block_group->free_space_lock); ret = __remove_from_free_space_tree(trans, block_group, path, start, size); mutex_unlock(&block_group->free_space_lock); btrfs_put_block_group(block_group); out: btrfs_free_path(path); if (ret) btrfs_abort_transaction(trans, ret); return ret; }
static int test_merge_none(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *cache, struct btrfs_path *path) { struct free_space_extent extents[] = { {cache->key.objectid, BITMAP_RANGE}, {cache->key.objectid + 2 * BITMAP_RANGE, BITMAP_RANGE}, {cache->key.objectid + 4 * BITMAP_RANGE, BITMAP_RANGE}, }; int ret; ret = __remove_from_free_space_tree(trans, fs_info, cache, path, cache->key.objectid, cache->key.offset); if (ret) { test_msg("Could not remove free space\n"); return ret; } ret = __add_to_free_space_tree(trans, fs_info, cache, path, cache->key.objectid, BITMAP_RANGE); if (ret) { test_msg("Could not add free space\n"); return ret; } ret = __add_to_free_space_tree(trans, fs_info, cache, path, cache->key.objectid + 4 * BITMAP_RANGE, BITMAP_RANGE); if (ret) { test_msg("Could not add free space\n"); return ret; } ret = __add_to_free_space_tree(trans, fs_info, cache, path, cache->key.objectid + 2 * BITMAP_RANGE, BITMAP_RANGE); if (ret) { test_msg("Could not add free space\n"); return ret; } return check_free_space_extents(trans, fs_info, cache, path, extents, ARRAY_SIZE(extents)); }
static int test_remove_all(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, struct btrfs_block_group_cache *cache, struct btrfs_path *path) { struct free_space_extent extents[] = {}; int ret; ret = __remove_from_free_space_tree(trans, fs_info, cache, path, cache->key.objectid, cache->key.offset); if (ret) { test_msg("Could not remove free space\n"); return ret; } return check_free_space_extents(trans, fs_info, cache, path, extents, ARRAY_SIZE(extents)); }