mirror of
https://github.com/kdave/btrfs-progs
synced 2025-03-06 02:37:37 +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,
|
||||
u64 file_pos, u64 disk_bytenr,
|
||||
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 */
|
||||
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,
|
||||
|
@ -3743,6 +3743,86 @@ out:
|
||||
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
|
||||
* make_block_groups isn't accuracy in this case.
|
||||
|
Loading…
Reference in New Issue
Block a user