diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-01-26 16:38:42 -0500 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-01-26 16:38:42 -0500 |
commit | 4920c9ac9a4bbc6bf9acd8c614987ee6b378e78f (patch) | |
tree | 4c23ba9685b87407a8d25e42eefb970e34d934bb /fs | |
parent | be0e5c097fc206b863ce9fe6b3cfd6974b0110f4 (diff) |
Btrfs: Faster deletes, add Makefile and kerncompat
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/Makefile | 7 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 82 | ||||
-rw-r--r-- | fs/btrfs/kerncompat.h | 68 |
3 files changed, 136 insertions, 21 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile new file mode 100644 index 000000000000..9f84c08baab2 --- /dev/null +++ b/fs/btrfs/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | |||
2 | ctree: ctree.o | ||
3 | gcc -g -O2 -Wall -o ctree ctree.c | ||
4 | |||
5 | clean: | ||
6 | rm ctree ctree.o | ||
7 | |||
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 | } |
diff --git a/fs/btrfs/kerncompat.h b/fs/btrfs/kerncompat.h new file mode 100644 index 000000000000..3a4bb4d661f9 --- /dev/null +++ b/fs/btrfs/kerncompat.h | |||
@@ -0,0 +1,68 @@ | |||
1 | #ifndef __KERNCOMPAT | ||
2 | #define __KERNCOMPAT | ||
3 | #define gfp_t int | ||
4 | #define get_cpu_var(p) (p) | ||
5 | #define __get_cpu_var(p) (p) | ||
6 | #define BITS_PER_LONG 64 | ||
7 | #define __GFP_BITS_SHIFT 20 | ||
8 | #define __GFP_BITS_MASK ((int)((1 << __GFP_BITS_SHIFT) - 1)) | ||
9 | #define __read_mostly | ||
10 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
11 | #define __force | ||
12 | #define PAGE_SHIFT 12 | ||
13 | #define ULONG_MAX (~0UL) | ||
14 | #define BUG() abort() | ||
15 | |||
16 | typedef unsigned int u32; | ||
17 | typedef unsigned long u64; | ||
18 | typedef unsigned char u8; | ||
19 | typedef unsigned short u16; | ||
20 | |||
21 | typedef unsigned long pgoff_t; | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <string.h> | ||
26 | |||
27 | struct vma_shared { int prio_tree_node; }; | ||
28 | struct vm_area_struct { | ||
29 | unsigned long vm_pgoff; | ||
30 | unsigned long vm_start; | ||
31 | unsigned long vm_end; | ||
32 | struct vma_shared shared; | ||
33 | }; | ||
34 | |||
35 | struct page { | ||
36 | unsigned long index; | ||
37 | }; | ||
38 | |||
39 | static inline void preempt_enable(void) { do {; } while(0);} | ||
40 | static inline void preempt_disable(void) { do {; } while(0);} | ||
41 | |||
42 | static inline void __set_bit(int bit, unsigned long *map) { | ||
43 | unsigned long *p = map + bit / BITS_PER_LONG; | ||
44 | bit = bit & (BITS_PER_LONG -1); | ||
45 | *p |= 1UL << bit; | ||
46 | } | ||
47 | |||
48 | static inline int test_bit(int bit, unsigned long *map) { | ||
49 | unsigned long *p = map + bit / BITS_PER_LONG; | ||
50 | bit = bit & (BITS_PER_LONG -1); | ||
51 | return *p & (1UL << bit) ? 1 : 0; | ||
52 | } | ||
53 | |||
54 | static inline void __clear_bit(int bit, unsigned long *map) { | ||
55 | unsigned long *p = map + bit / BITS_PER_LONG; | ||
56 | bit = bit & (BITS_PER_LONG -1); | ||
57 | *p &= ~(1UL << bit); | ||
58 | } | ||
59 | #define BUG_ON(c) do { if (c) abort(); } while (0) | ||
60 | |||
61 | #define container_of(ptr, type, member) ({ \ | ||
62 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ | ||
63 | (type *)( (char *)__mptr - __builtin_offsetof(type,member) );}) | ||
64 | |||
65 | #endif | ||
66 | |||
67 | #define ENOMEM 5 | ||
68 | #define EEXIST 6 | ||