btrfs-progs: extent-tree: Introduce functions to free dev extents in a chunk

Introduce two functions, free_dev_extent_item and
free_chunk_dev_extent_items, to free dev extent items in a chunk.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: David Sterba <dsterba@suse.com>
master
Qu Wenruo 2015-07-07 16:15:24 +08:00 committed by David Sterba
parent 9d25a273b0
commit 5bdee4862d
1 changed files with 73 additions and 0 deletions

View File

@ -3483,6 +3483,79 @@ out:
return ret;
}
static int free_dev_extent_item(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info,
u64 devid, u64 dev_offset)
{
struct btrfs_root *root = fs_info->dev_root;
struct btrfs_path *path;
struct btrfs_key key;
int ret;
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
key.objectid = devid;
key.type = BTRFS_DEV_EXTENT_KEY;
key.offset = dev_offset;
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
if (ret < 0)
goto out;
if (ret > 0) {
ret = -ENOENT;
goto out;
}
ret = btrfs_del_item(trans, root, path);
out:
btrfs_free_path(path);
return ret;
}
static int free_chunk_dev_extent_items(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info,
u64 chunk_offset)
{
struct btrfs_chunk *chunk = NULL;
struct btrfs_root *root= fs_info->chunk_root;
struct btrfs_path *path;
struct btrfs_key key;
u16 num_stripes;
int i;
int ret;
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
key.type = BTRFS_CHUNK_ITEM_KEY;
key.offset = chunk_offset;
ret = btrfs_search_slot(trans, root, &key, path, 0, 0);
if (ret < 0)
goto out;
if (ret > 0) {
ret = -ENOENT;
goto out;
}
chunk = btrfs_item_ptr(path->nodes[0], path->slots[0],
struct btrfs_chunk);
num_stripes = btrfs_chunk_num_stripes(path->nodes[0], chunk);
for (i = 0; i < num_stripes; i++) {
ret = free_dev_extent_item(trans, fs_info,
btrfs_stripe_devid_nr(path->nodes[0], chunk, i),
btrfs_stripe_offset_nr(path->nodes[0], chunk, i));
if (ret < 0)
goto out;
}
out:
btrfs_free_path(path);
return ret;
}
/*
* Fixup block accounting. The initial block accounting created by
* make_block_groups isn't accuracy in this case.