aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/relocation.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.yan@oracle.com>2010-05-16 10:46:25 -0400
committerChris Mason <chris.mason@oracle.com>2010-05-25 10:34:50 -0400
commitf0486c68e4bd9a06a5904d3eeb3a0d73a83befb8 (patch)
tree509428ef400ef45e875a3c448b63b86cbea36aea /fs/btrfs/relocation.c
parent2ead6ae770d9f9dec9f4286bf0fd9001b4388c4b (diff)
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>
Diffstat (limited to 'fs/btrfs/relocation.c')
-rw-r--r--fs/btrfs/relocation.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index e558dd941ded..d565b45a6352 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3514,6 +3514,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
3514 struct btrfs_fs_info *fs_info = extent_root->fs_info; 3514 struct btrfs_fs_info *fs_info = extent_root->fs_info;
3515 struct reloc_control *rc; 3515 struct reloc_control *rc;
3516 int ret; 3516 int ret;
3517 int rw = 0;
3517 int err = 0; 3518 int err = 0;
3518 3519
3519 rc = kzalloc(sizeof(*rc), GFP_NOFS); 3520 rc = kzalloc(sizeof(*rc), GFP_NOFS);
@@ -3524,15 +3525,22 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
3524 extent_io_tree_init(&rc->processed_blocks, NULL, GFP_NOFS); 3525 extent_io_tree_init(&rc->processed_blocks, NULL, GFP_NOFS);
3525 INIT_LIST_HEAD(&rc->reloc_roots); 3526 INIT_LIST_HEAD(&rc->reloc_roots);
3526 3527
3528 rc->extent_root = extent_root;
3527 rc->block_group = btrfs_lookup_block_group(fs_info, group_start); 3529 rc->block_group = btrfs_lookup_block_group(fs_info, group_start);
3528 BUG_ON(!rc->block_group); 3530 BUG_ON(!rc->block_group);
3529 3531
3532 if (!rc->block_group->ro) {
3533 ret = btrfs_set_block_group_ro(extent_root, rc->block_group);
3534 if (ret) {
3535 err = ret;
3536 goto out;
3537 }
3538 rw = 1;
3539 }
3540
3530 btrfs_init_workers(&rc->workers, "relocate", 3541 btrfs_init_workers(&rc->workers, "relocate",
3531 fs_info->thread_pool_size, NULL); 3542 fs_info->thread_pool_size, NULL);
3532 3543
3533 rc->extent_root = extent_root;
3534 btrfs_prepare_block_group_relocation(extent_root, rc->block_group);
3535
3536 rc->data_inode = create_reloc_inode(fs_info, rc->block_group); 3544 rc->data_inode = create_reloc_inode(fs_info, rc->block_group);
3537 if (IS_ERR(rc->data_inode)) { 3545 if (IS_ERR(rc->data_inode)) {
3538 err = PTR_ERR(rc->data_inode); 3546 err = PTR_ERR(rc->data_inode);
@@ -3597,6 +3605,8 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
3597 WARN_ON(rc->block_group->reserved > 0); 3605 WARN_ON(rc->block_group->reserved > 0);
3598 WARN_ON(btrfs_block_group_used(&rc->block_group->item) > 0); 3606 WARN_ON(btrfs_block_group_used(&rc->block_group->item) > 0);
3599out: 3607out:
3608 if (err && rw)
3609 btrfs_set_block_group_rw(extent_root, rc->block_group);
3600 iput(rc->data_inode); 3610 iput(rc->data_inode);
3601 btrfs_stop_workers(&rc->workers); 3611 btrfs_stop_workers(&rc->workers);
3602 btrfs_put_block_group(rc->block_group); 3612 btrfs_put_block_group(rc->block_group);