aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-10-29 14:49:05 -0400
committerChris Mason <chris.mason@oracle.com>2008-10-29 14:49:05 -0400
commitf82d02d9d8222183b7945e893111a6d1bf67ae4a (patch)
tree70be1bb231f4cc2e673920774e759359f3dcf1a5 /fs/btrfs/extent-tree.c
parentc8b978188c9a0fd3d535c13debd19d522b726f1f (diff)
Btrfs: Improve space balancing code
This patch improves the space balancing code to keep more sharing of tree blocks. The only case that breaks sharing of tree blocks is data extents get fragmented during balancing. The main changes in this patch are: Add a 'drop sub-tree' function. This solves the problem in old code that BTRFS_HEADER_FLAG_WRITTEN check breaks sharing of tree block. Remove relocation mapping tree. Relocation mappings are stored in struct btrfs_ref_path and updated dynamically during walking up/down the reference path. This reduces CPU usage and simplifies code. This patch also fixes a bug. Root items for reloc trees should be updated in btrfs_free_reloc_root. Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c364
1 files changed, 223 insertions, 141 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index bbf04e80a1a3..56e41369d713 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3032,13 +3032,103 @@ out:
3032} 3032}
3033 3033
3034/* 3034/*
3035 * helper function for drop_subtree, this function is similar to
3036 * walk_down_tree. The main difference is that it checks reference
3037 * counts while tree blocks are locked.
3038 */
3039static int noinline walk_down_subtree(struct btrfs_trans_handle *trans,
3040 struct btrfs_root *root,
3041 struct btrfs_path *path, int *level)
3042{
3043 struct extent_buffer *next;
3044 struct extent_buffer *cur;
3045 struct extent_buffer *parent;
3046 u64 bytenr;
3047 u64 ptr_gen;
3048 u32 blocksize;
3049 u32 refs;
3050 int ret;
3051
3052 cur = path->nodes[*level];
3053 ret = btrfs_lookup_extent_ref(trans, root, cur->start, cur->len,
3054 &refs);
3055 BUG_ON(ret);
3056 if (refs > 1)
3057 goto out;
3058
3059 while (*level >= 0) {
3060 cur = path->nodes[*level];
3061 if (*level == 0) {
3062 ret = btrfs_drop_leaf_ref(trans, root, cur);
3063 BUG_ON(ret);
3064 clean_tree_block(trans, root, cur);
3065 break;
3066 }
3067 if (path->slots[*level] >= btrfs_header_nritems(cur)) {
3068 clean_tree_block(trans, root, cur);
3069 break;
3070 }
3071
3072 bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
3073 blocksize = btrfs_level_size(root, *level - 1);
3074 ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]);
3075
3076 next = read_tree_block(root, bytenr, blocksize, ptr_gen);
3077 btrfs_tree_lock(next);
3078
3079 ret = btrfs_lookup_extent_ref(trans, root, bytenr, blocksize,
3080 &refs);
3081 BUG_ON(ret);
3082 if (refs > 1) {
3083 parent = path->nodes[*level];
3084 ret = btrfs_free_extent(trans, root, bytenr,
3085 blocksize, parent->start,
3086 btrfs_header_owner(parent),
3087 btrfs_header_generation(parent),
3088 *level - 1, 1);
3089 BUG_ON(ret);
3090 path->slots[*level]++;
3091 btrfs_tree_unlock(next);
3092 free_extent_buffer(next);
3093 continue;
3094 }
3095
3096 *level = btrfs_header_level(next);
3097 path->nodes[*level] = next;
3098 path->slots[*level] = 0;
3099 path->locks[*level] = 1;
3100 cond_resched();
3101 }
3102out:
3103 parent = path->nodes[*level + 1];
3104 bytenr = path->nodes[*level]->start;
3105 blocksize = path->nodes[*level]->len;
3106
3107 ret = btrfs_free_extent(trans, root, bytenr, blocksize,
3108 parent->start, btrfs_header_owner(parent),
3109 btrfs_header_generation(parent), *level, 1);
3110 BUG_ON(ret);
3111
3112 if (path->locks[*level]) {
3113 btrfs_tree_unlock(path->nodes[*level]);
3114 path->locks[*level] = 0;
3115 }
3116 free_extent_buffer(path->nodes[*level]);
3117 path->nodes[*level] = NULL;
3118 *level += 1;
3119 cond_resched();
3120 return 0;
3121}
3122
3123/*
3035 * helper for dropping snapshots. This walks back up the tree in the path 3124 * helper for dropping snapshots. This walks back up the tree in the path
3036 * to find the first node higher up where we haven't yet gone through 3125 * to find the first node higher up where we haven't yet gone through
3037 * all the slots 3126 * all the slots
3038 */ 3127 */
3039static int noinline walk_up_tree(struct btrfs_trans_handle *trans, 3128static int noinline walk_up_tree(struct btrfs_trans_handle *trans,
3040 struct btrfs_root *root, 3129 struct btrfs_root *root,
3041 struct btrfs_path *path, int *level) 3130 struct btrfs_path *path,
3131 int *level, int max_level)
3042{ 3132{
3043 u64 root_owner; 3133 u64 root_owner;
3044 u64 root_gen; 3134 u64 root_gen;
@@ -3047,7 +3137,7 @@ static int noinline walk_up_tree(struct btrfs_trans_handle *trans,
3047 int slot; 3137 int slot;
3048 int ret; 3138 int ret;
3049 3139
3050 for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) { 3140 for (i = *level; i < max_level && path->nodes[i]; i++) {
3051 slot = path->slots[i]; 3141 slot = path->slots[i];
3052 if (slot < btrfs_header_nritems(path->nodes[i]) - 1) { 3142 if (slot < btrfs_header_nritems(path->nodes[i]) - 1) {
3053 struct extent_buffer *node; 3143 struct extent_buffer *node;
@@ -3070,12 +3160,18 @@ static int noinline walk_up_tree(struct btrfs_trans_handle *trans,
3070 3160
3071 root_owner = btrfs_header_owner(parent); 3161 root_owner = btrfs_header_owner(parent);
3072 root_gen = btrfs_header_generation(parent); 3162 root_gen = btrfs_header_generation(parent);
3163
3164 clean_tree_block(trans, root, path->nodes[*level]);
3073 ret = btrfs_free_extent(trans, root, 3165 ret = btrfs_free_extent(trans, root,
3074 path->nodes[*level]->start, 3166 path->nodes[*level]->start,
3075 path->nodes[*level]->len, 3167 path->nodes[*level]->len,
3076 parent->start, root_owner, 3168 parent->start, root_owner,
3077 root_gen, *level, 1); 3169 root_gen, *level, 1);
3078 BUG_ON(ret); 3170 BUG_ON(ret);
3171 if (path->locks[*level]) {
3172 btrfs_tree_unlock(path->nodes[*level]);
3173 path->locks[*level] = 0;
3174 }
3079 free_extent_buffer(path->nodes[*level]); 3175 free_extent_buffer(path->nodes[*level]);
3080 path->nodes[*level] = NULL; 3176 path->nodes[*level] = NULL;
3081 *level = i + 1; 3177 *level = i + 1;
@@ -3145,7 +3241,8 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
3145 if (wret < 0) 3241 if (wret < 0)
3146 ret = wret; 3242 ret = wret;
3147 3243
3148 wret = walk_up_tree(trans, root, path, &level); 3244 wret = walk_up_tree(trans, root, path, &level,
3245 BTRFS_MAX_LEVEL);
3149 if (wret > 0) 3246 if (wret > 0)
3150 break; 3247 break;
3151 if (wret < 0) 3248 if (wret < 0)
@@ -3168,6 +3265,50 @@ out:
3168 return ret; 3265 return ret;
3169} 3266}
3170 3267
3268int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
3269 struct btrfs_root *root,
3270 struct extent_buffer *node,
3271 struct extent_buffer *parent)
3272{
3273 struct btrfs_path *path;
3274 int level;
3275 int parent_level;
3276 int ret = 0;
3277 int wret;
3278
3279 path = btrfs_alloc_path();
3280 BUG_ON(!path);
3281
3282 BUG_ON(!btrfs_tree_locked(parent));
3283 parent_level = btrfs_header_level(parent);
3284 extent_buffer_get(parent);
3285 path->nodes[parent_level] = parent;
3286 path->slots[parent_level] = btrfs_header_nritems(parent);
3287
3288 BUG_ON(!btrfs_tree_locked(node));
3289 level = btrfs_header_level(node);
3290 extent_buffer_get(node);
3291 path->nodes[level] = node;
3292 path->slots[level] = 0;
3293
3294 while (1) {
3295 wret = walk_down_subtree(trans, root, path, &level);
3296 if (wret < 0)
3297 ret = wret;
3298 if (wret != 0)
3299 break;
3300
3301 wret = walk_up_tree(trans, root, path, &level, parent_level);
3302 if (wret < 0)
3303 ret = wret;
3304 if (wret != 0)
3305 break;
3306 }
3307
3308 btrfs_free_path(path);
3309 return ret;
3310}
3311
3171static unsigned long calc_ra(unsigned long start, unsigned long last, 3312static unsigned long calc_ra(unsigned long start, unsigned long last,
3172 unsigned long nr) 3313 unsigned long nr)
3173{ 3314{
@@ -3312,6 +3453,10 @@ struct btrfs_ref_path {
3312 u32 num_refs; 3453 u32 num_refs;
3313 int lowest_level; 3454 int lowest_level;
3314 int current_level; 3455 int current_level;
3456 int shared_level;
3457
3458 struct btrfs_key node_keys[BTRFS_MAX_LEVEL];
3459 u64 new_nodes[BTRFS_MAX_LEVEL];
3315}; 3460};
3316 3461
3317struct disk_extent { 3462struct disk_extent {
@@ -3360,6 +3505,7 @@ static int noinline __next_ref_path(struct btrfs_trans_handle *trans,
3360 if (first_time) { 3505 if (first_time) {
3361 ref_path->lowest_level = -1; 3506 ref_path->lowest_level = -1;
3362 ref_path->current_level = -1; 3507 ref_path->current_level = -1;
3508 ref_path->shared_level = -1;
3363 goto walk_up; 3509 goto walk_up;
3364 } 3510 }
3365walk_down: 3511walk_down:
@@ -3403,8 +3549,11 @@ walk_down:
3403 3549
3404 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); 3550 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
3405 if (found_key.objectid == bytenr && 3551 if (found_key.objectid == bytenr &&
3406 found_key.type == BTRFS_EXTENT_REF_KEY) 3552 found_key.type == BTRFS_EXTENT_REF_KEY) {
3553 if (level < ref_path->shared_level)
3554 ref_path->shared_level = level;
3407 goto found; 3555 goto found;
3556 }
3408next: 3557next:
3409 level--; 3558 level--;
3410 btrfs_release_path(extent_root, path); 3559 btrfs_release_path(extent_root, path);
@@ -3992,51 +4141,6 @@ out:
3992 return ret; 4141 return ret;
3993} 4142}
3994 4143
3995int btrfs_add_reloc_mapping(struct btrfs_root *root, u64 orig_bytenr,
3996 u64 num_bytes, u64 new_bytenr)
3997{
3998 set_extent_bits(&root->fs_info->reloc_mapping_tree,
3999 orig_bytenr, orig_bytenr + num_bytes - 1,
4000 EXTENT_LOCKED, GFP_NOFS);
4001 set_state_private(&root->fs_info->reloc_mapping_tree,
4002 orig_bytenr, new_bytenr);
4003 return 0;
4004}
4005
4006int btrfs_get_reloc_mapping(struct btrfs_root *root, u64 orig_bytenr,
4007 u64 num_bytes, u64 *new_bytenr)
4008{
4009 u64 bytenr;
4010 u64 cur_bytenr = orig_bytenr;
4011 u64 prev_bytenr = orig_bytenr;
4012 int ret;
4013
4014 while (1) {
4015 ret = get_state_private(&root->fs_info->reloc_mapping_tree,
4016 cur_bytenr, &bytenr);
4017 if (ret)
4018 break;
4019 prev_bytenr = cur_bytenr;
4020 cur_bytenr = bytenr;
4021 }
4022
4023 if (orig_bytenr == cur_bytenr)
4024 return -ENOENT;
4025
4026 if (prev_bytenr != orig_bytenr) {
4027 set_state_private(&root->fs_info->reloc_mapping_tree,
4028 orig_bytenr, cur_bytenr);
4029 }
4030 *new_bytenr = cur_bytenr;
4031 return 0;
4032}
4033
4034void btrfs_free_reloc_mappings(struct btrfs_root *root)
4035{
4036 clear_extent_bits(&root->fs_info->reloc_mapping_tree,
4037 0, (u64)-1, -1, GFP_NOFS);
4038}
4039
4040int btrfs_reloc_tree_cache_ref(struct btrfs_trans_handle *trans, 4144int btrfs_reloc_tree_cache_ref(struct btrfs_trans_handle *trans,
4041 struct btrfs_root *root, 4145 struct btrfs_root *root,
4042 struct extent_buffer *buf, u64 orig_start) 4146 struct extent_buffer *buf, u64 orig_start)
@@ -4222,15 +4326,30 @@ static int noinline replace_extents_in_leaf(struct btrfs_trans_handle *trans,
4222 return 0; 4326 return 0;
4223} 4327}
4224 4328
4225int btrfs_free_reloc_root(struct btrfs_root *root) 4329int btrfs_free_reloc_root(struct btrfs_trans_handle *trans,
4330 struct btrfs_root *root)
4226{ 4331{
4227 struct btrfs_root *reloc_root; 4332 struct btrfs_root *reloc_root;
4333 int ret;
4228 4334
4229 if (root->reloc_root) { 4335 if (root->reloc_root) {
4230 reloc_root = root->reloc_root; 4336 reloc_root = root->reloc_root;
4231 root->reloc_root = NULL; 4337 root->reloc_root = NULL;
4232 list_add(&reloc_root->dead_list, 4338 list_add(&reloc_root->dead_list,
4233 &root->fs_info->dead_reloc_roots); 4339 &root->fs_info->dead_reloc_roots);
4340
4341 btrfs_set_root_bytenr(&reloc_root->root_item,
4342 reloc_root->node->start);
4343 btrfs_set_root_level(&root->root_item,
4344 btrfs_header_level(reloc_root->node));
4345 memset(&reloc_root->root_item.drop_progress, 0,
4346 sizeof(struct btrfs_disk_key));
4347 reloc_root->root_item.drop_level = 0;
4348
4349 ret = btrfs_update_root(trans, root->fs_info->tree_root,
4350 &reloc_root->root_key,
4351 &reloc_root->root_item);
4352 BUG_ON(ret);
4234 } 4353 }
4235 return 0; 4354 return 0;
4236} 4355}
@@ -4356,8 +4475,6 @@ static int noinline init_reloc_tree(struct btrfs_trans_handle *trans,
4356 btrfs_set_root_refs(root_item, 0); 4475 btrfs_set_root_refs(root_item, 0);
4357 btrfs_set_root_bytenr(root_item, eb->start); 4476 btrfs_set_root_bytenr(root_item, eb->start);
4358 btrfs_set_root_level(root_item, btrfs_header_level(eb)); 4477 btrfs_set_root_level(root_item, btrfs_header_level(eb));
4359 memset(&root_item->drop_progress, 0, sizeof(root_item->drop_progress));
4360 root_item->drop_level = 0;
4361 4478
4362 btrfs_tree_unlock(eb); 4479 btrfs_tree_unlock(eb);
4363 free_extent_buffer(eb); 4480 free_extent_buffer(eb);
@@ -4382,15 +4499,19 @@ static int noinline init_reloc_tree(struct btrfs_trans_handle *trans,
4382 * Core function of space balance. 4499 * Core function of space balance.
4383 * 4500 *
4384 * The idea is using reloc trees to relocate tree blocks in reference 4501 * The idea is using reloc trees to relocate tree blocks in reference
4385 * counted roots. There is one reloc tree for each subvol, all reloc 4502 * counted roots. There is one reloc tree for each subvol, and all
4386 * trees share same key objectid. Reloc trees are snapshots of the 4503 * reloc trees share same root key objectid. Reloc trees are snapshots
4387 * latest committed roots (subvol root->commit_root). To relocate a tree 4504 * of the latest committed roots of subvols (root->commit_root).
4388 * block referenced by a subvol, the code COW the block through the reloc 4505 *
4389 * tree, then update pointer in the subvol to point to the new block. 4506 * To relocate a tree block referenced by a subvol, there are two steps.
4390 * Since all reloc trees share same key objectid, we can easily do special 4507 * COW the block through subvol's reloc tree, then update block pointer
4391 * handing to share tree blocks between reloc trees. Once a tree block has 4508 * in the subvol to point to the new block. Since all reloc trees share
4392 * been COWed in one reloc tree, we can use the result when the same block 4509 * same root key objectid, doing special handing for tree blocks owned
4393 * is COWed again through other reloc trees. 4510 * by them is easy. Once a tree block has been COWed in one reloc tree,
4511 * we can use the resulting new block directly when the same block is
4512 * required to COW again through other reloc trees. By this way, relocated
4513 * tree blocks are shared between reloc trees, so they are also shared
4514 * between subvols.
4394 */ 4515 */
4395static int noinline relocate_one_path(struct btrfs_trans_handle *trans, 4516static int noinline relocate_one_path(struct btrfs_trans_handle *trans,
4396 struct btrfs_root *root, 4517 struct btrfs_root *root,
@@ -4405,15 +4526,14 @@ static int noinline relocate_one_path(struct btrfs_trans_handle *trans,
4405 struct btrfs_key *keys; 4526 struct btrfs_key *keys;
4406 u64 *nodes; 4527 u64 *nodes;
4407 int level; 4528 int level;
4408 int lowest_merge; 4529 int shared_level;
4409 int lowest_level = 0; 4530 int lowest_level = 0;
4410 int update_refs;
4411 int ret; 4531 int ret;
4412 4532
4413 if (ref_path->owner_objectid < BTRFS_FIRST_FREE_OBJECTID) 4533 if (ref_path->owner_objectid < BTRFS_FIRST_FREE_OBJECTID)
4414 lowest_level = ref_path->owner_objectid; 4534 lowest_level = ref_path->owner_objectid;
4415 4535
4416 if (is_cowonly_root(ref_path->root_objectid)) { 4536 if (!root->ref_cows) {
4417 path->lowest_level = lowest_level; 4537 path->lowest_level = lowest_level;
4418 ret = btrfs_search_slot(trans, root, first_key, path, 0, 1); 4538 ret = btrfs_search_slot(trans, root, first_key, path, 0, 1);
4419 BUG_ON(ret < 0); 4539 BUG_ON(ret < 0);
@@ -4422,91 +4542,49 @@ static int noinline relocate_one_path(struct btrfs_trans_handle *trans,
4422 return 0; 4542 return 0;
4423 } 4543 }
4424 4544
4425 keys = kzalloc(sizeof(*keys) * BTRFS_MAX_LEVEL, GFP_NOFS);
4426 BUG_ON(!keys);
4427 nodes = kzalloc(sizeof(*nodes) * BTRFS_MAX_LEVEL, GFP_NOFS);
4428 BUG_ON(!nodes);
4429
4430 mutex_lock(&root->fs_info->tree_reloc_mutex); 4545 mutex_lock(&root->fs_info->tree_reloc_mutex);
4431 ret = init_reloc_tree(trans, root); 4546 ret = init_reloc_tree(trans, root);
4432 BUG_ON(ret); 4547 BUG_ON(ret);
4433 reloc_root = root->reloc_root; 4548 reloc_root = root->reloc_root;
4434 4549
4435 path->lowest_level = lowest_level; 4550 shared_level = ref_path->shared_level;
4436 ret = btrfs_search_slot(trans, reloc_root, first_key, path, 0, 0); 4551 ref_path->shared_level = BTRFS_MAX_LEVEL - 1;
4437 BUG_ON(ret);
4438 /*
4439 * get relocation mapping for tree blocks in the path
4440 */
4441 lowest_merge = BTRFS_MAX_LEVEL;
4442 for (level = BTRFS_MAX_LEVEL - 1; level >= lowest_level; level--) {
4443 u64 new_bytenr;
4444 eb = path->nodes[level];
4445 if (!eb || eb == reloc_root->node)
4446 continue;
4447 ret = btrfs_get_reloc_mapping(reloc_root, eb->start, eb->len,
4448 &new_bytenr);
4449 if (ret)
4450 continue;
4451 if (level == 0)
4452 btrfs_item_key_to_cpu(eb, &keys[level], 0);
4453 else
4454 btrfs_node_key_to_cpu(eb, &keys[level], 0);
4455 nodes[level] = new_bytenr;
4456 lowest_merge = level;
4457 }
4458 4552
4459 update_refs = 0; 4553 keys = ref_path->node_keys;
4460 if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { 4554 nodes = ref_path->new_nodes;
4461 eb = path->nodes[0]; 4555 memset(&keys[shared_level + 1], 0,
4462 if (btrfs_header_generation(eb) < trans->transid) 4556 sizeof(*keys) * (BTRFS_MAX_LEVEL - shared_level - 1));
4463 update_refs = 1; 4557 memset(&nodes[shared_level + 1], 0,
4464 } 4558 sizeof(*nodes) * (BTRFS_MAX_LEVEL - shared_level - 1));
4465 4559
4466 btrfs_release_path(reloc_root, path); 4560 if (nodes[lowest_level] == 0) {
4467 /* 4561 path->lowest_level = lowest_level;
4468 * merge tree blocks that already relocated in other reloc trees 4562 ret = btrfs_search_slot(trans, reloc_root, first_key, path,
4469 */ 4563 0, 1);
4470 if (lowest_merge != BTRFS_MAX_LEVEL) { 4564 BUG_ON(ret);
4565 for (level = lowest_level; level < BTRFS_MAX_LEVEL; level++) {
4566 eb = path->nodes[level];
4567 if (!eb || eb == reloc_root->node)
4568 break;
4569 nodes[level] = eb->start;
4570 if (level == 0)
4571 btrfs_item_key_to_cpu(eb, &keys[level], 0);
4572 else
4573 btrfs_node_key_to_cpu(eb, &keys[level], 0);
4574 }
4575 if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) {
4576 eb = path->nodes[0];
4577 ret = replace_extents_in_leaf(trans, reloc_root, eb,
4578 group, reloc_inode);
4579 BUG_ON(ret);
4580 }
4581 btrfs_release_path(reloc_root, path);
4582 } else {
4471 ret = btrfs_merge_path(trans, reloc_root, keys, nodes, 4583 ret = btrfs_merge_path(trans, reloc_root, keys, nodes,
4472 lowest_merge); 4584 lowest_level);
4473 BUG_ON(ret < 0);
4474 }
4475 /*
4476 * cow any tree blocks that still haven't been relocated
4477 */
4478 ret = btrfs_search_slot(trans, reloc_root, first_key, path, 0, 1);
4479 BUG_ON(ret);
4480 /*
4481 * if we are relocating data block group, update extent pointers
4482 * in the newly created tree leaf.
4483 */
4484 eb = path->nodes[0];
4485 if (update_refs && nodes[0] != eb->start) {
4486 ret = replace_extents_in_leaf(trans, reloc_root, eb, group,
4487 reloc_inode);
4488 BUG_ON(ret); 4585 BUG_ON(ret);
4489 } 4586 }
4490 4587
4491 memset(keys, 0, sizeof(*keys) * BTRFS_MAX_LEVEL);
4492 memset(nodes, 0, sizeof(*nodes) * BTRFS_MAX_LEVEL);
4493 for (level = BTRFS_MAX_LEVEL - 1; level >= lowest_level; level--) {
4494 eb = path->nodes[level];
4495 if (!eb || eb == reloc_root->node)
4496 continue;
4497 BUG_ON(btrfs_header_owner(eb) != BTRFS_TREE_RELOC_OBJECTID);
4498 nodes[level] = eb->start;
4499 if (level == 0)
4500 btrfs_item_key_to_cpu(eb, &keys[level], 0);
4501 else
4502 btrfs_node_key_to_cpu(eb, &keys[level], 0);
4503 }
4504
4505 if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) {
4506 eb = path->nodes[0];
4507 extent_buffer_get(eb);
4508 }
4509 btrfs_release_path(reloc_root, path);
4510 /* 4588 /*
4511 * replace tree blocks in the fs tree with tree blocks in 4589 * replace tree blocks in the fs tree with tree blocks in
4512 * the reloc tree. 4590 * the reloc tree.
@@ -4515,15 +4593,19 @@ static int noinline relocate_one_path(struct btrfs_trans_handle *trans,
4515 BUG_ON(ret < 0); 4593 BUG_ON(ret < 0);
4516 4594
4517 if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { 4595 if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) {
4596 ret = btrfs_search_slot(trans, reloc_root, first_key, path,
4597 0, 0);
4598 BUG_ON(ret);
4599 extent_buffer_get(path->nodes[0]);
4600 eb = path->nodes[0];
4601 btrfs_release_path(reloc_root, path);
4518 ret = invalidate_extent_cache(reloc_root, eb, group, root); 4602 ret = invalidate_extent_cache(reloc_root, eb, group, root);
4519 BUG_ON(ret); 4603 BUG_ON(ret);
4520 free_extent_buffer(eb); 4604 free_extent_buffer(eb);
4521 } 4605 }
4522 mutex_unlock(&root->fs_info->tree_reloc_mutex);
4523 4606
4607 mutex_unlock(&root->fs_info->tree_reloc_mutex);
4524 path->lowest_level = 0; 4608 path->lowest_level = 0;
4525 kfree(nodes);
4526 kfree(keys);
4527 return 0; 4609 return 0;
4528} 4610}
4529 4611