diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 306 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 2 | ||||
-rw-r--r-- | fs/btrfs/ref-cache.c | 1 | ||||
-rw-r--r-- | fs/btrfs/ref-cache.h | 1 |
4 files changed, 265 insertions, 45 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index ed1e25d72483..1d3e9262a9da 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -1533,6 +1533,11 @@ out: | |||
1533 | * struct refsort is used to match byte number to slot in the btree block. | 1533 | * struct refsort is used to match byte number to slot in the btree block. |
1534 | * we sort based on the byte number and then use the slot to actually | 1534 | * we sort based on the byte number and then use the slot to actually |
1535 | * find the item. | 1535 | * find the item. |
1536 | * | ||
1537 | * struct refsort is smaller than strcut btrfs_item and smaller than | ||
1538 | * struct btrfs_key_ptr. Since we're currently limited to the page size | ||
1539 | * for a btree block, there's no way for a kmalloc of refsorts for a | ||
1540 | * single node to be bigger than a page. | ||
1536 | */ | 1541 | */ |
1537 | struct refsort { | 1542 | struct refsort { |
1538 | u64 bytenr; | 1543 | u64 bytenr; |
@@ -3457,36 +3462,73 @@ int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
3457 | { | 3462 | { |
3458 | u64 leaf_owner; | 3463 | u64 leaf_owner; |
3459 | u64 leaf_generation; | 3464 | u64 leaf_generation; |
3465 | struct refsort *sorted; | ||
3460 | struct btrfs_key key; | 3466 | struct btrfs_key key; |
3461 | struct btrfs_file_extent_item *fi; | 3467 | struct btrfs_file_extent_item *fi; |
3462 | int i; | 3468 | int i; |
3463 | int nritems; | 3469 | int nritems; |
3464 | int ret; | 3470 | int ret; |
3471 | int refi = 0; | ||
3472 | int slot; | ||
3465 | 3473 | ||
3466 | BUG_ON(!btrfs_is_leaf(leaf)); | 3474 | BUG_ON(!btrfs_is_leaf(leaf)); |
3467 | nritems = btrfs_header_nritems(leaf); | 3475 | nritems = btrfs_header_nritems(leaf); |
3468 | leaf_owner = btrfs_header_owner(leaf); | 3476 | leaf_owner = btrfs_header_owner(leaf); |
3469 | leaf_generation = btrfs_header_generation(leaf); | 3477 | leaf_generation = btrfs_header_generation(leaf); |
3470 | 3478 | ||
3479 | sorted = kmalloc(sizeof(*sorted) * nritems, GFP_NOFS); | ||
3480 | /* we do this loop twice. The first time we build a list | ||
3481 | * of the extents we have a reference on, then we sort the list | ||
3482 | * by bytenr. The second time around we actually do the | ||
3483 | * extent freeing. | ||
3484 | */ | ||
3471 | for (i = 0; i < nritems; i++) { | 3485 | for (i = 0; i < nritems; i++) { |
3472 | u64 disk_bytenr; | 3486 | u64 disk_bytenr; |
3473 | cond_resched(); | 3487 | cond_resched(); |
3474 | 3488 | ||
3475 | btrfs_item_key_to_cpu(leaf, &key, i); | 3489 | btrfs_item_key_to_cpu(leaf, &key, i); |
3490 | |||
3491 | /* only extents have references, skip everything else */ | ||
3476 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 3492 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
3477 | continue; | 3493 | continue; |
3494 | |||
3478 | fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); | 3495 | fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); |
3496 | |||
3497 | /* inline extents live in the btree, they don't have refs */ | ||
3479 | if (btrfs_file_extent_type(leaf, fi) == | 3498 | if (btrfs_file_extent_type(leaf, fi) == |
3480 | BTRFS_FILE_EXTENT_INLINE) | 3499 | BTRFS_FILE_EXTENT_INLINE) |
3481 | continue; | 3500 | continue; |
3482 | /* | 3501 | |
3483 | * FIXME make sure to insert a trans record that | ||
3484 | * repeats the snapshot del on crash | ||
3485 | */ | ||
3486 | disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); | 3502 | disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); |
3503 | |||
3504 | /* holes don't have refs */ | ||
3487 | if (disk_bytenr == 0) | 3505 | if (disk_bytenr == 0) |
3488 | continue; | 3506 | continue; |
3489 | 3507 | ||
3508 | sorted[refi].bytenr = disk_bytenr; | ||
3509 | sorted[refi].slot = i; | ||
3510 | refi++; | ||
3511 | } | ||
3512 | |||
3513 | if (refi == 0) | ||
3514 | goto out; | ||
3515 | |||
3516 | sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); | ||
3517 | |||
3518 | for (i = 0; i < refi; i++) { | ||
3519 | u64 disk_bytenr; | ||
3520 | |||
3521 | disk_bytenr = sorted[i].bytenr; | ||
3522 | slot = sorted[i].slot; | ||
3523 | |||
3524 | cond_resched(); | ||
3525 | |||
3526 | btrfs_item_key_to_cpu(leaf, &key, slot); | ||
3527 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | ||
3528 | continue; | ||
3529 | |||
3530 | fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); | ||
3531 | |||
3490 | ret = __btrfs_free_extent(trans, root, disk_bytenr, | 3532 | ret = __btrfs_free_extent(trans, root, disk_bytenr, |
3491 | btrfs_file_extent_disk_num_bytes(leaf, fi), | 3533 | btrfs_file_extent_disk_num_bytes(leaf, fi), |
3492 | leaf->start, leaf_owner, leaf_generation, | 3534 | leaf->start, leaf_owner, leaf_generation, |
@@ -3497,6 +3539,8 @@ int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
3497 | wake_up(&root->fs_info->transaction_throttle); | 3539 | wake_up(&root->fs_info->transaction_throttle); |
3498 | cond_resched(); | 3540 | cond_resched(); |
3499 | } | 3541 | } |
3542 | out: | ||
3543 | kfree(sorted); | ||
3500 | return 0; | 3544 | return 0; |
3501 | } | 3545 | } |
3502 | 3546 | ||
@@ -3506,9 +3550,25 @@ static noinline int cache_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
3506 | { | 3550 | { |
3507 | int i; | 3551 | int i; |
3508 | int ret; | 3552 | int ret; |
3509 | struct btrfs_extent_info *info = ref->extents; | 3553 | struct btrfs_extent_info *info; |
3554 | struct refsort *sorted; | ||
3555 | |||
3556 | if (ref->nritems == 0) | ||
3557 | return 0; | ||
3510 | 3558 | ||
3559 | sorted = kmalloc(sizeof(*sorted) * ref->nritems, GFP_NOFS); | ||
3560 | for (i = 0; i < ref->nritems; i++) { | ||
3561 | sorted[i].bytenr = ref->extents[i].bytenr; | ||
3562 | sorted[i].slot = i; | ||
3563 | } | ||
3564 | sort(sorted, ref->nritems, sizeof(struct refsort), refsort_cmp, NULL); | ||
3565 | |||
3566 | /* | ||
3567 | * the items in the ref were sorted when the ref was inserted | ||
3568 | * into the ref cache, so this is already in order | ||
3569 | */ | ||
3511 | for (i = 0; i < ref->nritems; i++) { | 3570 | for (i = 0; i < ref->nritems; i++) { |
3571 | info = ref->extents + sorted[i].slot; | ||
3512 | ret = __btrfs_free_extent(trans, root, info->bytenr, | 3572 | ret = __btrfs_free_extent(trans, root, info->bytenr, |
3513 | info->num_bytes, ref->bytenr, | 3573 | info->num_bytes, ref->bytenr, |
3514 | ref->owner, ref->generation, | 3574 | ref->owner, ref->generation, |
@@ -3566,6 +3626,152 @@ static int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, | |||
3566 | } | 3626 | } |
3567 | 3627 | ||
3568 | /* | 3628 | /* |
3629 | * this is used while deleting old snapshots, and it drops the refs | ||
3630 | * on a whole subtree starting from a level 1 node. | ||
3631 | * | ||
3632 | * The idea is to sort all the leaf pointers, and then drop the | ||
3633 | * ref on all the leaves in order. Most of the time the leaves | ||
3634 | * will have ref cache entries, so no leaf IOs will be required to | ||
3635 | * find the extents they have references on. | ||
3636 | * | ||
3637 | * For each leaf, any references it has are also dropped in order | ||
3638 | * | ||
3639 | * This ends up dropping the references in something close to optimal | ||
3640 | * order for reading and modifying the extent allocation tree. | ||
3641 | */ | ||
3642 | static noinline int drop_level_one_refs(struct btrfs_trans_handle *trans, | ||
3643 | struct btrfs_root *root, | ||
3644 | struct btrfs_path *path) | ||
3645 | { | ||
3646 | u64 bytenr; | ||
3647 | u64 root_owner; | ||
3648 | u64 root_gen; | ||
3649 | struct extent_buffer *eb = path->nodes[1]; | ||
3650 | struct extent_buffer *leaf; | ||
3651 | struct btrfs_leaf_ref *ref; | ||
3652 | struct refsort *sorted = NULL; | ||
3653 | int nritems = btrfs_header_nritems(eb); | ||
3654 | int ret; | ||
3655 | int i; | ||
3656 | int refi = 0; | ||
3657 | int slot = path->slots[1]; | ||
3658 | u32 blocksize = btrfs_level_size(root, 0); | ||
3659 | u32 refs; | ||
3660 | |||
3661 | if (nritems == 0) | ||
3662 | goto out; | ||
3663 | |||
3664 | root_owner = btrfs_header_owner(eb); | ||
3665 | root_gen = btrfs_header_generation(eb); | ||
3666 | sorted = kmalloc(sizeof(*sorted) * nritems, GFP_NOFS); | ||
3667 | |||
3668 | /* | ||
3669 | * step one, sort all the leaf pointers so we don't scribble | ||
3670 | * randomly into the extent allocation tree | ||
3671 | */ | ||
3672 | for (i = slot; i < nritems; i++) { | ||
3673 | sorted[refi].bytenr = btrfs_node_blockptr(eb, i); | ||
3674 | sorted[refi].slot = i; | ||
3675 | refi++; | ||
3676 | } | ||
3677 | |||
3678 | /* | ||
3679 | * nritems won't be zero, but if we're picking up drop_snapshot | ||
3680 | * after a crash, slot might be > 0, so double check things | ||
3681 | * just in case. | ||
3682 | */ | ||
3683 | if (refi == 0) | ||
3684 | goto out; | ||
3685 | |||
3686 | sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); | ||
3687 | |||
3688 | /* | ||
3689 | * the first loop frees everything the leaves point to | ||
3690 | */ | ||
3691 | for (i = 0; i < refi; i++) { | ||
3692 | u64 ptr_gen; | ||
3693 | |||
3694 | bytenr = sorted[i].bytenr; | ||
3695 | |||
3696 | /* | ||
3697 | * check the reference count on this leaf. If it is > 1 | ||
3698 | * we just decrement it below and don't update any | ||
3699 | * of the refs the leaf points to. | ||
3700 | */ | ||
3701 | ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs); | ||
3702 | BUG_ON(ret); | ||
3703 | if (refs != 1) | ||
3704 | continue; | ||
3705 | |||
3706 | ptr_gen = btrfs_node_ptr_generation(eb, sorted[i].slot); | ||
3707 | |||
3708 | /* | ||
3709 | * the leaf only had one reference, which means the | ||
3710 | * only thing pointing to this leaf is the snapshot | ||
3711 | * we're deleting. It isn't possible for the reference | ||
3712 | * count to increase again later | ||
3713 | * | ||
3714 | * The reference cache is checked for the leaf, | ||
3715 | * and if found we'll be able to drop any refs held by | ||
3716 | * the leaf without needing to read it in. | ||
3717 | */ | ||
3718 | ref = btrfs_lookup_leaf_ref(root, bytenr); | ||
3719 | if (ref && ref->generation != ptr_gen) { | ||
3720 | btrfs_free_leaf_ref(root, ref); | ||
3721 | ref = NULL; | ||
3722 | } | ||
3723 | if (ref) { | ||
3724 | ret = cache_drop_leaf_ref(trans, root, ref); | ||
3725 | BUG_ON(ret); | ||
3726 | btrfs_remove_leaf_ref(root, ref); | ||
3727 | btrfs_free_leaf_ref(root, ref); | ||
3728 | } else { | ||
3729 | /* | ||
3730 | * the leaf wasn't in the reference cache, so | ||
3731 | * we have to read it. | ||
3732 | */ | ||
3733 | leaf = read_tree_block(root, bytenr, blocksize, | ||
3734 | ptr_gen); | ||
3735 | ret = btrfs_drop_leaf_ref(trans, root, leaf); | ||
3736 | BUG_ON(ret); | ||
3737 | free_extent_buffer(leaf); | ||
3738 | } | ||
3739 | atomic_inc(&root->fs_info->throttle_gen); | ||
3740 | wake_up(&root->fs_info->transaction_throttle); | ||
3741 | cond_resched(); | ||
3742 | } | ||
3743 | |||
3744 | /* | ||
3745 | * run through the loop again to free the refs on the leaves. | ||
3746 | * This is faster than doing it in the loop above because | ||
3747 | * the leaves are likely to be clustered together. We end up | ||
3748 | * working in nice chunks on the extent allocation tree. | ||
3749 | */ | ||
3750 | for (i = 0; i < refi; i++) { | ||
3751 | bytenr = sorted[i].bytenr; | ||
3752 | ret = __btrfs_free_extent(trans, root, bytenr, | ||
3753 | blocksize, eb->start, | ||
3754 | root_owner, root_gen, 0, 1); | ||
3755 | BUG_ON(ret); | ||
3756 | |||
3757 | atomic_inc(&root->fs_info->throttle_gen); | ||
3758 | wake_up(&root->fs_info->transaction_throttle); | ||
3759 | cond_resched(); | ||
3760 | } | ||
3761 | out: | ||
3762 | kfree(sorted); | ||
3763 | |||
3764 | /* | ||
3765 | * update the path to show we've processed the entire level 1 | ||
3766 | * node. This will get saved into the root's drop_snapshot_progress | ||
3767 | * field so these drops are not repeated again if this transaction | ||
3768 | * commits. | ||
3769 | */ | ||
3770 | path->slots[1] = nritems; | ||
3771 | return 0; | ||
3772 | } | ||
3773 | |||
3774 | /* | ||
3569 | * helper function for drop_snapshot, this walks down the tree dropping ref | 3775 | * helper function for drop_snapshot, this walks down the tree dropping ref |
3570 | * counts as it goes. | 3776 | * counts as it goes. |
3571 | */ | 3777 | */ |
@@ -3580,7 +3786,6 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, | |||
3580 | struct extent_buffer *next; | 3786 | struct extent_buffer *next; |
3581 | struct extent_buffer *cur; | 3787 | struct extent_buffer *cur; |
3582 | struct extent_buffer *parent; | 3788 | struct extent_buffer *parent; |
3583 | struct btrfs_leaf_ref *ref; | ||
3584 | u32 blocksize; | 3789 | u32 blocksize; |
3585 | int ret; | 3790 | int ret; |
3586 | u32 refs; | 3791 | u32 refs; |
@@ -3607,17 +3812,46 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, | |||
3607 | if (path->slots[*level] >= | 3812 | if (path->slots[*level] >= |
3608 | btrfs_header_nritems(cur)) | 3813 | btrfs_header_nritems(cur)) |
3609 | break; | 3814 | break; |
3815 | |||
3816 | /* the new code goes down to level 1 and does all the | ||
3817 | * leaves pointed to that node in bulk. So, this check | ||
3818 | * for level 0 will always be false. | ||
3819 | * | ||
3820 | * But, the disk format allows the drop_snapshot_progress | ||
3821 | * field in the root to leave things in a state where | ||
3822 | * a leaf will need cleaning up here. If someone crashes | ||
3823 | * with the old code and then boots with the new code, | ||
3824 | * we might find a leaf here. | ||
3825 | */ | ||
3610 | if (*level == 0) { | 3826 | if (*level == 0) { |
3611 | ret = btrfs_drop_leaf_ref(trans, root, cur); | 3827 | ret = btrfs_drop_leaf_ref(trans, root, cur); |
3612 | BUG_ON(ret); | 3828 | BUG_ON(ret); |
3613 | break; | 3829 | break; |
3614 | } | 3830 | } |
3831 | |||
3832 | /* | ||
3833 | * once we get to level one, process the whole node | ||
3834 | * at once, including everything below it. | ||
3835 | */ | ||
3836 | if (*level == 1) { | ||
3837 | ret = drop_level_one_refs(trans, root, path); | ||
3838 | BUG_ON(ret); | ||
3839 | break; | ||
3840 | } | ||
3841 | |||
3615 | bytenr = btrfs_node_blockptr(cur, path->slots[*level]); | 3842 | bytenr = btrfs_node_blockptr(cur, path->slots[*level]); |
3616 | ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); | 3843 | ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); |
3617 | blocksize = btrfs_level_size(root, *level - 1); | 3844 | blocksize = btrfs_level_size(root, *level - 1); |
3618 | 3845 | ||
3619 | ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs); | 3846 | ret = drop_snap_lookup_refcount(root, bytenr, blocksize, &refs); |
3620 | BUG_ON(ret); | 3847 | BUG_ON(ret); |
3848 | |||
3849 | /* | ||
3850 | * if there is more than one reference, we don't need | ||
3851 | * to read that node to drop any references it has. We | ||
3852 | * just drop the ref we hold on that node and move on to the | ||
3853 | * next slot in this level. | ||
3854 | */ | ||
3621 | if (refs != 1) { | 3855 | if (refs != 1) { |
3622 | parent = path->nodes[*level]; | 3856 | parent = path->nodes[*level]; |
3623 | root_owner = btrfs_header_owner(parent); | 3857 | root_owner = btrfs_header_owner(parent); |
@@ -3636,46 +3870,12 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, | |||
3636 | 3870 | ||
3637 | continue; | 3871 | continue; |
3638 | } | 3872 | } |
3873 | |||
3639 | /* | 3874 | /* |
3640 | * at this point, we have a single ref, and since the | 3875 | * we need to keep freeing things in the next level down. |
3641 | * only place referencing this extent is a dead root | 3876 | * read the block and loop around to process it |
3642 | * the reference count should never go higher. | ||
3643 | * So, we don't need to check it again | ||
3644 | */ | 3877 | */ |
3645 | if (*level == 1) { | 3878 | next = read_tree_block(root, bytenr, blocksize, ptr_gen); |
3646 | ref = btrfs_lookup_leaf_ref(root, bytenr); | ||
3647 | if (ref && ref->generation != ptr_gen) { | ||
3648 | btrfs_free_leaf_ref(root, ref); | ||
3649 | ref = NULL; | ||
3650 | } | ||
3651 | if (ref) { | ||
3652 | ret = cache_drop_leaf_ref(trans, root, ref); | ||
3653 | BUG_ON(ret); | ||
3654 | btrfs_remove_leaf_ref(root, ref); | ||
3655 | btrfs_free_leaf_ref(root, ref); | ||
3656 | *level = 0; | ||
3657 | break; | ||
3658 | } | ||
3659 | } | ||
3660 | next = btrfs_find_tree_block(root, bytenr, blocksize); | ||
3661 | if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) { | ||
3662 | free_extent_buffer(next); | ||
3663 | |||
3664 | next = read_tree_block(root, bytenr, blocksize, | ||
3665 | ptr_gen); | ||
3666 | cond_resched(); | ||
3667 | #if 0 | ||
3668 | /* | ||
3669 | * this is a debugging check and can go away | ||
3670 | * the ref should never go all the way down to 1 | ||
3671 | * at this point | ||
3672 | */ | ||
3673 | ret = lookup_extent_ref(NULL, root, bytenr, blocksize, | ||
3674 | &refs); | ||
3675 | BUG_ON(ret); | ||
3676 | WARN_ON(refs != 1); | ||
3677 | #endif | ||
3678 | } | ||
3679 | WARN_ON(*level <= 0); | 3879 | WARN_ON(*level <= 0); |
3680 | if (path->nodes[*level-1]) | 3880 | if (path->nodes[*level-1]) |
3681 | free_extent_buffer(path->nodes[*level-1]); | 3881 | free_extent_buffer(path->nodes[*level-1]); |
@@ -3700,11 +3900,16 @@ out: | |||
3700 | root_owner = btrfs_header_owner(parent); | 3900 | root_owner = btrfs_header_owner(parent); |
3701 | root_gen = btrfs_header_generation(parent); | 3901 | root_gen = btrfs_header_generation(parent); |
3702 | 3902 | ||
3903 | /* | ||
3904 | * cleanup and free the reference on the last node | ||
3905 | * we processed | ||
3906 | */ | ||
3703 | ret = __btrfs_free_extent(trans, root, bytenr, blocksize, | 3907 | ret = __btrfs_free_extent(trans, root, bytenr, blocksize, |
3704 | parent->start, root_owner, root_gen, | 3908 | parent->start, root_owner, root_gen, |
3705 | *level, 1); | 3909 | *level, 1); |
3706 | free_extent_buffer(path->nodes[*level]); | 3910 | free_extent_buffer(path->nodes[*level]); |
3707 | path->nodes[*level] = NULL; | 3911 | path->nodes[*level] = NULL; |
3912 | |||
3708 | *level += 1; | 3913 | *level += 1; |
3709 | BUG_ON(ret); | 3914 | BUG_ON(ret); |
3710 | 3915 | ||
@@ -3824,6 +4029,13 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, | |||
3824 | if (slot < btrfs_header_nritems(path->nodes[i]) - 1) { | 4029 | if (slot < btrfs_header_nritems(path->nodes[i]) - 1) { |
3825 | struct extent_buffer *node; | 4030 | struct extent_buffer *node; |
3826 | struct btrfs_disk_key disk_key; | 4031 | struct btrfs_disk_key disk_key; |
4032 | |||
4033 | /* | ||
4034 | * there is more work to do in this level. | ||
4035 | * Update the drop_progress marker to reflect | ||
4036 | * the work we've done so far, and then bump | ||
4037 | * the slot number | ||
4038 | */ | ||
3827 | node = path->nodes[i]; | 4039 | node = path->nodes[i]; |
3828 | path->slots[i]++; | 4040 | path->slots[i]++; |
3829 | *level = i; | 4041 | *level = i; |
@@ -3835,6 +4047,11 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, | |||
3835 | return 0; | 4047 | return 0; |
3836 | } else { | 4048 | } else { |
3837 | struct extent_buffer *parent; | 4049 | struct extent_buffer *parent; |
4050 | |||
4051 | /* | ||
4052 | * this whole node is done, free our reference | ||
4053 | * on it and go up one level | ||
4054 | */ | ||
3838 | if (path->nodes[*level] == root->node) | 4055 | if (path->nodes[*level] == root->node) |
3839 | parent = path->nodes[*level]; | 4056 | parent = path->nodes[*level]; |
3840 | else | 4057 | else |
@@ -4849,6 +5066,7 @@ int btrfs_reloc_tree_cache_ref(struct btrfs_trans_handle *trans, | |||
4849 | ref->bytenr = buf->start; | 5066 | ref->bytenr = buf->start; |
4850 | ref->owner = btrfs_header_owner(buf); | 5067 | ref->owner = btrfs_header_owner(buf); |
4851 | ref->generation = btrfs_header_generation(buf); | 5068 | ref->generation = btrfs_header_generation(buf); |
5069 | |||
4852 | ret = btrfs_add_leaf_ref(root, ref, 0); | 5070 | ret = btrfs_add_leaf_ref(root, ref, 0); |
4853 | WARN_ON(ret); | 5071 | WARN_ON(ret); |
4854 | btrfs_free_leaf_ref(root, ref); | 5072 | btrfs_free_leaf_ref(root, ref); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ebd7d6c37df8..95ea58cb3065 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2441,6 +2441,8 @@ next_node: | |||
2441 | ref->generation = leaf_gen; | 2441 | ref->generation = leaf_gen; |
2442 | ref->nritems = 0; | 2442 | ref->nritems = 0; |
2443 | 2443 | ||
2444 | btrfs_sort_leaf_ref(ref); | ||
2445 | |||
2444 | ret = btrfs_add_leaf_ref(root, ref, 0); | 2446 | ret = btrfs_add_leaf_ref(root, ref, 0); |
2445 | WARN_ON(ret); | 2447 | WARN_ON(ret); |
2446 | btrfs_free_leaf_ref(root, ref); | 2448 | btrfs_free_leaf_ref(root, ref); |
diff --git a/fs/btrfs/ref-cache.c b/fs/btrfs/ref-cache.c index 6f0acc4c9eab..d0cc62bccb94 100644 --- a/fs/btrfs/ref-cache.c +++ b/fs/btrfs/ref-cache.c | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <linux/sort.h> | ||
20 | #include "ctree.h" | 21 | #include "ctree.h" |
21 | #include "ref-cache.h" | 22 | #include "ref-cache.h" |
22 | #include "transaction.h" | 23 | #include "transaction.h" |
diff --git a/fs/btrfs/ref-cache.h b/fs/btrfs/ref-cache.h index 16f3183d7c59..bc283ad2db73 100644 --- a/fs/btrfs/ref-cache.h +++ b/fs/btrfs/ref-cache.h | |||
@@ -73,5 +73,4 @@ int btrfs_add_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref, | |||
73 | int btrfs_remove_leaf_refs(struct btrfs_root *root, u64 max_root_gen, | 73 | int btrfs_remove_leaf_refs(struct btrfs_root *root, u64 max_root_gen, |
74 | int shared); | 74 | int shared); |
75 | int btrfs_remove_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref); | 75 | int btrfs_remove_leaf_ref(struct btrfs_root *root, struct btrfs_leaf_ref *ref); |
76 | |||
77 | #endif | 76 | #endif |