Btrfs: Introduce contexts for metadata reservation
Introducing metadata reseravtion contexts has two major advantages. First, it makes metadata reseravtion more traceable. Second, it can reclaim freed space and re-add them to the itself after transaction committed. Besides add btrfs_block_rsv structure and related helper functions, This patch contains following changes: Move code that decides if freed tree block should be pinned into btrfs_free_tree_block(). Make space accounting more accurate, mainly for handling read only block groups. Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
@@ -3514,6 +3514,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
|
||||
struct btrfs_fs_info *fs_info = extent_root->fs_info;
|
||||
struct reloc_control *rc;
|
||||
int ret;
|
||||
int rw = 0;
|
||||
int err = 0;
|
||||
|
||||
rc = kzalloc(sizeof(*rc), GFP_NOFS);
|
||||
@@ -3524,15 +3525,22 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
|
||||
extent_io_tree_init(&rc->processed_blocks, NULL, GFP_NOFS);
|
||||
INIT_LIST_HEAD(&rc->reloc_roots);
|
||||
|
||||
rc->extent_root = extent_root;
|
||||
rc->block_group = btrfs_lookup_block_group(fs_info, group_start);
|
||||
BUG_ON(!rc->block_group);
|
||||
|
||||
if (!rc->block_group->ro) {
|
||||
ret = btrfs_set_block_group_ro(extent_root, rc->block_group);
|
||||
if (ret) {
|
||||
err = ret;
|
||||
goto out;
|
||||
}
|
||||
rw = 1;
|
||||
}
|
||||
|
||||
btrfs_init_workers(&rc->workers, "relocate",
|
||||
fs_info->thread_pool_size, NULL);
|
||||
|
||||
rc->extent_root = extent_root;
|
||||
btrfs_prepare_block_group_relocation(extent_root, rc->block_group);
|
||||
|
||||
rc->data_inode = create_reloc_inode(fs_info, rc->block_group);
|
||||
if (IS_ERR(rc->data_inode)) {
|
||||
err = PTR_ERR(rc->data_inode);
|
||||
@@ -3597,6 +3605,8 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
|
||||
WARN_ON(rc->block_group->reserved > 0);
|
||||
WARN_ON(btrfs_block_group_used(&rc->block_group->item) > 0);
|
||||
out:
|
||||
if (err && rw)
|
||||
btrfs_set_block_group_rw(extent_root, rc->block_group);
|
||||
iput(rc->data_inode);
|
||||
btrfs_stop_workers(&rc->workers);
|
||||
btrfs_put_block_group(rc->block_group);
|
||||
|
Reference in New Issue
Block a user