diff options
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 40f0e0cb804b..7f4cc2b88d09 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -354,7 +354,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
354 | struct btrfs_key *progress) | 354 | struct btrfs_key *progress) |
355 | { | 355 | { |
356 | struct extent_buffer *cur; | 356 | struct extent_buffer *cur; |
357 | struct extent_buffer *tmp; | ||
358 | u64 blocknr; | 357 | u64 blocknr; |
359 | u64 gen; | 358 | u64 gen; |
360 | u64 search_start = *last_ret; | 359 | u64 search_start = *last_ret; |
@@ -370,9 +369,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
370 | int progress_passed = 0; | 369 | int progress_passed = 0; |
371 | struct btrfs_disk_key disk_key; | 370 | struct btrfs_disk_key disk_key; |
372 | 371 | ||
373 | /* FIXME this code needs locking */ | ||
374 | return 0; | ||
375 | |||
376 | parent_level = btrfs_header_level(parent); | 372 | parent_level = btrfs_header_level(parent); |
377 | if (cache_only && parent_level != 1) | 373 | if (cache_only && parent_level != 1) |
378 | return 0; | 374 | return 0; |
@@ -454,20 +450,23 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
454 | if (search_start == 0) | 450 | if (search_start == 0) |
455 | search_start = last_block; | 451 | search_start = last_block; |
456 | 452 | ||
453 | btrfs_tree_lock(cur); | ||
457 | err = __btrfs_cow_block(trans, root, cur, parent, i, | 454 | err = __btrfs_cow_block(trans, root, cur, parent, i, |
458 | &tmp, search_start, | 455 | &cur, search_start, |
459 | min(16 * blocksize, | 456 | min(16 * blocksize, |
460 | (end_slot - i) * blocksize)); | 457 | (end_slot - i) * blocksize)); |
461 | if (err) { | 458 | if (err) { |
459 | btrfs_tree_unlock(cur); | ||
462 | free_extent_buffer(cur); | 460 | free_extent_buffer(cur); |
463 | break; | 461 | break; |
464 | } | 462 | } |
465 | search_start = tmp->start; | 463 | search_start = cur->start; |
466 | last_block = tmp->start; | 464 | last_block = cur->start; |
467 | *last_ret = search_start; | 465 | *last_ret = search_start; |
468 | if (parent_level == 1) | 466 | if (parent_level == 1) |
469 | btrfs_clear_buffer_defrag(tmp); | 467 | btrfs_clear_buffer_defrag(cur); |
470 | free_extent_buffer(tmp); | 468 | btrfs_tree_unlock(cur); |
469 | free_extent_buffer(cur); | ||
471 | } | 470 | } |
472 | if (parent->map_token) { | 471 | if (parent->map_token) { |
473 | unmap_extent_buffer(parent, parent->map_token, | 472 | unmap_extent_buffer(parent, parent->map_token, |
@@ -2970,6 +2969,35 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
2970 | return 1; | 2969 | return 1; |
2971 | } | 2970 | } |
2972 | 2971 | ||
2972 | int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, | ||
2973 | struct btrfs_key *key, int lowest_level) | ||
2974 | { | ||
2975 | int level = lowest_level; | ||
2976 | int slot; | ||
2977 | struct extent_buffer *c; | ||
2978 | |||
2979 | while(level < BTRFS_MAX_LEVEL) { | ||
2980 | if (!path->nodes[level]) | ||
2981 | return 1; | ||
2982 | |||
2983 | slot = path->slots[level] + 1; | ||
2984 | c = path->nodes[level]; | ||
2985 | if (slot >= btrfs_header_nritems(c)) { | ||
2986 | level++; | ||
2987 | if (level == BTRFS_MAX_LEVEL) { | ||
2988 | return 1; | ||
2989 | } | ||
2990 | continue; | ||
2991 | } | ||
2992 | if (level == 0) | ||
2993 | btrfs_item_key_to_cpu(c, key, slot); | ||
2994 | else | ||
2995 | btrfs_node_key_to_cpu(c, key, slot); | ||
2996 | return 0; | ||
2997 | } | ||
2998 | return 1; | ||
2999 | } | ||
3000 | |||
2973 | /* | 3001 | /* |
2974 | * search the tree again to find a leaf with greater keys | 3002 | * search the tree again to find a leaf with greater keys |
2975 | * returns 0 if it found something or 1 if there are no greater leaves. | 3003 | * returns 0 if it found something or 1 if there are no greater leaves. |