aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-02-21 17:04:57 -0500
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-02-21 17:04:57 -0500
commitcfaa72952fa7b44aa5d967cbc266110900552aef (patch)
tree7ca429e7417d168faa57dab4bc069c23fefb5cc4 /fs/btrfs/ctree.c
parent06ed4b316e8e24b6899ece7186c6a7a0129326ba (diff)
Btrfs: extent fixes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c69
1 files changed, 46 insertions, 23 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 2177744dedd3..2891b582e26f 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -354,6 +354,7 @@ int __insert_ptr(struct ctree_root *root,
354 c->header.nritems = 2; 354 c->header.nritems = 2;
355 c->header.flags = node_level(level); 355 c->header.flags = node_level(level);
356 c->header.blocknr = t->blocknr; 356 c->header.blocknr = t->blocknr;
357 c->header.parentid = root->node->node.header.parentid;
357 lower = &path->nodes[level-1]->node; 358 lower = &path->nodes[level-1]->node;
358 if (is_leaf(lower->header.flags)) 359 if (is_leaf(lower->header.flags))
359 lower_key = &((struct leaf *)lower)->items[0].key; 360 lower_key = &((struct leaf *)lower)->items[0].key;
@@ -363,7 +364,7 @@ int __insert_ptr(struct ctree_root *root,
363 memcpy(c->keys + 1, key, sizeof(struct key)); 364 memcpy(c->keys + 1, key, sizeof(struct key));
364 c->blockptrs[0] = path->nodes[level-1]->blocknr; 365 c->blockptrs[0] = path->nodes[level-1]->blocknr;
365 c->blockptrs[1] = blocknr; 366 c->blockptrs[1] = blocknr;
366 /* the path has an extra ref to root->node */ 367 /* the super has an extra ref to root->node */
367 tree_block_release(root, root->node); 368 tree_block_release(root, root->node);
368 root->node = t; 369 root->node = t;
369 t->count++; 370 t->count++;
@@ -439,6 +440,7 @@ int insert_ptr(struct ctree_root *root,
439 b = &b_buffer->node; 440 b = &b_buffer->node;
440 b->header.flags = c->header.flags; 441 b->header.flags = c->header.flags;
441 b->header.blocknr = b_buffer->blocknr; 442 b->header.blocknr = b_buffer->blocknr;
443 b->header.parentid = root->node->node.header.parentid;
442 mid = (c->header.nritems + 1) / 2; 444 mid = (c->header.nritems + 1) / 2;
443 memcpy(b->keys, c->keys + mid, 445 memcpy(b->keys, c->keys + mid,
444 (c->header.nritems - mid) * sizeof(struct key)); 446 (c->header.nritems - mid) * sizeof(struct key));
@@ -642,6 +644,7 @@ int split_leaf(struct ctree_root *root, struct ctree_path *path, int data_size)
642 right->header.nritems = nritems - mid; 644 right->header.nritems = nritems - mid;
643 right->header.blocknr = right_buffer->blocknr; 645 right->header.blocknr = right_buffer->blocknr;
644 right->header.flags = node_level(0); 646 right->header.flags = node_level(0);
647 right->header.parentid = root->node->node.header.parentid;
645 data_copy_size = l->items[mid].offset + l->items[mid].size - 648 data_copy_size = l->items[mid].offset + l->items[mid].size -
646 leaf_data_end(l); 649 leaf_data_end(l);
647 memcpy(right->items, l->items + mid, 650 memcpy(right->items, l->items + mid,
@@ -689,8 +692,12 @@ int insert_item(struct ctree_root *root, struct key *key,
689 unsigned int data_end; 692 unsigned int data_end;
690 struct ctree_path path; 693 struct ctree_path path;
691 694
695 refill_alloc_extent(root);
696
692 /* create a root if there isn't one */ 697 /* create a root if there isn't one */
693 if (!root->node) { 698 if (!root->node) {
699 BUG();
700#if 0
694 struct tree_buffer *t; 701 struct tree_buffer *t;
695 t = alloc_free_block(root); 702 t = alloc_free_block(root);
696 BUG_ON(!t); 703 BUG_ON(!t);
@@ -699,6 +706,7 @@ int insert_item(struct ctree_root *root, struct key *key,
699 t->node.header.blocknr = t->blocknr; 706 t->node.header.blocknr = t->blocknr;
700 root->node = t; 707 root->node = t;
701 write_tree_block(root, t); 708 write_tree_block(root, t);
709#endif
702 } 710 }
703 init_path(&path); 711 init_path(&path);
704 ret = search_slot(root, key, &path); 712 ret = search_slot(root, key, &path);
@@ -758,7 +766,6 @@ int insert_item(struct ctree_root *root, struct key *key,
758 if (leaf_free_space(leaf) < 0) 766 if (leaf_free_space(leaf) < 0)
759 BUG(); 767 BUG();
760 release_path(root, &path); 768 release_path(root, &path);
761 refill_alloc_extent(root);
762 return 0; 769 return 0;
763} 770}
764 771
@@ -893,7 +900,7 @@ int next_leaf(struct ctree_root *root, struct ctree_path *path)
893 int level = 1; 900 int level = 1;
894 u64 blocknr; 901 u64 blocknr;
895 struct tree_buffer *c; 902 struct tree_buffer *c;
896 struct tree_buffer *next; 903 struct tree_buffer *next = NULL;
897 904
898 while(level < MAX_LEVEL) { 905 while(level < MAX_LEVEL) {
899 if (!path->nodes[level]) 906 if (!path->nodes[level])
@@ -905,6 +912,8 @@ int next_leaf(struct ctree_root *root, struct ctree_path *path)
905 continue; 912 continue;
906 } 913 }
907 blocknr = c->node.blockptrs[slot]; 914 blocknr = c->node.blockptrs[slot];
915 if (next)
916 tree_block_release(root, next);
908 next = read_tree_block(root, blocknr); 917 next = read_tree_block(root, blocknr);
909 break; 918 break;
910 } 919 }
@@ -922,7 +931,7 @@ int next_leaf(struct ctree_root *root, struct ctree_path *path)
922 return 0; 931 return 0;
923} 932}
924 933
925int alloc_extent(struct ctree_root *root, u64 num_blocks, u64 search_start, 934int alloc_extent(struct ctree_root *orig_root, u64 num_blocks, u64 search_start,
926 u64 search_end, u64 owner, struct key *ins) 935 u64 search_end, u64 owner, struct key *ins)
927{ 936{
928 struct ctree_path path; 937 struct ctree_path path;
@@ -934,6 +943,7 @@ int alloc_extent(struct ctree_root *root, u64 num_blocks, u64 search_start,
934 int start_found = 0; 943 int start_found = 0;
935 struct leaf *l; 944 struct leaf *l;
936 struct extent_item extent_item; 945 struct extent_item extent_item;
946 struct ctree_root * root = orig_root->extent_root;
937 947
938 init_path(&path); 948 init_path(&path);
939 ins->objectid = search_start; 949 ins->objectid = search_start;
@@ -974,13 +984,18 @@ int alloc_extent(struct ctree_root *root, u64 num_blocks, u64 search_start,
974 start_found = 1; 984 start_found = 1;
975 last_block = key->objectid + key->offset; 985 last_block = key->objectid + key->offset;
976 path.slots[0]++; 986 path.slots[0]++;
977 printf("last block is not %lu\n", last_block);
978 } 987 }
979 // FIXME -ENOSPC 988 // FIXME -ENOSPC
980insert: 989insert:
990 release_path(root, &path);
981 extent_item.refs = 1; 991 extent_item.refs = 1;
982 extent_item.owner = owner; 992 extent_item.owner = owner;
983 ret = insert_item(root, ins, &extent_item, sizeof(extent_item)); 993 if (root == orig_root && root->reserve_extent->num_blocks == 0) {
994 root->reserve_extent->blocknr = ins->objectid;
995 root->reserve_extent->num_blocks = ins->offset;
996 root->reserve_extent->num_used = 0;
997 }
998 ret = insert_item(root->extent_root, ins, &extent_item, sizeof(extent_item));
984 return ret; 999 return ret;
985} 1000}
986 1001
@@ -991,7 +1006,6 @@ static int refill_alloc_extent(struct ctree_root *root)
991 int ret; 1006 int ret;
992 int min_blocks = MAX_LEVEL * 2; 1007 int min_blocks = MAX_LEVEL * 2;
993 1008
994 printf("refill alloc root %p, numused %lu total %lu\n", root, ae->num_used, ae->num_blocks);
995 if (ae->num_blocks > ae->num_used && ae->num_blocks - ae->num_used > 1009 if (ae->num_blocks > ae->num_used && ae->num_blocks - ae->num_used >
996 min_blocks) 1010 min_blocks)
997 return 0; 1011 return 0;
@@ -1007,9 +1021,9 @@ static int refill_alloc_extent(struct ctree_root *root)
1007 BUG(); 1021 BUG();
1008 return 0; 1022 return 0;
1009 } 1023 }
1010 // FIXME, this recurses 1024 ret = alloc_extent(root,
1011 ret = alloc_extent(root->extent_root, 1025 min_blocks * 2, 0, (unsigned long)-1,
1012 min_blocks * 2, 0, (unsigned long)-1, 0, &key); 1026 root->node->node.header.parentid, &key);
1013 ae->blocknr = key.objectid; 1027 ae->blocknr = key.objectid;
1014 ae->num_blocks = key.offset; 1028 ae->num_blocks = key.offset;
1015 ae->num_used = 0; 1029 ae->num_used = 0;
@@ -1021,6 +1035,7 @@ void print_leaf(struct leaf *l)
1021 int i; 1035 int i;
1022 int nr = l->header.nritems; 1036 int nr = l->header.nritems;
1023 struct item *item; 1037 struct item *item;
1038 struct extent_item *ei;
1024 printf("leaf %lu total ptrs %d free space %d\n", l->header.blocknr, nr, 1039 printf("leaf %lu total ptrs %d free space %d\n", l->header.blocknr, nr,
1025 leaf_free_space(l)); 1040 leaf_free_space(l));
1026 fflush(stdout); 1041 fflush(stdout);
@@ -1032,6 +1047,8 @@ void print_leaf(struct leaf *l)
1032 item->offset, item->size); 1047 item->offset, item->size);
1033 fflush(stdout); 1048 fflush(stdout);
1034 printf("\t\titem data %.*s\n", item->size, l->data+item->offset); 1049 printf("\t\titem data %.*s\n", item->size, l->data+item->offset);
1050 ei = (struct extent_item *)(l->data + item->offset);
1051 printf("\t\textent data %u %lu\n", ei->refs, ei->owner);
1035 fflush(stdout); 1052 fflush(stdout);
1036 } 1053 }
1037} 1054}
@@ -1080,8 +1097,8 @@ void print_tree(struct ctree_root *root, struct tree_buffer *t)
1080 1097
1081/* for testing only */ 1098/* for testing only */
1082int next_key(int i, int max_key) { 1099int next_key(int i, int max_key) {
1083 // return rand() % max_key; 1100 return rand() % max_key;
1084 return i; 1101 // return i;
1085} 1102}
1086 1103
1087int main() { 1104int main() {
@@ -1092,15 +1109,20 @@ int main() {
1092 int i; 1109 int i;
1093 int num; 1110 int num;
1094 int ret; 1111 int ret;
1095 int run_size = 256; 1112 int run_size = 10000;
1096 int max_key = 100000000; 1113 int max_key = 100000000;
1097 int tree_size = 0; 1114 int tree_size = 0;
1098 struct ctree_path path; 1115 struct ctree_path path;
1116 struct ctree_super_block super;
1099 1117
1100 radix_tree_init(); 1118 radix_tree_init();
1101 1119
1102 1120
1103 root = open_ctree("dbfile"); 1121 root = open_ctree("dbfile", &super);
1122 printf("root tree\n");
1123 print_tree(root, root->node);
1124 printf("map tree\n");
1125 print_tree(root->extent_root, root->extent_root->node);
1104 1126
1105 srand(55); 1127 srand(55);
1106 for (i = 0; i < run_size; i++) { 1128 for (i = 0; i < run_size; i++) {
@@ -1112,22 +1134,20 @@ int main() {
1112 ins.objectid = num; 1134 ins.objectid = num;
1113 ins.offset = 0; 1135 ins.offset = 0;
1114 ins.flags = 0; 1136 ins.flags = 0;
1115 printf("insert %d\n", i);
1116 ret = insert_item(root, &ins, buf, strlen(buf)); 1137 ret = insert_item(root, &ins, buf, strlen(buf));
1117 if (!ret) 1138 if (!ret)
1118 tree_size++; 1139 tree_size++;
1119 printf("done insert %d\n", i);
1120 } 1140 }
1121 printf("root used: %lu\n", root->alloc_extent->num_used); 1141 printf("root used: %lu\n", root->alloc_extent->num_used);
1122 printf("root tree\n"); 1142 printf("root tree\n");
1123 print_tree(root, root->node); 1143 // print_tree(root, root->node);
1124 printf("map tree\n"); 1144 printf("map tree\n");
1125 printf("map used: %lu\n", root->extent_root->alloc_extent->num_used); 1145 printf("map used: %lu\n", root->extent_root->alloc_extent->num_used);
1126 print_tree(root->extent_root, root->extent_root->node); 1146 // print_tree(root->extent_root, root->extent_root->node);
1127 exit(1); 1147 write_ctree_super(root, &super);
1128
1129 close_ctree(root); 1148 close_ctree(root);
1130 root = open_ctree("dbfile"); 1149
1150 root = open_ctree("dbfile", &super);
1131 printf("starting search\n"); 1151 printf("starting search\n");
1132 srand(55); 1152 srand(55);
1133 for (i = 0; i < run_size; i++) { 1153 for (i = 0; i < run_size; i++) {
@@ -1142,8 +1162,9 @@ int main() {
1142 } 1162 }
1143 release_path(root, &path); 1163 release_path(root, &path);
1144 } 1164 }
1165 write_ctree_super(root, &super);
1145 close_ctree(root); 1166 close_ctree(root);
1146 root = open_ctree("dbfile"); 1167 root = open_ctree("dbfile", &super);
1147 printf("node %p level %d total ptrs %d free spc %lu\n", root->node, 1168 printf("node %p level %d total ptrs %d free spc %lu\n", root->node,
1148 node_level(root->node->node.header.flags), 1169 node_level(root->node->node.header.flags),
1149 root->node->node.header.nritems, 1170 root->node->node.header.nritems,
@@ -1174,8 +1195,9 @@ int main() {
1174 if (!ret) 1195 if (!ret)
1175 tree_size++; 1196 tree_size++;
1176 } 1197 }
1198 write_ctree_super(root, &super);
1177 close_ctree(root); 1199 close_ctree(root);
1178 root = open_ctree("dbfile"); 1200 root = open_ctree("dbfile", &super);
1179 printf("starting search2\n"); 1201 printf("starting search2\n");
1180 srand(128); 1202 srand(128);
1181 for (i = 0; i < run_size; i++) { 1203 for (i = 0; i < run_size; i++) {
@@ -1221,6 +1243,7 @@ int main() {
1221 } 1243 }
1222 release_path(root, &path); 1244 release_path(root, &path);
1223 } 1245 }
1246 write_ctree_super(root, &super);
1224 close_ctree(root); 1247 close_ctree(root);
1225 printf("tree size is now %d\n", tree_size); 1248 printf("tree size is now %d\n", tree_size);
1226 return 0; 1249 return 0;