aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/relocation.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/relocation.c')
-rw-r--r--fs/btrfs/relocation.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 045c9c2b2d7e..31ade5802ae8 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -1157,6 +1157,7 @@ static int clone_backref_node(struct btrfs_trans_handle *trans,
1157 new_node->bytenr = dest->node->start; 1157 new_node->bytenr = dest->node->start;
1158 new_node->level = node->level; 1158 new_node->level = node->level;
1159 new_node->lowest = node->lowest; 1159 new_node->lowest = node->lowest;
1160 new_node->checked = 1;
1160 new_node->root = dest; 1161 new_node->root = dest;
1161 1162
1162 if (!node->lowest) { 1163 if (!node->lowest) {
@@ -2028,6 +2029,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
2028 2029
2029 while (1) { 2030 while (1) {
2030 trans = btrfs_start_transaction(root, 0); 2031 trans = btrfs_start_transaction(root, 0);
2032 BUG_ON(IS_ERR(trans));
2031 trans->block_rsv = rc->block_rsv; 2033 trans->block_rsv = rc->block_rsv;
2032 2034
2033 ret = btrfs_block_rsv_check(trans, root, rc->block_rsv, 2035 ret = btrfs_block_rsv_check(trans, root, rc->block_rsv,
@@ -2147,6 +2149,12 @@ again:
2147 } 2149 }
2148 2150
2149 trans = btrfs_join_transaction(rc->extent_root, 1); 2151 trans = btrfs_join_transaction(rc->extent_root, 1);
2152 if (IS_ERR(trans)) {
2153 if (!err)
2154 btrfs_block_rsv_release(rc->extent_root,
2155 rc->block_rsv, num_bytes);
2156 return PTR_ERR(trans);
2157 }
2150 2158
2151 if (!err) { 2159 if (!err) {
2152 if (num_bytes != rc->merging_rsv_size) { 2160 if (num_bytes != rc->merging_rsv_size) {
@@ -3222,6 +3230,7 @@ truncate:
3222 trans = btrfs_join_transaction(root, 0); 3230 trans = btrfs_join_transaction(root, 0);
3223 if (IS_ERR(trans)) { 3231 if (IS_ERR(trans)) {
3224 btrfs_free_path(path); 3232 btrfs_free_path(path);
3233 ret = PTR_ERR(trans);
3225 goto out; 3234 goto out;
3226 } 3235 }
3227 3236
@@ -3628,6 +3637,7 @@ int prepare_to_relocate(struct reloc_control *rc)
3628 set_reloc_control(rc); 3637 set_reloc_control(rc);
3629 3638
3630 trans = btrfs_join_transaction(rc->extent_root, 1); 3639 trans = btrfs_join_transaction(rc->extent_root, 1);
3640 BUG_ON(IS_ERR(trans));
3631 btrfs_commit_transaction(trans, rc->extent_root); 3641 btrfs_commit_transaction(trans, rc->extent_root);
3632 return 0; 3642 return 0;
3633} 3643}
@@ -3644,6 +3654,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
3644 u32 item_size; 3654 u32 item_size;
3645 int ret; 3655 int ret;
3646 int err = 0; 3656 int err = 0;
3657 int progress = 0;
3647 3658
3648 path = btrfs_alloc_path(); 3659 path = btrfs_alloc_path();
3649 if (!path) 3660 if (!path)
@@ -3656,8 +3667,10 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
3656 } 3667 }
3657 3668
3658 while (1) { 3669 while (1) {
3670 progress++;
3659 trans = btrfs_start_transaction(rc->extent_root, 0); 3671 trans = btrfs_start_transaction(rc->extent_root, 0);
3660 3672 BUG_ON(IS_ERR(trans));
3673restart:
3661 if (update_backref_cache(trans, &rc->backref_cache)) { 3674 if (update_backref_cache(trans, &rc->backref_cache)) {
3662 btrfs_end_transaction(trans, rc->extent_root); 3675 btrfs_end_transaction(trans, rc->extent_root);
3663 continue; 3676 continue;
@@ -3770,6 +3783,15 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
3770 } 3783 }
3771 } 3784 }
3772 } 3785 }
3786 if (trans && progress && err == -ENOSPC) {
3787 ret = btrfs_force_chunk_alloc(trans, rc->extent_root,
3788 rc->block_group->flags);
3789 if (ret == 0) {
3790 err = 0;
3791 progress = 0;
3792 goto restart;
3793 }
3794 }
3773 3795
3774 btrfs_release_path(rc->extent_root, path); 3796 btrfs_release_path(rc->extent_root, path);
3775 clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY, 3797 clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY,
@@ -3804,7 +3826,10 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
3804 3826
3805 /* get rid of pinned extents */ 3827 /* get rid of pinned extents */
3806 trans = btrfs_join_transaction(rc->extent_root, 1); 3828 trans = btrfs_join_transaction(rc->extent_root, 1);
3807 btrfs_commit_transaction(trans, rc->extent_root); 3829 if (IS_ERR(trans))
3830 err = PTR_ERR(trans);
3831 else
3832 btrfs_commit_transaction(trans, rc->extent_root);
3808out_free: 3833out_free:
3809 btrfs_free_block_rsv(rc->extent_root, rc->block_rsv); 3834 btrfs_free_block_rsv(rc->extent_root, rc->block_rsv);
3810 btrfs_free_path(path); 3835 btrfs_free_path(path);
@@ -4022,6 +4047,7 @@ static noinline_for_stack int mark_garbage_root(struct btrfs_root *root)
4022 int ret; 4047 int ret;
4023 4048
4024 trans = btrfs_start_transaction(root->fs_info->tree_root, 0); 4049 trans = btrfs_start_transaction(root->fs_info->tree_root, 0);
4050 BUG_ON(IS_ERR(trans));
4025 4051
4026 memset(&root->root_item.drop_progress, 0, 4052 memset(&root->root_item.drop_progress, 0,
4027 sizeof(root->root_item.drop_progress)); 4053 sizeof(root->root_item.drop_progress));
@@ -4125,6 +4151,11 @@ int btrfs_recover_relocation(struct btrfs_root *root)
4125 set_reloc_control(rc); 4151 set_reloc_control(rc);
4126 4152
4127 trans = btrfs_join_transaction(rc->extent_root, 1); 4153 trans = btrfs_join_transaction(rc->extent_root, 1);
4154 if (IS_ERR(trans)) {
4155 unset_reloc_control(rc);
4156 err = PTR_ERR(trans);
4157 goto out_free;
4158 }
4128 4159
4129 rc->merge_reloc_tree = 1; 4160 rc->merge_reloc_tree = 1;
4130 4161
@@ -4154,9 +4185,13 @@ int btrfs_recover_relocation(struct btrfs_root *root)
4154 unset_reloc_control(rc); 4185 unset_reloc_control(rc);
4155 4186
4156 trans = btrfs_join_transaction(rc->extent_root, 1); 4187 trans = btrfs_join_transaction(rc->extent_root, 1);
4157 btrfs_commit_transaction(trans, rc->extent_root); 4188 if (IS_ERR(trans))
4158out: 4189 err = PTR_ERR(trans);
4190 else
4191 btrfs_commit_transaction(trans, rc->extent_root);
4192out_free:
4159 kfree(rc); 4193 kfree(rc);
4194out:
4160 while (!list_empty(&reloc_roots)) { 4195 while (!list_empty(&reloc_roots)) {
4161 reloc_root = list_entry(reloc_roots.next, 4196 reloc_root = list_entry(reloc_roots.next,
4162 struct btrfs_root, root_list); 4197 struct btrfs_root, root_list);