aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-02 16:08:05 -0500
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-02 16:08:05 -0500
commit02217ed299c6340a35696e0610047eb96826de2d (patch)
tree4a92c16ce2a51f701c829d96f644486fb7b29517 /fs/btrfs
parent77ce6846c40e83193df01295e5af437f8b6c7a2d (diff)
Btrfs: early reference counting
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.c153
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/disk-io.c2
-rw-r--r--fs/btrfs/extent-tree.c45
-rw-r--r--fs/btrfs/quick-test.c10
-rw-r--r--fs/btrfs/random-test.c12
6 files changed, 145 insertions, 80 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 3c5f4c2dd525..1118986d7569 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -34,6 +34,37 @@ void release_path(struct ctree_root *root, struct ctree_path *p)
34 memset(p, 0, sizeof(*p)); 34 memset(p, 0, sizeof(*p));
35} 35}
36 36
37int btrfs_cow_block(struct ctree_root *root,
38 struct tree_buffer *buf,
39 struct tree_buffer *parent,
40 int parent_slot,
41 struct tree_buffer **cow_ret)
42{
43 struct tree_buffer *cow;
44
45 if (!list_empty(&buf->dirty)) {
46 *cow_ret = buf;
47 return 0;
48 }
49 cow = alloc_free_block(root);
50 memcpy(&cow->node, &buf->node, sizeof(buf->node));
51 cow->node.header.blocknr = cow->blocknr;
52 *cow_ret = cow;
53 if (buf == root->node) {
54 root->node = cow;
55 cow->count++;
56 tree_block_release(root, buf);
57 } else {
58 parent->node.blockptrs[parent_slot] = cow->blocknr;
59 BUG_ON(list_empty(&parent->dirty));
60 }
61 if (0 && root != root->extent_root && !is_leaf(cow->node.header.flags)) {
62 btrfs_inc_ref(root, cow);
63 }
64 tree_block_release(root, buf);
65 return 0;
66}
67
37/* 68/*
38 * The leaf data grows from end-to-front in the node. 69 * The leaf data grows from end-to-front in the node.
39 * this returns the address of the start of the last item, 70 * this returns the address of the start of the last item,
@@ -263,6 +294,8 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
263 294
264 /* first, try to make some room in the middle buffer */ 295 /* first, try to make some room in the middle buffer */
265 if (left_buf) { 296 if (left_buf) {
297 btrfs_cow_block(root, left_buf, parent_buf,
298 pslot - 1, &left_buf);
266 left = &left_buf->node; 299 left = &left_buf->node;
267 orig_slot += left->header.nritems; 300 orig_slot += left->header.nritems;
268 wret = push_node_left(root, left_buf, mid_buf); 301 wret = push_node_left(root, left_buf, mid_buf);
@@ -274,6 +307,8 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
274 * then try to empty the right most buffer into the middle 307 * then try to empty the right most buffer into the middle
275 */ 308 */
276 if (right_buf) { 309 if (right_buf) {
310 btrfs_cow_block(root, right_buf, parent_buf,
311 pslot + 1, &right_buf);
277 right = &right_buf->node; 312 right = &right_buf->node;
278 wret = push_node_left(root, mid_buf, right_buf); 313 wret = push_node_left(root, mid_buf, right_buf);
279 if (wret < 0) 314 if (wret < 0)
@@ -293,9 +328,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
293 } else { 328 } else {
294 memcpy(parent->keys + pslot + 1, right->keys, 329 memcpy(parent->keys + pslot + 1, right->keys,
295 sizeof(struct key)); 330 sizeof(struct key));
296 wret = dirty_tree_block(root, parent_buf); 331 BUG_ON(list_empty(&parent_buf->dirty));
297 if (wret)
298 ret = wret;
299 } 332 }
300 } 333 }
301 if (mid->header.nritems == 1) { 334 if (mid->header.nritems == 1) {
@@ -330,9 +363,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
330 } else { 363 } else {
331 /* update the parent key to reflect our changes */ 364 /* update the parent key to reflect our changes */
332 memcpy(parent->keys + pslot, mid->keys, sizeof(struct key)); 365 memcpy(parent->keys + pslot, mid->keys, sizeof(struct key));
333 wret = dirty_tree_block(root, parent_buf); 366 BUG_ON(list_empty(&parent_buf->dirty));
334 if (wret)
335 ret = wret;
336 } 367 }
337 368
338 /* update the path */ 369 /* update the path */
@@ -375,9 +406,10 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
375 * possible) 406 * possible)
376 */ 407 */
377int search_slot(struct ctree_root *root, struct key *key, 408int search_slot(struct ctree_root *root, struct key *key,
378 struct ctree_path *p, int ins_len) 409 struct ctree_path *p, int ins_len, int cow)
379{ 410{
380 struct tree_buffer *b; 411 struct tree_buffer *b;
412 struct tree_buffer *cow_buf;
381 struct node *c; 413 struct node *c;
382 int slot; 414 int slot;
383 int ret; 415 int ret;
@@ -387,8 +419,15 @@ again:
387 b = root->node; 419 b = root->node;
388 b->count++; 420 b->count++;
389 while (b) { 421 while (b) {
422 level = node_level(b->node.header.flags);
423 if (cow) {
424 int wret;
425 wret = btrfs_cow_block(root, b, p->nodes[level + 1],
426 p->slots[level + 1], &cow_buf);
427 b = cow_buf;
428 }
429 BUG_ON(!cow && ins_len);
390 c = &b->node; 430 c = &b->node;
391 level = node_level(c->header.flags);
392 p->nodes[level] = b; 431 p->nodes[level] = b;
393 ret = check_block(p, level); 432 ret = check_block(p, level);
394 if (ret) 433 if (ret)
@@ -453,7 +492,6 @@ static int fixup_low_keys(struct ctree_root *root,
453{ 492{
454 int i; 493 int i;
455 int ret = 0; 494 int ret = 0;
456 int wret;
457 for (i = level; i < MAX_LEVEL; i++) { 495 for (i = level; i < MAX_LEVEL; i++) {
458 struct node *t; 496 struct node *t;
459 int tslot = path->slots[i]; 497 int tslot = path->slots[i];
@@ -461,9 +499,7 @@ static int fixup_low_keys(struct ctree_root *root,
461 break; 499 break;
462 t = &path->nodes[i]->node; 500 t = &path->nodes[i]->node;
463 memcpy(t->keys + tslot, key, sizeof(*key)); 501 memcpy(t->keys + tslot, key, sizeof(*key));
464 wret = dirty_tree_block(root, path->nodes[i]); 502 BUG_ON(list_empty(&path->nodes[i]->dirty));
465 if (wret)
466 ret = wret;
467 if (tslot != 0) 503 if (tslot != 0)
468 break; 504 break;
469 } 505 }
@@ -486,7 +522,6 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf,
486 int src_nritems; 522 int src_nritems;
487 int dst_nritems; 523 int dst_nritems;
488 int ret = 0; 524 int ret = 0;
489 int wret;
490 525
491 src_nritems = src->header.nritems; 526 src_nritems = src->header.nritems;
492 dst_nritems = dst->header.nritems; 527 dst_nritems = dst->header.nritems;
@@ -511,13 +546,8 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf,
511 src->header.nritems -= push_items; 546 src->header.nritems -= push_items;
512 dst->header.nritems += push_items; 547 dst->header.nritems += push_items;
513 548
514 wret = dirty_tree_block(root, src_buf); 549 BUG_ON(list_empty(&src_buf->dirty));
515 if (wret < 0) 550 BUG_ON(list_empty(&dst_buf->dirty));
516 ret = wret;
517
518 wret = dirty_tree_block(root, dst_buf);
519 if (wret < 0)
520 ret = wret;
521 return ret; 551 return ret;
522} 552}
523 553
@@ -541,7 +571,6 @@ static int balance_node_right(struct ctree_root *root,
541 int src_nritems; 571 int src_nritems;
542 int dst_nritems; 572 int dst_nritems;
543 int ret = 0; 573 int ret = 0;
544 int wret;
545 574
546 src_nritems = src->header.nritems; 575 src_nritems = src->header.nritems;
547 dst_nritems = dst->header.nritems; 576 dst_nritems = dst->header.nritems;
@@ -569,13 +598,8 @@ static int balance_node_right(struct ctree_root *root,
569 src->header.nritems -= push_items; 598 src->header.nritems -= push_items;
570 dst->header.nritems += push_items; 599 dst->header.nritems += push_items;
571 600
572 wret = dirty_tree_block(root, src_buf); 601 BUG_ON(list_empty(&src_buf->dirty));
573 if (wret < 0) 602 BUG_ON(list_empty(&dst_buf->dirty));
574 ret = wret;
575
576 wret = dirty_tree_block(root, dst_buf);
577 if (wret < 0)
578 ret = wret;
579 return ret; 603 return ret;
580} 604}
581 605
@@ -615,7 +639,6 @@ static int insert_new_root(struct ctree_root *root,
615 tree_block_release(root, root->node); 639 tree_block_release(root, root->node);
616 root->node = t; 640 root->node = t;
617 t->count++; 641 t->count++;
618 dirty_tree_block(root, t);
619 path->nodes[level] = t; 642 path->nodes[level] = t;
620 path->slots[level] = 0; 643 path->slots[level] = 0;
621 return 0; 644 return 0;
@@ -655,7 +678,7 @@ static int insert_ptr(struct ctree_root *root,
655 lower->header.nritems++; 678 lower->header.nritems++;
656 if (lower->keys[1].objectid == 0) 679 if (lower->keys[1].objectid == 0)
657 BUG(); 680 BUG();
658 dirty_tree_block(root, path->nodes[level]); 681 BUG_ON(list_empty(&path->nodes[level]->dirty));
659 return 0; 682 return 0;
660} 683}
661 684
@@ -701,12 +724,7 @@ static int split_node(struct ctree_root *root, struct ctree_path *path,
701 c->header.nritems = mid; 724 c->header.nritems = mid;
702 ret = 0; 725 ret = 0;
703 726
704 wret = dirty_tree_block(root, t); 727 BUG_ON(list_empty(&t->dirty));
705 if (wret)
706 ret = wret;
707 wret = dirty_tree_block(root, split_buffer);
708 if (wret)
709 ret = wret;
710 wret = insert_ptr(root, path, split->keys, split_buffer->blocknr, 728 wret = insert_ptr(root, path, split->keys, split_buffer->blocknr,
711 path->slots[level + 1] + 1, level + 1); 729 path->slots[level + 1] + 1, level + 1);
712 if (wret) 730 if (wret)
@@ -778,6 +796,15 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
778 tree_block_release(root, right_buf); 796 tree_block_release(root, right_buf);
779 return 1; 797 return 1;
780 } 798 }
799 /* cow and double check */
800 btrfs_cow_block(root, right_buf, upper, slot + 1, &right_buf);
801 right = &right_buf->leaf;
802 free_space = leaf_free_space(right);
803 if (free_space < data_size + sizeof(struct item)) {
804 tree_block_release(root, right_buf);
805 return 1;
806 }
807
781 for (i = left->header.nritems - 1; i >= 0; i--) { 808 for (i = left->header.nritems - 1; i >= 0; i--) {
782 item = left->items + i; 809 item = left->items + i;
783 if (path->slots[0] == i) 810 if (path->slots[0] == i)
@@ -818,11 +845,12 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
818 } 845 }
819 left->header.nritems -= push_items; 846 left->header.nritems -= push_items;
820 847
821 dirty_tree_block(root, left_buf); 848 BUG_ON(list_empty(&left_buf->dirty));
822 dirty_tree_block(root, right_buf); 849 BUG_ON(list_empty(&right_buf->dirty));
823 memcpy(upper->node.keys + slot + 1, 850 memcpy(upper->node.keys + slot + 1,
824 &right->items[0].key, sizeof(struct key)); 851 &right->items[0].key, sizeof(struct key));
825 dirty_tree_block(root, upper); 852 BUG_ON(list_empty(&upper->dirty));
853
826 /* then fixup the leaf pointer in the path */ 854 /* then fixup the leaf pointer in the path */
827 if (path->slots[0] >= left->header.nritems) { 855 if (path->slots[0] >= left->header.nritems) {
828 path->slots[0] -= left->header.nritems; 856 path->slots[0] -= left->header.nritems;
@@ -869,6 +897,16 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
869 tree_block_release(root, t); 897 tree_block_release(root, t);
870 return 1; 898 return 1;
871 } 899 }
900
901 /* cow and double check */
902 btrfs_cow_block(root, t, path->nodes[1], slot - 1, &t);
903 left = &t->leaf;
904 free_space = leaf_free_space(left);
905 if (free_space < data_size + sizeof(struct item)) {
906 tree_block_release(root, t);
907 return 1;
908 }
909
872 for (i = 0; i < right->header.nritems; i++) { 910 for (i = 0; i < right->header.nritems; i++) {
873 item = right->items + i; 911 item = right->items + i;
874 if (path->slots[0] == i) 912 if (path->slots[0] == i)
@@ -912,12 +950,8 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
912 push_space = right->items[i].offset; 950 push_space = right->items[i].offset;
913 } 951 }
914 952
915 wret = dirty_tree_block(root, t); 953 BUG_ON(list_empty(&t->dirty));
916 if (wret) 954 BUG_ON(list_empty(&right_buf->dirty));
917 ret = wret;
918 wret = dirty_tree_block(root, right_buf);
919 if (wret)
920 ret = wret;
921 955
922 wret = fixup_low_keys(root, path, &right->items[0].key, 1); 956 wret = fixup_low_keys(root, path, &right->items[0].key, 1);
923 if (wret) 957 if (wret)
@@ -968,6 +1002,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
968 if (wret < 0) 1002 if (wret < 0)
969 return wret; 1003 return wret;
970 } 1004 }
1005
971 l_buf = path->nodes[0]; 1006 l_buf = path->nodes[0];
972 l = &l_buf->leaf; 1007 l = &l_buf->leaf;
973 1008
@@ -1022,13 +1057,8 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
1022 right_buffer->blocknr, path->slots[1] + 1, 1); 1057 right_buffer->blocknr, path->slots[1] + 1, 1);
1023 if (wret) 1058 if (wret)
1024 ret = wret; 1059 ret = wret;
1025 wret = dirty_tree_block(root, right_buffer); 1060 BUG_ON(list_empty(&right_buffer->dirty));
1026 if (wret) 1061 BUG_ON(list_empty(&l_buf->dirty));
1027 ret = wret;
1028 wret = dirty_tree_block(root, l_buf);
1029 if (wret)
1030 ret = wret;
1031
1032 BUG_ON(path->slots[0] != slot); 1062 BUG_ON(path->slots[0] != slot);
1033 if (mid <= slot) { 1063 if (mid <= slot) {
1034 tree_block_release(root, path->nodes[0]); 1064 tree_block_release(root, path->nodes[0]);
@@ -1049,7 +1079,6 @@ int insert_item(struct ctree_root *root, struct key *key,
1049 void *data, int data_size) 1079 void *data, int data_size)
1050{ 1080{
1051 int ret = 0; 1081 int ret = 0;
1052 int wret;
1053 int slot; 1082 int slot;
1054 int slot_orig; 1083 int slot_orig;
1055 struct leaf *leaf; 1084 struct leaf *leaf;
@@ -1062,7 +1091,7 @@ int insert_item(struct ctree_root *root, struct key *key,
1062 if (!root->node) 1091 if (!root->node)
1063 BUG(); 1092 BUG();
1064 init_path(&path); 1093 init_path(&path);
1065 ret = search_slot(root, key, &path, data_size); 1094 ret = search_slot(root, key, &path, data_size, 1);
1066 if (ret == 0) { 1095 if (ret == 0) {
1067 release_path(root, &path); 1096 release_path(root, &path);
1068 return -EEXIST; 1097 return -EEXIST;
@@ -1114,10 +1143,7 @@ int insert_item(struct ctree_root *root, struct key *key,
1114 if (slot == 0) 1143 if (slot == 0)
1115 ret = fixup_low_keys(root, &path, key, 1); 1144 ret = fixup_low_keys(root, &path, key, 1);
1116 1145
1117 wret = dirty_tree_block(root, leaf_buf); 1146 BUG_ON(list_empty(&leaf_buf->dirty));
1118 if (wret)
1119 ret = wret;
1120
1121 if (leaf_free_space(leaf) < 0) 1147 if (leaf_free_space(leaf) < 0)
1122 BUG(); 1148 BUG();
1123 check_leaf(&path, 0); 1149 check_leaf(&path, 0);
@@ -1162,9 +1188,7 @@ static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level,
1162 if (wret) 1188 if (wret)
1163 ret = wret; 1189 ret = wret;
1164 } 1190 }
1165 wret = dirty_tree_block(root, parent); 1191 BUG_ON(list_empty(&parent->dirty));
1166 if (wret)
1167 ret = wret;
1168 return ret; 1192 return ret;
1169} 1193}
1170 1194
@@ -1205,7 +1229,7 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
1205 if (leaf->header.nritems == 0) { 1229 if (leaf->header.nritems == 0) {
1206 if (leaf_buf == root->node) { 1230 if (leaf_buf == root->node) {
1207 leaf->header.flags = node_level(0); 1231 leaf->header.flags = node_level(0);
1208 dirty_tree_block(root, leaf_buf); 1232 BUG_ON(list_empty(&leaf_buf->dirty));
1209 } else { 1233 } else {
1210 clean_tree_block(root, leaf_buf); 1234 clean_tree_block(root, leaf_buf);
1211 wret = del_ptr(root, path, 1, path->slots[1]); 1235 wret = del_ptr(root, path, 1, path->slots[1]);
@@ -1223,9 +1247,7 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
1223 if (wret) 1247 if (wret)
1224 ret = wret; 1248 ret = wret;
1225 } 1249 }
1226 wret = dirty_tree_block(root, leaf_buf); 1250 BUG_ON(list_empty(&leaf_buf->dirty));
1227 if (wret)
1228 ret = wret;
1229 1251
1230 /* delete the leaf if it is mostly empty */ 1252 /* delete the leaf if it is mostly empty */
1231 if (used < LEAF_DATA_SIZE / 3) { 1253 if (used < LEAF_DATA_SIZE / 3) {
@@ -1304,3 +1326,4 @@ int next_leaf(struct ctree_root *root, struct ctree_path *path)
1304 return 0; 1326 return 0;
1305} 1327}
1306 1328
1329
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 6b4dabd47698..9fe8ba6e25c1 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -142,8 +142,9 @@ struct ctree_path {
142}; 142};
143 143
144struct tree_buffer *alloc_free_block(struct ctree_root *root); 144struct tree_buffer *alloc_free_block(struct ctree_root *root);
145int btrfs_inc_ref(struct ctree_root *root, struct tree_buffer *buf);
145int free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks); 146int free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks);
146int search_slot(struct ctree_root *root, struct key *key, struct ctree_path *p, int ins_len); 147int search_slot(struct ctree_root *root, struct key *key, struct ctree_path *p, int ins_len, int cow);
147void release_path(struct ctree_root *root, struct ctree_path *p); 148void release_path(struct ctree_root *root, struct ctree_path *p);
148void init_path(struct ctree_path *p); 149void init_path(struct ctree_path *p);
149int del_item(struct ctree_root *root, struct ctree_path *path); 150int del_item(struct ctree_root *root, struct ctree_path *path);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index b1a8149bbc84..0e1c31e682fb 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -260,6 +260,8 @@ void tree_block_release(struct ctree_root *root, struct tree_buffer *buf)
260 if (buf->count < 0) 260 if (buf->count < 0)
261 BUG(); 261 BUG();
262 if (buf->count == 0) { 262 if (buf->count == 0) {
263 BUG_ON(!list_empty(&buf->cache));
264 BUG_ON(!list_empty(&buf->dirty));
263 if (!radix_tree_lookup(&root->cache_radix, buf->blocknr)) 265 if (!radix_tree_lookup(&root->cache_radix, buf->blocknr))
264 BUG(); 266 BUG();
265 radix_tree_delete(&root->cache_radix, buf->blocknr); 267 radix_tree_delete(&root->cache_radix, buf->blocknr);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index fb2144496215..25d9cd169209 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -15,6 +15,39 @@
15 */ 15 */
16#define CTREE_EXTENT_PENDING 0 16#define CTREE_EXTENT_PENDING 0
17 17
18static int inc_block_ref(struct ctree_root *root, u64 blocknr)
19{
20 struct ctree_path path;
21 int ret;
22 struct key key;
23 struct leaf *l;
24 struct extent_item *item;
25 init_path(&path);
26 key.objectid = blocknr;
27 key.flags = 0;
28 key.offset = 1;
29 ret = search_slot(root->extent_root, &key, &path, 0, 1);
30 BUG_ON(ret != 0);
31 l = &path.nodes[0]->leaf;
32 item = (struct extent_item *)(l->data +
33 l->items[path.slots[0]].offset);
34 item->refs++;
35 BUG_ON(list_empty(&path.nodes[0]->dirty));
36 release_path(root->extent_root, &path);
37 return 0;
38}
39
40int btrfs_inc_ref(struct ctree_root *root, struct tree_buffer *buf)
41{
42 u64 blocknr;
43 int i;
44 for (i = 0; i < buf->node.header.nritems; i++) {
45 blocknr = buf->node.blockptrs[i];
46 inc_block_ref(root, blocknr);
47 }
48 return 0;
49}
50
18/* 51/*
19 * find all the blocks marked as pending in the radix tree and remove 52 * find all the blocks marked as pending in the radix tree and remove
20 * them from the extent map 53 * them from the extent map
@@ -39,7 +72,7 @@ static int del_pending_extents(struct ctree_root *extent_root)
39 key.flags = 0; 72 key.flags = 0;
40 key.offset = 1; 73 key.offset = 1;
41 init_path(&path); 74 init_path(&path);
42 ret = search_slot(extent_root, &key, &path, -1); 75 ret = search_slot(extent_root, &key, &path, -1, 1);
43 if (ret) { 76 if (ret) {
44 print_tree(extent_root, extent_root->node); 77 print_tree(extent_root, extent_root->node);
45 printf("unable to find %Lu\n", key.objectid); 78 printf("unable to find %Lu\n", key.objectid);
@@ -83,7 +116,7 @@ int free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks)
83 return 0; 116 return 0;
84 } 117 }
85 init_path(&path); 118 init_path(&path);
86 ret = search_slot(extent_root, &key, &path, -1); 119 ret = search_slot(extent_root, &key, &path, -1, 1);
87 if (ret) { 120 if (ret) {
88 print_tree(extent_root, extent_root->node); 121 print_tree(extent_root, extent_root->node);
89 printf("failed to find %Lu\n", key.objectid); 122 printf("failed to find %Lu\n", key.objectid);
@@ -124,7 +157,7 @@ check_failed:
124 ins->offset = 0; 157 ins->offset = 0;
125 ins->flags = 0; 158 ins->flags = 0;
126 start_found = 0; 159 start_found = 0;
127 ret = search_slot(root, ins, &path, 0); 160 ret = search_slot(root, ins, &path, 0, 0);
128 if (ret < 0) 161 if (ret < 0)
129 goto error; 162 goto error;
130 163
@@ -221,6 +254,8 @@ static int insert_pending_extents(struct ctree_root *extent_root)
221 ret = insert_item(extent_root, &key, &item, 254 ret = insert_item(extent_root, &key, &item,
222 sizeof(item)); 255 sizeof(item));
223 if (ret) { 256 if (ret) {
257 printf("%Lu already in tree\n", key.objectid);
258 print_tree(extent_root, extent_root->node);
224 BUG(); 259 BUG();
225 // FIXME undo it and return sane 260 // FIXME undo it and return sane
226 return ret; 261 return ret;
@@ -228,6 +263,7 @@ static int insert_pending_extents(struct ctree_root *extent_root)
228 radix_tree_tag_clear(&extent_root->cache_radix, 263 radix_tree_tag_clear(&extent_root->cache_radix,
229 gang[i]->blocknr, 264 gang[i]->blocknr,
230 CTREE_EXTENT_PENDING); 265 CTREE_EXTENT_PENDING);
266 printf("%Lu is not pending\n", gang[i]->blocknr);
231 tree_block_release(extent_root, gang[i]); 267 tree_block_release(extent_root, gang[i]);
232 } 268 }
233 } 269 }
@@ -266,15 +302,18 @@ int alloc_extent(struct ctree_root *root, u64 num_blocks, u64 search_start,
266 if (pending_ret) 302 if (pending_ret)
267 return pending_ret; 303 return pending_ret;
268 *buf = find_tree_block(root, ins->objectid); 304 *buf = find_tree_block(root, ins->objectid);
305 dirty_tree_block(root, *buf);
269 return 0; 306 return 0;
270 } 307 }
271 /* we're allocating an extent for the extent tree, don't recurse */ 308 /* we're allocating an extent for the extent tree, don't recurse */
272 BUG_ON(ins->offset != 1); 309 BUG_ON(ins->offset != 1);
273 *buf = find_tree_block(root, ins->objectid); 310 *buf = find_tree_block(root, ins->objectid);
274 BUG_ON(!*buf); 311 BUG_ON(!*buf);
312 printf("%Lu is pending\n", ins->objectid);
275 radix_tree_tag_set(&root->cache_radix, ins->objectid, 313 radix_tree_tag_set(&root->cache_radix, ins->objectid,
276 CTREE_EXTENT_PENDING); 314 CTREE_EXTENT_PENDING);
277 (*buf)->count++; 315 (*buf)->count++;
316 dirty_tree_block(root, *buf);
278 return 0; 317 return 0;
279 318
280} 319}
diff --git a/fs/btrfs/quick-test.c b/fs/btrfs/quick-test.c
index dbd00c3b7ab4..8255f79ceca5 100644
--- a/fs/btrfs/quick-test.c
+++ b/fs/btrfs/quick-test.c
@@ -19,7 +19,7 @@ int main(int ac, char **av) {
19 int i; 19 int i;
20 int num; 20 int num;
21 int ret; 21 int ret;
22 int run_size = 100000; 22 int run_size = 1024;
23 int max_key = 100000000; 23 int max_key = 100000000;
24 int tree_size = 0; 24 int tree_size = 0;
25 struct ctree_path path; 25 struct ctree_path path;
@@ -57,7 +57,7 @@ int main(int ac, char **av) {
57 init_path(&path); 57 init_path(&path);
58 if (i % 10000 == 0) 58 if (i % 10000 == 0)
59 fprintf(stderr, "search %d:%d\n", num, i); 59 fprintf(stderr, "search %d:%d\n", num, i);
60 ret = search_slot(root, &ins, &path, 0); 60 ret = search_slot(root, &ins, &path, 0, 0);
61 if (ret) { 61 if (ret) {
62 print_tree(root, root->node); 62 print_tree(root, root->node);
63 printf("unable to find %d\n", num); 63 printf("unable to find %d\n", num);
@@ -79,7 +79,7 @@ int main(int ac, char **av) {
79 num = next_key(i, max_key); 79 num = next_key(i, max_key);
80 ins.objectid = num; 80 ins.objectid = num;
81 init_path(&path); 81 init_path(&path);
82 ret = search_slot(root, &ins, &path, -1); 82 ret = search_slot(root, &ins, &path, -1, 1);
83 if (!ret) { 83 if (!ret) {
84 if (i % 10000 == 0) 84 if (i % 10000 == 0)
85 fprintf(stderr, "del %d:%d\n", num, i); 85 fprintf(stderr, "del %d:%d\n", num, i);
@@ -117,7 +117,7 @@ int main(int ac, char **av) {
117 init_path(&path); 117 init_path(&path);
118 if (i % 10000 == 0) 118 if (i % 10000 == 0)
119 fprintf(stderr, "search %d:%d\n", num, i); 119 fprintf(stderr, "search %d:%d\n", num, i);
120 ret = search_slot(root, &ins, &path, 0); 120 ret = search_slot(root, &ins, &path, 0, 0);
121 if (ret) { 121 if (ret) {
122 print_tree(root, root->node); 122 print_tree(root, root->node);
123 printf("unable to find %d\n", num); 123 printf("unable to find %d\n", num);
@@ -131,7 +131,7 @@ int main(int ac, char **av) {
131 int slot; 131 int slot;
132 ins.objectid = (u64)-1; 132 ins.objectid = (u64)-1;
133 init_path(&path); 133 init_path(&path);
134 ret = search_slot(root, &ins, &path, -1); 134 ret = search_slot(root, &ins, &path, -1, 1);
135 if (ret == 0) 135 if (ret == 0)
136 BUG(); 136 BUG();
137 137
diff --git a/fs/btrfs/random-test.c b/fs/btrfs/random-test.c
index 53245c5039dc..dcc852ad6737 100644
--- a/fs/btrfs/random-test.c
+++ b/fs/btrfs/random-test.c
@@ -93,7 +93,7 @@ static int del_one(struct ctree_root *root, struct radix_tree_root *radix)
93 ret = setup_key(radix, &key, 1); 93 ret = setup_key(radix, &key, 1);
94 if (ret < 0) 94 if (ret < 0)
95 return 0; 95 return 0;
96 ret = search_slot(root, &key, &path, -1); 96 ret = search_slot(root, &key, &path, -1, 1);
97 if (ret) 97 if (ret)
98 goto error; 98 goto error;
99 ret = del_item(root, &path); 99 ret = del_item(root, &path);
@@ -118,7 +118,7 @@ static int lookup_item(struct ctree_root *root, struct radix_tree_root *radix)
118 ret = setup_key(radix, &key, 1); 118 ret = setup_key(radix, &key, 1);
119 if (ret < 0) 119 if (ret < 0)
120 return 0; 120 return 0;
121 ret = search_slot(root, &key, &path, 0); 121 ret = search_slot(root, &key, &path, 0, 1);
122 release_path(root, &path); 122 release_path(root, &path);
123 if (ret) 123 if (ret)
124 goto error; 124 goto error;
@@ -137,7 +137,7 @@ static int lookup_enoent(struct ctree_root *root, struct radix_tree_root *radix)
137 ret = setup_key(radix, &key, 0); 137 ret = setup_key(radix, &key, 0);
138 if (ret < 0) 138 if (ret < 0)
139 return ret; 139 return ret;
140 ret = search_slot(root, &key, &path, 0); 140 ret = search_slot(root, &key, &path, 0, 0);
141 release_path(root, &path); 141 release_path(root, &path);
142 if (ret <= 0) 142 if (ret <= 0)
143 goto error; 143 goto error;
@@ -163,7 +163,7 @@ static int empty_tree(struct ctree_root *root, struct radix_tree_root *radix,
163 key.objectid = (unsigned long)-1; 163 key.objectid = (unsigned long)-1;
164 while(nr-- >= 0) { 164 while(nr-- >= 0) {
165 init_path(&path); 165 init_path(&path);
166 ret = search_slot(root, &key, &path, -1); 166 ret = search_slot(root, &key, &path, -1, 1);
167 if (ret < 0) { 167 if (ret < 0) {
168 release_path(root, &path); 168 release_path(root, &path);
169 return ret; 169 return ret;
@@ -216,7 +216,7 @@ static int fill_tree(struct ctree_root *root, struct radix_tree_root *radix,
216 return ret; 216 return ret;
217 } 217 }
218 } 218 }
219 if (i % 10000 == 0) { 219 if (i && i % 10000 == 0) {
220 printf("bigfill %d\n", i); 220 printf("bigfill %d\n", i);
221 } 221 }
222 if (!keep_running) 222 if (!keep_running)
@@ -263,7 +263,7 @@ static int fill_radix(struct ctree_root *root, struct radix_tree_root *radix)
263 key.objectid = (unsigned long)-1; 263 key.objectid = (unsigned long)-1;
264 while(1) { 264 while(1) {
265 init_path(&path); 265 init_path(&path);
266 ret = search_slot(root, &key, &path, 0); 266 ret = search_slot(root, &key, &path, 0, 0);
267 if (ret < 0) { 267 if (ret < 0) {
268 release_path(root, &path); 268 release_path(root, &path);
269 return ret; 269 return ret;