mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-29 01:22:13 +00:00
btrfs-progs: extent-tree: Introduce functions to free chunk items
Introduce two functions, free_chunk_item and free_system_chunk_item. First one will free chunk item in chunk tree. The latter one will free a system chunk in super block. They are used for later chunk/block group free function. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
5bdee4862d
commit
1da859012b
@ -3556,6 +3556,92 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int free_system_chunk_item(struct btrfs_super_block *super,
|
||||
struct btrfs_key *key)
|
||||
{
|
||||
struct btrfs_disk_key *disk_key;
|
||||
struct btrfs_key cpu_key;
|
||||
u32 array_size = btrfs_super_sys_array_size(super);
|
||||
char *ptr = (char *)super->sys_chunk_array;
|
||||
int cur = 0;
|
||||
int ret = -ENOENT;
|
||||
|
||||
while (cur < btrfs_super_sys_array_size(super)) {
|
||||
struct btrfs_chunk *chunk;
|
||||
u32 num_stripes;
|
||||
u32 chunk_len;
|
||||
|
||||
disk_key = (struct btrfs_disk_key *)(ptr + cur);
|
||||
btrfs_disk_key_to_cpu(&cpu_key, disk_key);
|
||||
if (cpu_key.type != BTRFS_CHUNK_ITEM_KEY) {
|
||||
/* just in case */
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
chunk = (struct btrfs_chunk *)(ptr + cur + sizeof(*disk_key));
|
||||
num_stripes = btrfs_stack_chunk_num_stripes(chunk);
|
||||
chunk_len = btrfs_chunk_item_size(num_stripes) +
|
||||
sizeof(*disk_key);
|
||||
|
||||
if (key->objectid == cpu_key.objectid &&
|
||||
key->offset == cpu_key.offset &&
|
||||
key->type == cpu_key.type) {
|
||||
memmove(ptr + cur, ptr + cur + chunk_len,
|
||||
array_size - cur - chunk_len);
|
||||
array_size -= chunk_len;
|
||||
btrfs_set_super_sys_array_size(super, array_size);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cur += chunk_len;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int free_chunk_item(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info,
|
||||
u64 bytenr, u64 len)
|
||||
{
|
||||
struct btrfs_path *path;
|
||||
struct btrfs_key key;
|
||||
struct btrfs_root *root = fs_info->chunk_root;
|
||||
struct btrfs_chunk *chunk;
|
||||
u64 chunk_type;
|
||||
int ret;
|
||||
|
||||
key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
|
||||
key.offset = bytenr;
|
||||
key.type = BTRFS_CHUNK_ITEM_KEY;
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
|
||||
if (ret > 0) {
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
chunk = btrfs_item_ptr(path->nodes[0], path->slots[0],
|
||||
struct btrfs_chunk);
|
||||
chunk_type = btrfs_chunk_type(path->nodes[0], chunk);
|
||||
|
||||
ret = btrfs_del_item(trans, root, path);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (chunk_type & BTRFS_BLOCK_GROUP_SYSTEM)
|
||||
ret = free_system_chunk_item(fs_info->super_copy, &key);
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user