mirror of
https://github.com/kdave/btrfs-progs
synced 2025-03-06 10:47:42 +00:00
btrfs-progs: extent-tree: Introduce btrfs_free_block_group function
This function will be used to free a empty chunk. This provides the basis for later temp chunk cleanup. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
00827cad8e
commit
80fc1e0fc6
2
ctree.h
2
ctree.h
@ -2275,6 +2275,8 @@ int btrfs_record_file_extent(struct btrfs_trans_handle *trans,
|
|||||||
struct btrfs_inode_item *inode,
|
struct btrfs_inode_item *inode,
|
||||||
u64 file_pos, u64 disk_bytenr,
|
u64 file_pos, u64 disk_bytenr,
|
||||||
u64 num_bytes);
|
u64 num_bytes);
|
||||||
|
int btrfs_free_block_group(struct btrfs_trans_handle *trans,
|
||||||
|
struct btrfs_fs_info *fs_info, u64 bytenr, u64 len);
|
||||||
/* ctree.c */
|
/* ctree.c */
|
||||||
int btrfs_comp_cpu_keys(struct btrfs_key *k1, struct btrfs_key *k2);
|
int btrfs_comp_cpu_keys(struct btrfs_key *k1, struct btrfs_key *k2);
|
||||||
int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||||
|
@ -3743,6 +3743,86 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int btrfs_free_block_group(struct btrfs_trans_handle *trans,
|
||||||
|
struct btrfs_fs_info *fs_info, u64 bytenr, u64 len)
|
||||||
|
{
|
||||||
|
struct btrfs_root *extent_root = fs_info->extent_root;
|
||||||
|
struct btrfs_path *path;
|
||||||
|
struct btrfs_block_group_item *bgi;
|
||||||
|
struct btrfs_key key;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
path = btrfs_alloc_path();
|
||||||
|
if (!path)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
key.objectid = bytenr;
|
||||||
|
key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
|
||||||
|
key.offset = len;
|
||||||
|
|
||||||
|
/* Double check the block group to ensure it's empty */
|
||||||
|
ret = btrfs_search_slot(trans, extent_root, &key, path, 0, 0);
|
||||||
|
if (ret > 0) {
|
||||||
|
ret = -ENONET;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
bgi = btrfs_item_ptr(path->nodes[0], path->slots[0],
|
||||||
|
struct btrfs_block_group_item);
|
||||||
|
if (btrfs_disk_block_group_used(path->nodes[0], bgi)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARNING: block group [%llu,%llu) is not empty\n",
|
||||||
|
bytenr, bytenr + len);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
btrfs_release_path(path);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now pin all space in the block group, to prevent further transaction
|
||||||
|
* allocate space from it.
|
||||||
|
* Every operation needs a transaction must be in the range.
|
||||||
|
*/
|
||||||
|
btrfs_pin_extent(fs_info, bytenr, len);
|
||||||
|
|
||||||
|
/* delete block group item and chunk item */
|
||||||
|
ret = free_block_group_item(trans, fs_info, bytenr, len);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"failed to free block group item for [%llu,%llu)\n",
|
||||||
|
bytenr, bytenr + len);
|
||||||
|
btrfs_unpin_extent(fs_info, bytenr, len);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = free_chunk_dev_extent_items(trans, fs_info, bytenr);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"failed to dev extents belongs to [%llu,%llu)\n",
|
||||||
|
bytenr, bytenr + len);
|
||||||
|
btrfs_unpin_extent(fs_info, bytenr, len);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
ret = free_chunk_item(trans, fs_info, bytenr, len);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"failed to free chunk for [%llu,%llu)\n",
|
||||||
|
bytenr, bytenr + len);
|
||||||
|
btrfs_unpin_extent(fs_info, bytenr, len);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now release the block_group_cache */
|
||||||
|
ret = free_block_group_cache(trans, fs_info, bytenr, len);
|
||||||
|
btrfs_unpin_extent(fs_info, bytenr, len);
|
||||||
|
|
||||||
|
out:
|
||||||
|
btrfs_free_path(path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fixup block accounting. The initial block accounting created by
|
* Fixup block accounting. The initial block accounting created by
|
||||||
* make_block_groups isn't accuracy in this case.
|
* make_block_groups isn't accuracy in this case.
|
||||||
|
Loading…
Reference in New Issue
Block a user