aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-01-26 16:38:42 -0500
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-01-26 16:38:42 -0500
commit4920c9ac9a4bbc6bf9acd8c614987ee6b378e78f (patch)
tree4c23ba9685b87407a8d25e42eefb970e34d934bb /fs
parentbe0e5c097fc206b863ce9fe6b3cfd6974b0110f4 (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/Makefile7
-rw-r--r--fs/btrfs/ctree.c82
-rw-r--r--fs/btrfs/kerncompat.h68
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
2ctree: ctree.o
3 gcc -g -O2 -Wall -o ctree ctree.c
4
5clean:
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
635int del_item(struct ctree_root *root, struct key *key) 635int 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
16typedef unsigned int u32;
17typedef unsigned long u64;
18typedef unsigned char u8;
19typedef unsigned short u16;
20
21typedef unsigned long pgoff_t;
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27struct vma_shared { int prio_tree_node; };
28struct 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
35struct page {
36 unsigned long index;
37};
38
39static inline void preempt_enable(void) { do {; } while(0);}
40static inline void preempt_disable(void) { do {; } while(0);}
41
42static 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
48static 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
54static 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