diff options
author | Yan, Zheng <zheng.yan@oracle.com> | 2010-05-16 10:46:25 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2010-05-25 10:34:50 -0400 |
commit | f0486c68e4bd9a06a5904d3eeb3a0d73a83befb8 (patch) | |
tree | 509428ef400ef45e875a3c448b63b86cbea36aea /fs/btrfs/relocation.c | |
parent | 2ead6ae770d9f9dec9f4286bf0fd9001b4388c4b (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.c | 16 |
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); |
3599 | out: | 3607 | out: |
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); |