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, 27 insertions, 16 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 12096496cc99..aacc2121e87c 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -335,7 +335,7 @@ static void backref_tree_panic(struct rb_node *rb_node, int errno, u64 bytenr)
335 if (bnode->root) 335 if (bnode->root)
336 fs_info = bnode->root->fs_info; 336 fs_info = bnode->root->fs_info;
337 btrfs_panic(fs_info, errno, "Inconsistency in backref cache " 337 btrfs_panic(fs_info, errno, "Inconsistency in backref cache "
338 "found at offset %llu\n", (unsigned long long)bytenr); 338 "found at offset %llu\n", bytenr);
339} 339}
340 340
341/* 341/*
@@ -641,6 +641,11 @@ int find_inline_backref(struct extent_buffer *leaf, int slot,
641 WARN_ON(item_size < sizeof(*ei) + sizeof(*bi)); 641 WARN_ON(item_size < sizeof(*ei) + sizeof(*bi));
642 return 1; 642 return 1;
643 } 643 }
644 if (key.type == BTRFS_METADATA_ITEM_KEY &&
645 item_size <= sizeof(*ei)) {
646 WARN_ON(item_size < sizeof(*ei));
647 return 1;
648 }
644 649
645 if (key.type == BTRFS_EXTENT_ITEM_KEY) { 650 if (key.type == BTRFS_EXTENT_ITEM_KEY) {
646 bi = (struct btrfs_tree_block_info *)(ei + 1); 651 bi = (struct btrfs_tree_block_info *)(ei + 1);
@@ -691,6 +696,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
691 int cowonly; 696 int cowonly;
692 int ret; 697 int ret;
693 int err = 0; 698 int err = 0;
699 bool need_check = true;
694 700
695 path1 = btrfs_alloc_path(); 701 path1 = btrfs_alloc_path();
696 path2 = btrfs_alloc_path(); 702 path2 = btrfs_alloc_path();
@@ -914,6 +920,7 @@ again:
914 cur->bytenr); 920 cur->bytenr);
915 921
916 lower = cur; 922 lower = cur;
923 need_check = true;
917 for (; level < BTRFS_MAX_LEVEL; level++) { 924 for (; level < BTRFS_MAX_LEVEL; level++) {
918 if (!path2->nodes[level]) { 925 if (!path2->nodes[level]) {
919 BUG_ON(btrfs_root_bytenr(&root->root_item) != 926 BUG_ON(btrfs_root_bytenr(&root->root_item) !=
@@ -957,14 +964,12 @@ again:
957 964
958 /* 965 /*
959 * add the block to pending list if we 966 * add the block to pending list if we
960 * need check its backrefs. only block 967 * need check its backrefs, we only do this once
961 * at 'cur->level + 1' is added to the 968 * while walking up a tree as we will catch
962 * tail of pending list. this guarantees 969 * anything else later on.
963 * we check backrefs from lower level
964 * blocks to upper level blocks.
965 */ 970 */
966 if (!upper->checked && 971 if (!upper->checked && need_check) {
967 level == cur->level + 1) { 972 need_check = false;
968 list_add_tail(&edge->list[UPPER], 973 list_add_tail(&edge->list[UPPER],
969 &list); 974 &list);
970 } else 975 } else
@@ -2314,8 +2319,13 @@ again:
2314 BUG_ON(root->reloc_root != reloc_root); 2319 BUG_ON(root->reloc_root != reloc_root);
2315 2320
2316 ret = merge_reloc_root(rc, root); 2321 ret = merge_reloc_root(rc, root);
2317 if (ret) 2322 if (ret) {
2323 __update_reloc_root(reloc_root, 1);
2324 free_extent_buffer(reloc_root->node);
2325 free_extent_buffer(reloc_root->commit_root);
2326 kfree(reloc_root);
2318 goto out; 2327 goto out;
2328 }
2319 } else { 2329 } else {
2320 list_del_init(&reloc_root->root_list); 2330 list_del_init(&reloc_root->root_list);
2321 } 2331 }
@@ -2344,9 +2354,6 @@ again:
2344 if (IS_ERR(root)) 2354 if (IS_ERR(root))
2345 continue; 2355 continue;
2346 2356
2347 if (btrfs_root_refs(&root->root_item) == 0)
2348 continue;
2349
2350 trans = btrfs_join_transaction(root); 2357 trans = btrfs_join_transaction(root);
2351 BUG_ON(IS_ERR(trans)); 2358 BUG_ON(IS_ERR(trans));
2352 2359
@@ -3628,7 +3635,7 @@ int add_data_references(struct reloc_control *rc,
3628 unsigned long ptr; 3635 unsigned long ptr;
3629 unsigned long end; 3636 unsigned long end;
3630 u32 blocksize = btrfs_level_size(rc->extent_root, 0); 3637 u32 blocksize = btrfs_level_size(rc->extent_root, 0);
3631 int ret; 3638 int ret = 0;
3632 int err = 0; 3639 int err = 0;
3633 3640
3634 eb = path->nodes[0]; 3641 eb = path->nodes[0];
@@ -3655,6 +3662,10 @@ int add_data_references(struct reloc_control *rc,
3655 } else { 3662 } else {
3656 BUG(); 3663 BUG();
3657 } 3664 }
3665 if (ret) {
3666 err = ret;
3667 goto out;
3668 }
3658 ptr += btrfs_extent_inline_ref_size(key.type); 3669 ptr += btrfs_extent_inline_ref_size(key.type);
3659 } 3670 }
3660 WARN_ON(ptr > end); 3671 WARN_ON(ptr > end);
@@ -3700,6 +3711,7 @@ int add_data_references(struct reloc_control *rc,
3700 } 3711 }
3701 path->slots[0]++; 3712 path->slots[0]++;
3702 } 3713 }
3714out:
3703 btrfs_release_path(path); 3715 btrfs_release_path(path);
3704 if (err) 3716 if (err)
3705 free_block_list(blocks); 3717 free_block_list(blocks);
@@ -4219,8 +4231,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
4219 } 4231 }
4220 4232
4221 printk(KERN_INFO "btrfs: relocating block group %llu flags %llu\n", 4233 printk(KERN_INFO "btrfs: relocating block group %llu flags %llu\n",
4222 (unsigned long long)rc->block_group->key.objectid, 4234 rc->block_group->key.objectid, rc->block_group->flags);
4223 (unsigned long long)rc->block_group->flags);
4224 4235
4225 ret = btrfs_start_all_delalloc_inodes(fs_info, 0); 4236 ret = btrfs_start_all_delalloc_inodes(fs_info, 0);
4226 if (ret < 0) { 4237 if (ret < 0) {
@@ -4242,7 +4253,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
4242 break; 4253 break;
4243 4254
4244 printk(KERN_INFO "btrfs: found %llu extents\n", 4255 printk(KERN_INFO "btrfs: found %llu extents\n",
4245 (unsigned long long)rc->extents_found); 4256 rc->extents_found);
4246 4257
4247 if (rc->stage == MOVE_DATA_EXTENTS && rc->found_file_extent) { 4258 if (rc->stage == MOVE_DATA_EXTENTS && rc->found_file_extent) {
4248 btrfs_wait_ordered_range(rc->data_inode, 0, (u64)-1); 4259 btrfs_wait_ordered_range(rc->data_inode, 0, (u64)-1);