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.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 3be16ccc7eea..48a504260635 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3203,6 +3203,7 @@ static int check_extent_flags(u64 flags)
3203 return 0; 3203 return 0;
3204} 3204}
3205 3205
3206
3206static noinline_for_stack int relocate_block_group(struct reloc_control *rc) 3207static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
3207{ 3208{
3208 struct rb_root blocks = RB_ROOT; 3209 struct rb_root blocks = RB_ROOT;
@@ -3220,6 +3221,9 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
3220 if (!path) 3221 if (!path)
3221 return -ENOMEM; 3222 return -ENOMEM;
3222 3223
3224 rc->extents_found = 0;
3225 rc->extents_skipped = 0;
3226
3223 rc->search_start = rc->block_group->key.objectid; 3227 rc->search_start = rc->block_group->key.objectid;
3224 clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY, 3228 clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY,
3225 GFP_NOFS); 3229 GFP_NOFS);
@@ -3475,14 +3479,15 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
3475 btrfs_wait_ordered_extents(fs_info->tree_root, 0); 3479 btrfs_wait_ordered_extents(fs_info->tree_root, 0);
3476 3480
3477 while (1) { 3481 while (1) {
3478 mutex_lock(&fs_info->cleaner_mutex);
3479 btrfs_clean_old_snapshots(fs_info->tree_root);
3480 mutex_unlock(&fs_info->cleaner_mutex);
3481
3482 rc->extents_found = 0; 3482 rc->extents_found = 0;
3483 rc->extents_skipped = 0; 3483 rc->extents_skipped = 0;
3484 3484
3485 mutex_lock(&fs_info->cleaner_mutex);
3486
3487 btrfs_clean_old_snapshots(fs_info->tree_root);
3485 ret = relocate_block_group(rc); 3488 ret = relocate_block_group(rc);
3489
3490 mutex_unlock(&fs_info->cleaner_mutex);
3486 if (ret < 0) { 3491 if (ret < 0) {
3487 err = ret; 3492 err = ret;
3488 break; 3493 break;
@@ -3530,6 +3535,26 @@ out:
3530 return err; 3535 return err;
3531} 3536}
3532 3537
3538static noinline_for_stack int mark_garbage_root(struct btrfs_root *root)
3539{
3540 struct btrfs_trans_handle *trans;
3541 int ret;
3542
3543 trans = btrfs_start_transaction(root->fs_info->tree_root, 1);
3544
3545 memset(&root->root_item.drop_progress, 0,
3546 sizeof(root->root_item.drop_progress));
3547 root->root_item.drop_level = 0;
3548 btrfs_set_root_refs(&root->root_item, 0);
3549 ret = btrfs_update_root(trans, root->fs_info->tree_root,
3550 &root->root_key, &root->root_item);
3551 BUG_ON(ret);
3552
3553 ret = btrfs_end_transaction(trans, root->fs_info->tree_root);
3554 BUG_ON(ret);
3555 return 0;
3556}
3557
3533/* 3558/*
3534 * recover relocation interrupted by system crash. 3559 * recover relocation interrupted by system crash.
3535 * 3560 *
@@ -3589,8 +3614,12 @@ int btrfs_recover_relocation(struct btrfs_root *root)
3589 fs_root = read_fs_root(root->fs_info, 3614 fs_root = read_fs_root(root->fs_info,
3590 reloc_root->root_key.offset); 3615 reloc_root->root_key.offset);
3591 if (IS_ERR(fs_root)) { 3616 if (IS_ERR(fs_root)) {
3592 err = PTR_ERR(fs_root); 3617 ret = PTR_ERR(fs_root);
3593 goto out; 3618 if (ret != -ENOENT) {
3619 err = ret;
3620 goto out;
3621 }
3622 mark_garbage_root(reloc_root);
3594 } 3623 }
3595 } 3624 }
3596 3625