diff options
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 82 |
1 files changed, 61 insertions, 21 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 893fd56960a0..4bf5e92584bd 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -615,9 +615,9 @@ int del_ptr(struct ctree_root *root, struct ctree_path *path, int level) | |||
615 | if (node->header.nritems) { | 615 | if (node->header.nritems) { |
616 | push_node_right(root, path, level); | 616 | push_node_right(root, path, level); |
617 | } | 617 | } |
618 | path->slots[level+1] = tslot; | ||
619 | if (node->header.nritems) | 618 | if (node->header.nritems) |
620 | break; | 619 | break; |
620 | path->slots[level+1] = tslot; | ||
621 | } | 621 | } |
622 | if (node == root->node) { | 622 | if (node == root->node) { |
623 | printf("root is now null!\n"); | 623 | printf("root is now null!\n"); |
@@ -632,22 +632,15 @@ int del_ptr(struct ctree_root *root, struct ctree_path *path, int level) | |||
632 | return 0; | 632 | return 0; |
633 | } | 633 | } |
634 | 634 | ||
635 | int del_item(struct ctree_root *root, struct key *key) | 635 | int del_item(struct ctree_root *root, struct ctree_path *path) |
636 | { | 636 | { |
637 | int ret; | ||
638 | int slot; | 637 | int slot; |
639 | struct leaf *leaf; | 638 | struct leaf *leaf; |
640 | struct ctree_path path; | ||
641 | int doff; | 639 | int doff; |
642 | int dsize; | 640 | int dsize; |
643 | 641 | ||
644 | init_path(&path); | 642 | leaf = (struct leaf *)path->nodes[0]; |
645 | ret = search_slot(root, key, &path); | 643 | slot = path->slots[0]; |
646 | if (ret != 0) | ||
647 | return -1; | ||
648 | |||
649 | leaf = (struct leaf *)path.nodes[0]; | ||
650 | slot = path.slots[0]; | ||
651 | doff = leaf->items[slot].offset; | 644 | doff = leaf->items[slot].offset; |
652 | dsize = leaf->items[slot].size; | 645 | dsize = leaf->items[slot].size; |
653 | 646 | ||
@@ -665,23 +658,26 @@ int del_item(struct ctree_root *root, struct key *key) | |||
665 | } | 658 | } |
666 | leaf->header.nritems -= 1; | 659 | leaf->header.nritems -= 1; |
667 | if (leaf->header.nritems == 0) { | 660 | if (leaf->header.nritems == 0) { |
661 | if (leaf == (struct leaf *)root->node) | ||
662 | root->node = NULL; | ||
663 | else | ||
664 | del_ptr(root, path, 1); | ||
668 | free(leaf); | 665 | free(leaf); |
669 | del_ptr(root, &path, 1); | ||
670 | } else { | 666 | } else { |
671 | if (slot == 0) | 667 | if (slot == 0) |
672 | fixup_low_keys(&path, &leaf->items[0].key, 1); | 668 | fixup_low_keys(path, &leaf->items[0].key, 1); |
673 | if (leaf_space_used(leaf, 0, leaf->header.nritems) < | 669 | if (leaf_space_used(leaf, 0, leaf->header.nritems) < |
674 | LEAF_DATA_SIZE / 4) { | 670 | LEAF_DATA_SIZE / 4) { |
675 | /* push_leaf_left fixes the path. | 671 | /* push_leaf_left fixes the path. |
676 | * make sure the path still points to our leaf | 672 | * make sure the path still points to our leaf |
677 | * for possible call to del_ptr below | 673 | * for possible call to del_ptr below |
678 | */ | 674 | */ |
679 | slot = path.slots[1]; | 675 | slot = path->slots[1]; |
680 | push_leaf_left(root, &path, 1); | 676 | push_leaf_left(root, path, 1); |
681 | path.slots[1] = slot; | ||
682 | if (leaf->header.nritems == 0) { | 677 | if (leaf->header.nritems == 0) { |
683 | free(leaf); | 678 | free(leaf); |
684 | del_ptr(root, &path, 1); | 679 | path->slots[1] = slot; |
680 | del_ptr(root, path, 1); | ||
685 | } | 681 | } |
686 | } | 682 | } |
687 | } | 683 | } |
@@ -753,11 +749,12 @@ int main() { | |||
753 | struct leaf *first_node = malloc(sizeof(struct leaf)); | 749 | struct leaf *first_node = malloc(sizeof(struct leaf)); |
754 | struct ctree_root root; | 750 | struct ctree_root root; |
755 | struct key ins; | 751 | struct key ins; |
752 | struct key last = { (u64)-1, 0, 0}; | ||
756 | char *buf; | 753 | char *buf; |
757 | int i; | 754 | int i; |
758 | int num; | 755 | int num; |
759 | int ret; | 756 | int ret; |
760 | int run_size = 10000000; | 757 | int run_size = 100000; |
761 | int max_key = 100000000; | 758 | int max_key = 100000000; |
762 | int tree_size = 0; | 759 | int tree_size = 0; |
763 | struct ctree_path path; | 760 | struct ctree_path path; |
@@ -783,8 +780,6 @@ int main() { | |||
783 | for (i = 0; i < run_size; i++) { | 780 | for (i = 0; i < run_size; i++) { |
784 | num = next_key(i, max_key); | 781 | num = next_key(i, max_key); |
785 | ins.objectid = num; | 782 | ins.objectid = num; |
786 | ins.offset = 0; | ||
787 | ins.flags = 0; | ||
788 | init_path(&path); | 783 | init_path(&path); |
789 | ret = search_slot(&root, &ins, &path); | 784 | ret = search_slot(&root, &ins, &path); |
790 | if (ret) { | 785 | if (ret) { |
@@ -800,11 +795,56 @@ int main() { | |||
800 | printf("all searches good\n"); | 795 | printf("all searches good\n"); |
801 | i = 0; | 796 | i = 0; |
802 | srand(55); | 797 | srand(55); |
798 | for (i = 0 ; i < run_size/4; i++) { | ||
799 | num = next_key(i, max_key); | ||
800 | ins.objectid = num; | ||
801 | init_path(&path); | ||
802 | ret = search_slot(&root, &ins, &path); | ||
803 | if (ret) | ||
804 | continue; | ||
805 | ret = del_item(&root, &path); | ||
806 | if (ret != 0) | ||
807 | BUG(); | ||
808 | tree_size--; | ||
809 | } | ||
810 | srand(128); | ||
803 | for (i = 0; i < run_size; i++) { | 811 | for (i = 0; i < run_size; i++) { |
812 | buf = malloc(64); | ||
804 | num = next_key(i, max_key); | 813 | num = next_key(i, max_key); |
814 | sprintf(buf, "string-%d", num); | ||
805 | ins.objectid = num; | 815 | ins.objectid = num; |
806 | del_item(&root, &ins); | 816 | ret = insert_item(&root, &ins, buf, strlen(buf)); |
817 | if (!ret) | ||
818 | tree_size++; | ||
819 | } | ||
820 | while(root.node) { | ||
821 | struct leaf *leaf; | ||
822 | int slot; | ||
823 | ins.objectid = (u64)-1; | ||
824 | init_path(&path); | ||
825 | ret = search_slot(&root, &ins, &path); | ||
826 | if (ret == 0) | ||
827 | BUG(); | ||
828 | |||
829 | leaf = (struct leaf *)(path.nodes[0]); | ||
830 | slot = path.slots[0]; | ||
831 | if (slot != leaf->header.nritems) | ||
832 | BUG(); | ||
833 | while(path.slots[0] > 0) { | ||
834 | path.slots[0] -= 1; | ||
835 | slot = path.slots[0]; | ||
836 | leaf = (struct leaf *)(path.nodes[0]); | ||
837 | |||
838 | if (comp_keys(&last, &leaf->items[slot].key) <= 0) | ||
839 | BUG(); | ||
840 | memcpy(&last, &leaf->items[slot].key, sizeof(last)); | ||
841 | ret = del_item(&root, &path); | ||
842 | if (ret != 0) | ||
843 | BUG(); | ||
844 | tree_size--; | ||
845 | } | ||
807 | } | 846 | } |
808 | print_tree(root.node); | 847 | print_tree(root.node); |
848 | printf("tree size is now %d\n", tree_size); | ||
809 | return 0; | 849 | return 0; |
810 | } | 850 | } |