aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-12 12:01:18 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-12 12:01:18 -0400
commit7518a238ea0152dc849d1ed76d3cae8b44e12f46 (patch)
tree97e5c285f10bdb2576046e7bb15d239471815c28 /fs
parent83e15a28e046dbb4534dd263d1d3dc867a8994a2 (diff)
Btrfs: get/set for struct header fields
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/Makefile2
-rw-r--r--fs/btrfs/TODO1
-rw-r--r--fs/btrfs/ctree.c224
-rw-r--r--fs/btrfs/ctree.h63
-rw-r--r--fs/btrfs/disk-io.c7
-rw-r--r--fs/btrfs/extent-tree.c53
-rw-r--r--fs/btrfs/mkfs.c10
-rw-r--r--fs/btrfs/print-tree.c26
-rw-r--r--fs/btrfs/quick-test.c12
-rw-r--r--fs/btrfs/random-test.c4
10 files changed, 230 insertions, 172 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile
index ae7f4c00c39c..f8532200e9ad 100644
--- a/fs/btrfs/Makefile
+++ b/fs/btrfs/Makefile
@@ -25,7 +25,7 @@ tester: $(objects) random-test.o
25quick-test: $(objects) quick-test.o 25quick-test: $(objects) quick-test.o
26 gcc $(CFLAGS) -o quick-test $(objects) quick-test.o 26 gcc $(CFLAGS) -o quick-test $(objects) quick-test.o
27 27
28$(objects) : $(headers) 28$(objects): $(headers)
29 29
30clean : 30clean :
31 rm debug-tree tester *.o 31 rm debug-tree tester *.o
diff --git a/fs/btrfs/TODO b/fs/btrfs/TODO
index 5c4395c3784a..52d2a7a071f4 100644
--- a/fs/btrfs/TODO
+++ b/fs/btrfs/TODO
@@ -1,4 +1,5 @@
1* cleanup, add more error checking, get rid of BUG_ONs 1* cleanup, add more error checking, get rid of BUG_ONs
2* endian fixes
2* Make IO functions look more like the page cache 3* Make IO functions look more like the page cache
3* Fix ENOSPC handling 4* Fix ENOSPC handling
4* make blocksize a mkfs parameter instead of #define 5* make blocksize a mkfs parameter instead of #define
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 729d4ddb3746..e43c827e0dfd 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -48,7 +48,7 @@ int btrfs_cow_block(struct ctree_root *root,
48 } 48 }
49 cow = alloc_free_block(root); 49 cow = alloc_free_block(root);
50 memcpy(&cow->node, &buf->node, sizeof(buf->node)); 50 memcpy(&cow->node, &buf->node, sizeof(buf->node));
51 cow->node.header.blocknr = cow->blocknr; 51 btrfs_set_header_blocknr(&cow->node.header, cow->blocknr);
52 *cow_ret = cow; 52 *cow_ret = cow;
53 btrfs_inc_ref(root, buf); 53 btrfs_inc_ref(root, buf);
54 if (buf == root->node) { 54 if (buf == root->node) {
@@ -73,7 +73,7 @@ int btrfs_cow_block(struct ctree_root *root,
73 */ 73 */
74static inline unsigned int leaf_data_end(struct leaf *leaf) 74static inline unsigned int leaf_data_end(struct leaf *leaf)
75{ 75{
76 unsigned int nr = leaf->header.nritems; 76 u32 nr = btrfs_header_nritems(&leaf->header);
77 if (nr == 0) 77 if (nr == 0)
78 return sizeof(leaf->data); 78 return sizeof(leaf->data);
79 return leaf->items[nr-1].offset; 79 return leaf->items[nr-1].offset;
@@ -87,7 +87,7 @@ static inline unsigned int leaf_data_end(struct leaf *leaf)
87int leaf_free_space(struct leaf *leaf) 87int leaf_free_space(struct leaf *leaf)
88{ 88{
89 int data_end = leaf_data_end(leaf); 89 int data_end = leaf_data_end(leaf);
90 int nritems = leaf->header.nritems; 90 int nritems = btrfs_header_nritems(&leaf->header);
91 char *items_end = (char *)(leaf->items + nritems + 1); 91 char *items_end = (char *)(leaf->items + nritems + 1);
92 return (char *)(leaf->data + data_end) - (char *)items_end; 92 return (char *)(leaf->data + data_end) - (char *)items_end;
93} 93}
@@ -118,18 +118,21 @@ int check_node(struct ctree_path *path, int level)
118 struct node *parent = NULL; 118 struct node *parent = NULL;
119 struct node *node = &path->nodes[level]->node; 119 struct node *node = &path->nodes[level]->node;
120 int parent_slot; 120 int parent_slot;
121 u32 nritems = btrfs_header_nritems(&node->header);
121 122
122 if (path->nodes[level + 1]) 123 if (path->nodes[level + 1])
123 parent = &path->nodes[level + 1]->node; 124 parent = &path->nodes[level + 1]->node;
124 parent_slot = path->slots[level + 1]; 125 parent_slot = path->slots[level + 1];
125 if (parent && node->header.nritems > 0) { 126 BUG_ON(nritems == 0);
127 if (parent) {
126 struct key *parent_key; 128 struct key *parent_key;
127 parent_key = &parent->keys[parent_slot]; 129 parent_key = &parent->keys[parent_slot];
128 BUG_ON(memcmp(parent_key, node->keys, sizeof(struct key))); 130 BUG_ON(memcmp(parent_key, node->keys, sizeof(struct key)));
129 BUG_ON(parent->blockptrs[parent_slot] != node->header.blocknr); 131 BUG_ON(parent->blockptrs[parent_slot] !=
132 btrfs_header_blocknr(&node->header));
130 } 133 }
131 BUG_ON(node->header.nritems > NODEPTRS_PER_BLOCK); 134 BUG_ON(nritems > NODEPTRS_PER_BLOCK);
132 for (i = 0; i < node->header.nritems - 2; i++) { 135 for (i = 0; nritems > 1 && i < nritems - 2; i++) {
133 BUG_ON(comp_keys(&node->keys[i], &node->keys[i+1]) >= 0); 136 BUG_ON(comp_keys(&node->keys[i], &node->keys[i+1]) >= 0);
134 } 137 }
135 return 0; 138 return 0;
@@ -141,18 +144,25 @@ int check_leaf(struct ctree_path *path, int level)
141 struct leaf *leaf = &path->nodes[level]->leaf; 144 struct leaf *leaf = &path->nodes[level]->leaf;
142 struct node *parent = NULL; 145 struct node *parent = NULL;
143 int parent_slot; 146 int parent_slot;
147 u32 nritems = btrfs_header_nritems(&leaf->header);
144 148
145 if (path->nodes[level + 1]) 149 if (path->nodes[level + 1])
146 parent = &path->nodes[level + 1]->node; 150 parent = &path->nodes[level + 1]->node;
147 parent_slot = path->slots[level + 1]; 151 parent_slot = path->slots[level + 1];
148 if (parent && leaf->header.nritems > 0) { 152 BUG_ON(leaf_free_space(leaf) < 0);
153
154 if (nritems == 0)
155 return 0;
156
157 if (parent) {
149 struct key *parent_key; 158 struct key *parent_key;
150 parent_key = &parent->keys[parent_slot]; 159 parent_key = &parent->keys[parent_slot];
151 BUG_ON(memcmp(parent_key, &leaf->items[0].key, 160 BUG_ON(memcmp(parent_key, &leaf->items[0].key,
152 sizeof(struct key))); 161 sizeof(struct key)));
153 BUG_ON(parent->blockptrs[parent_slot] != leaf->header.blocknr); 162 BUG_ON(parent->blockptrs[parent_slot] !=
163 btrfs_header_blocknr(&leaf->header));
154 } 164 }
155 for (i = 0; i < leaf->header.nritems - 2; i++) { 165 for (i = 0; nritems > 1 && i < nritems - 2; i++) {
156 BUG_ON(comp_keys(&leaf->items[i].key, 166 BUG_ON(comp_keys(&leaf->items[i].key,
157 &leaf->items[i+1].key) >= 0); 167 &leaf->items[i+1].key) >= 0);
158 BUG_ON(leaf->items[i].offset != leaf->items[i + 1].offset + 168 BUG_ON(leaf->items[i].offset != leaf->items[i + 1].offset +
@@ -162,7 +172,6 @@ int check_leaf(struct ctree_path *path, int level)
162 LEAF_DATA_SIZE); 172 LEAF_DATA_SIZE);
163 } 173 }
164 } 174 }
165 BUG_ON(leaf_free_space(leaf) < 0);
166 return 0; 175 return 0;
167} 176}
168 177
@@ -215,13 +224,15 @@ int generic_bin_search(char *p, int item_size, struct key *key,
215 */ 224 */
216int bin_search(struct node *c, struct key *key, int *slot) 225int bin_search(struct node *c, struct key *key, int *slot)
217{ 226{
218 if (is_leaf(c->header.flags)) { 227 if (btrfs_is_leaf(c)) {
219 struct leaf *l = (struct leaf *)c; 228 struct leaf *l = (struct leaf *)c;
220 return generic_bin_search((void *)l->items, sizeof(struct item), 229 return generic_bin_search((void *)l->items, sizeof(struct item),
221 key, c->header.nritems, slot); 230 key, btrfs_header_nritems(&c->header),
231 slot);
222 } else { 232 } else {
223 return generic_bin_search((void *)c->keys, sizeof(struct key), 233 return generic_bin_search((void *)c->keys, sizeof(struct key),
224 key, c->header.nritems, slot); 234 key, btrfs_header_nritems(&c->header),
235 slot);
225 } 236 }
226 return -1; 237 return -1;
227} 238}
@@ -233,7 +244,7 @@ struct tree_buffer *read_node_slot(struct ctree_root *root,
233 struct node *node = &parent_buf->node; 244 struct node *node = &parent_buf->node;
234 if (slot < 0) 245 if (slot < 0)
235 return NULL; 246 return NULL;
236 if (slot >= node->header.nritems) 247 if (slot >= btrfs_header_nritems(&node->header))
237 return NULL; 248 return NULL;
238 return read_tree_block(root, node->blockptrs[slot]); 249 return read_tree_block(root, node->blockptrs[slot]);
239} 250}
@@ -270,7 +281,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
270 struct tree_buffer *child; 281 struct tree_buffer *child;
271 u64 blocknr = mid_buf->blocknr; 282 u64 blocknr = mid_buf->blocknr;
272 283
273 if (mid->header.nritems != 1) 284 if (btrfs_header_nritems(&mid->header) != 1)
274 return 0; 285 return 0;
275 286
276 /* promote the child to a root */ 287 /* promote the child to a root */
@@ -287,7 +298,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
287 } 298 }
288 parent = &parent_buf->node; 299 parent = &parent_buf->node;
289 300
290 if (mid->header.nritems > NODEPTRS_PER_BLOCK / 4) 301 if (btrfs_header_nritems(&mid->header) > NODEPTRS_PER_BLOCK / 4)
291 return 0; 302 return 0;
292 303
293 left_buf = read_node_slot(root, parent_buf, pslot - 1); 304 left_buf = read_node_slot(root, parent_buf, pslot - 1);
@@ -298,7 +309,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
298 btrfs_cow_block(root, left_buf, parent_buf, 309 btrfs_cow_block(root, left_buf, parent_buf,
299 pslot - 1, &left_buf); 310 pslot - 1, &left_buf);
300 left = &left_buf->node; 311 left = &left_buf->node;
301 orig_slot += left->header.nritems; 312 orig_slot += btrfs_header_nritems(&left->header);
302 wret = push_node_left(root, left_buf, mid_buf); 313 wret = push_node_left(root, left_buf, mid_buf);
303 if (wret < 0) 314 if (wret < 0)
304 ret = wret; 315 ret = wret;
@@ -314,7 +325,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
314 wret = push_node_left(root, mid_buf, right_buf); 325 wret = push_node_left(root, mid_buf, right_buf);
315 if (wret < 0) 326 if (wret < 0)
316 ret = wret; 327 ret = wret;
317 if (right->header.nritems == 0) { 328 if (btrfs_header_nritems(&right->header) == 0) {
318 u64 blocknr = right_buf->blocknr; 329 u64 blocknr = right_buf->blocknr;
319 tree_block_release(root, right_buf); 330 tree_block_release(root, right_buf);
320 clean_tree_block(root, right_buf); 331 clean_tree_block(root, right_buf);
@@ -332,7 +343,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
332 BUG_ON(list_empty(&parent_buf->dirty)); 343 BUG_ON(list_empty(&parent_buf->dirty));
333 } 344 }
334 } 345 }
335 if (mid->header.nritems == 1) { 346 if (btrfs_header_nritems(&mid->header) == 1) {
336 /* 347 /*
337 * we're not allowed to leave a node with one item in the 348 * we're not allowed to leave a node with one item in the
338 * tree during a delete. A deletion from lower in the tree 349 * tree during a delete. A deletion from lower in the tree
@@ -348,7 +359,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
348 ret = wret; 359 ret = wret;
349 BUG_ON(wret == 1); 360 BUG_ON(wret == 1);
350 } 361 }
351 if (mid->header.nritems == 0) { 362 if (btrfs_header_nritems(&mid->header) == 0) {
352 /* we've managed to empty the middle node, drop it */ 363 /* we've managed to empty the middle node, drop it */
353 u64 blocknr = mid_buf->blocknr; 364 u64 blocknr = mid_buf->blocknr;
354 tree_block_release(root, mid_buf); 365 tree_block_release(root, mid_buf);
@@ -369,7 +380,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
369 380
370 /* update the path */ 381 /* update the path */
371 if (left_buf) { 382 if (left_buf) {
372 if (left->header.nritems > orig_slot) { 383 if (btrfs_header_nritems(&left->header) > orig_slot) {
373 left_buf->count++; // released below 384 left_buf->count++; // released below
374 path->nodes[level] = left_buf; 385 path->nodes[level] = left_buf;
375 path->slots[level + 1] -= 1; 386 path->slots[level + 1] -= 1;
@@ -377,7 +388,7 @@ static int balance_level(struct ctree_root *root, struct ctree_path *path,
377 if (mid_buf) 388 if (mid_buf)
378 tree_block_release(root, mid_buf); 389 tree_block_release(root, mid_buf);
379 } else { 390 } else {
380 orig_slot -= left->header.nritems; 391 orig_slot -= btrfs_header_nritems(&left->header);
381 path->slots[level] = orig_slot; 392 path->slots[level] = orig_slot;
382 } 393 }
383 } 394 }
@@ -420,7 +431,7 @@ again:
420 b = root->node; 431 b = root->node;
421 b->count++; 432 b->count++;
422 while (b) { 433 while (b) {
423 level = node_level(b->node.header.flags); 434 level = btrfs_header_level(&b->node.header);
424 if (cow) { 435 if (cow) {
425 int wret; 436 int wret;
426 wret = btrfs_cow_block(root, b, p->nodes[level + 1], 437 wret = btrfs_cow_block(root, b, p->nodes[level + 1],
@@ -434,12 +445,12 @@ again:
434 if (ret) 445 if (ret)
435 return -1; 446 return -1;
436 ret = bin_search(c, key, &slot); 447 ret = bin_search(c, key, &slot);
437 if (!is_leaf(c->header.flags)) { 448 if (!btrfs_is_leaf(c)) {
438 if (ret && slot > 0) 449 if (ret && slot > 0)
439 slot -= 1; 450 slot -= 1;
440 p->slots[level] = slot; 451 p->slots[level] = slot;
441 if (ins_len > 0 && 452 if (ins_len > 0 && btrfs_header_nritems(&c->header) ==
442 c->header.nritems == NODEPTRS_PER_BLOCK) { 453 NODEPTRS_PER_BLOCK) {
443 int sret = split_node(root, p, level); 454 int sret = split_node(root, p, level);
444 BUG_ON(sret > 0); 455 BUG_ON(sret > 0);
445 if (sret) 456 if (sret)
@@ -456,7 +467,7 @@ again:
456 goto again; 467 goto again;
457 c = &b->node; 468 c = &b->node;
458 slot = p->slots[level]; 469 slot = p->slots[level];
459 BUG_ON(c->header.nritems == 1); 470 BUG_ON(btrfs_header_nritems(&c->header) == 1);
460 } 471 }
461 b = read_tree_block(root, c->blockptrs[slot]); 472 b = read_tree_block(root, c->blockptrs[slot]);
462 } else { 473 } else {
@@ -524,8 +535,8 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf,
524 int dst_nritems; 535 int dst_nritems;
525 int ret = 0; 536 int ret = 0;
526 537
527 src_nritems = src->header.nritems; 538 src_nritems = btrfs_header_nritems(&src->header);
528 dst_nritems = dst->header.nritems; 539 dst_nritems = btrfs_header_nritems(&dst->header);
529 push_items = NODEPTRS_PER_BLOCK - dst_nritems; 540 push_items = NODEPTRS_PER_BLOCK - dst_nritems;
530 if (push_items <= 0) { 541 if (push_items <= 0) {
531 return 1; 542 return 1;
@@ -544,9 +555,8 @@ static int push_node_left(struct ctree_root *root, struct tree_buffer *dst_buf,
544 memmove(src->blockptrs, src->blockptrs + push_items, 555 memmove(src->blockptrs, src->blockptrs + push_items,
545 (src_nritems - push_items) * sizeof(u64)); 556 (src_nritems - push_items) * sizeof(u64));
546 } 557 }
547 src->header.nritems -= push_items; 558 btrfs_set_header_nritems(&src->header, src_nritems - push_items);
548 dst->header.nritems += push_items; 559 btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
549
550 BUG_ON(list_empty(&src_buf->dirty)); 560 BUG_ON(list_empty(&src_buf->dirty));
551 BUG_ON(list_empty(&dst_buf->dirty)); 561 BUG_ON(list_empty(&dst_buf->dirty));
552 return ret; 562 return ret;
@@ -573,8 +583,8 @@ static int balance_node_right(struct ctree_root *root,
573 int dst_nritems; 583 int dst_nritems;
574 int ret = 0; 584 int ret = 0;
575 585
576 src_nritems = src->header.nritems; 586 src_nritems = btrfs_header_nritems(&src->header);
577 dst_nritems = dst->header.nritems; 587 dst_nritems = btrfs_header_nritems(&dst->header);
578 push_items = NODEPTRS_PER_BLOCK - dst_nritems; 588 push_items = NODEPTRS_PER_BLOCK - dst_nritems;
579 if (push_items <= 0) { 589 if (push_items <= 0) {
580 return 1; 590 return 1;
@@ -596,8 +606,8 @@ static int balance_node_right(struct ctree_root *root,
596 memcpy(dst->blockptrs, src->blockptrs + src_nritems - push_items, 606 memcpy(dst->blockptrs, src->blockptrs + src_nritems - push_items,
597 push_items * sizeof(u64)); 607 push_items * sizeof(u64));
598 608
599 src->header.nritems -= push_items; 609 btrfs_set_header_nritems(&src->header, src_nritems - push_items);
600 dst->header.nritems += push_items; 610 btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
601 611
602 BUG_ON(list_empty(&src_buf->dirty)); 612 BUG_ON(list_empty(&src_buf->dirty));
603 BUG_ON(list_empty(&dst_buf->dirty)); 613 BUG_ON(list_empty(&dst_buf->dirty));
@@ -625,12 +635,13 @@ static int insert_new_root(struct ctree_root *root,
625 t = alloc_free_block(root); 635 t = alloc_free_block(root);
626 c = &t->node; 636 c = &t->node;
627 memset(c, 0, sizeof(c)); 637 memset(c, 0, sizeof(c));
628 c->header.nritems = 1; 638 btrfs_set_header_nritems(&c->header, 1);
629 c->header.flags = node_level(level); 639 btrfs_set_header_level(&c->header, level);
630 c->header.blocknr = t->blocknr; 640 btrfs_set_header_blocknr(&c->header, t->blocknr);
631 c->header.parentid = root->node->node.header.parentid; 641 btrfs_set_header_parentid(&c->header,
642 btrfs_header_parentid(&root->node->node.header));
632 lower = &path->nodes[level-1]->node; 643 lower = &path->nodes[level-1]->node;
633 if (is_leaf(lower->header.flags)) 644 if (btrfs_is_leaf(lower))
634 lower_key = &((struct leaf *)lower)->items[0].key; 645 lower_key = &((struct leaf *)lower)->items[0].key;
635 else 646 else
636 lower_key = lower->keys; 647 lower_key = lower->keys;
@@ -663,7 +674,7 @@ static int insert_ptr(struct ctree_root *root,
663 674
664 BUG_ON(!path->nodes[level]); 675 BUG_ON(!path->nodes[level]);
665 lower = &path->nodes[level]->node; 676 lower = &path->nodes[level]->node;
666 nritems = lower->header.nritems; 677 nritems = btrfs_header_nritems(&lower->header);
667 if (slot > nritems) 678 if (slot > nritems)
668 BUG(); 679 BUG();
669 if (nritems == NODEPTRS_PER_BLOCK) 680 if (nritems == NODEPTRS_PER_BLOCK)
@@ -676,7 +687,7 @@ static int insert_ptr(struct ctree_root *root,
676 } 687 }
677 memcpy(lower->keys + slot, key, sizeof(struct key)); 688 memcpy(lower->keys + slot, key, sizeof(struct key));
678 lower->blockptrs[slot] = blocknr; 689 lower->blockptrs[slot] = blocknr;
679 lower->header.nritems++; 690 btrfs_set_header_nritems(&lower->header, nritems + 1);
680 if (lower->keys[1].objectid == 0) 691 if (lower->keys[1].objectid == 0)
681 BUG(); 692 BUG();
682 BUG_ON(list_empty(&path->nodes[level]->dirty)); 693 BUG_ON(list_empty(&path->nodes[level]->dirty));
@@ -702,6 +713,7 @@ static int split_node(struct ctree_root *root, struct ctree_path *path,
702 int mid; 713 int mid;
703 int ret; 714 int ret;
704 int wret; 715 int wret;
716 u32 c_nritems;
705 717
706 t = path->nodes[level]; 718 t = path->nodes[level];
707 c = &t->node; 719 c = &t->node;
@@ -711,18 +723,20 @@ static int split_node(struct ctree_root *root, struct ctree_path *path,
711 if (ret) 723 if (ret)
712 return ret; 724 return ret;
713 } 725 }
726 c_nritems = btrfs_header_nritems(&c->header);
714 split_buffer = alloc_free_block(root); 727 split_buffer = alloc_free_block(root);
715 split = &split_buffer->node; 728 split = &split_buffer->node;
716 split->header.flags = c->header.flags; 729 btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
717 split->header.blocknr = split_buffer->blocknr; 730 btrfs_set_header_blocknr(&split->header, split_buffer->blocknr);
718 split->header.parentid = root->node->node.header.parentid; 731 btrfs_set_header_parentid(&split->header,
719 mid = (c->header.nritems + 1) / 2; 732 btrfs_header_parentid(&root->node->node.header));
733 mid = (c_nritems + 1) / 2;
720 memcpy(split->keys, c->keys + mid, 734 memcpy(split->keys, c->keys + mid,
721 (c->header.nritems - mid) * sizeof(struct key)); 735 (c_nritems - mid) * sizeof(struct key));
722 memcpy(split->blockptrs, c->blockptrs + mid, 736 memcpy(split->blockptrs, c->blockptrs + mid,
723 (c->header.nritems - mid) * sizeof(u64)); 737 (c_nritems - mid) * sizeof(u64));
724 split->header.nritems = c->header.nritems - mid; 738 btrfs_set_header_nritems(&split->header, c_nritems - mid);
725 c->header.nritems = mid; 739 btrfs_set_header_nritems(&c->header, mid);
726 ret = 0; 740 ret = 0;
727 741
728 BUG_ON(list_empty(&t->dirty)); 742 BUG_ON(list_empty(&t->dirty));
@@ -781,13 +795,15 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
781 int push_space = 0; 795 int push_space = 0;
782 int push_items = 0; 796 int push_items = 0;
783 struct item *item; 797 struct item *item;
798 u32 left_nritems;
799 u32 right_nritems;
784 800
785 slot = path->slots[1]; 801 slot = path->slots[1];
786 if (!path->nodes[1]) { 802 if (!path->nodes[1]) {
787 return 1; 803 return 1;
788 } 804 }
789 upper = path->nodes[1]; 805 upper = path->nodes[1];
790 if (slot >= upper->node.header.nritems - 1) { 806 if (slot >= btrfs_header_nritems(&upper->node.header) - 1) {
791 return 1; 807 return 1;
792 } 808 }
793 right_buf = read_tree_block(root, upper->node.blockptrs[slot + 1]); 809 right_buf = read_tree_block(root, upper->node.blockptrs[slot + 1]);
@@ -806,7 +822,8 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
806 return 1; 822 return 1;
807 } 823 }
808 824
809 for (i = left->header.nritems - 1; i >= 0; i--) { 825 left_nritems = btrfs_header_nritems(&left->header);
826 for (i = left_nritems - 1; i >= 0; i--) {
810 item = left->items + i; 827 item = left->items + i;
811 if (path->slots[0] == i) 828 if (path->slots[0] == i)
812 push_space += data_size + sizeof(*item); 829 push_space += data_size + sizeof(*item);
@@ -819,9 +836,10 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
819 tree_block_release(root, right_buf); 836 tree_block_release(root, right_buf);
820 return 1; 837 return 1;
821 } 838 }
839 right_nritems = btrfs_header_nritems(&right->header);
822 /* push left to right */ 840 /* push left to right */
823 push_space = left->items[left->header.nritems - push_items].offset + 841 push_space = left->items[left_nritems - push_items].offset +
824 left->items[left->header.nritems - push_items].size; 842 left->items[left_nritems - push_items].size;
825 push_space -= leaf_data_end(left); 843 push_space -= leaf_data_end(left);
826 /* make room in the right data area */ 844 /* make room in the right data area */
827 memmove(right->data + leaf_data_end(right) - push_space, 845 memmove(right->data + leaf_data_end(right) - push_space,
@@ -832,19 +850,21 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
832 left->data + leaf_data_end(left), 850 left->data + leaf_data_end(left),
833 push_space); 851 push_space);
834 memmove(right->items + push_items, right->items, 852 memmove(right->items + push_items, right->items,
835 right->header.nritems * sizeof(struct item)); 853 right_nritems * sizeof(struct item));
836 /* copy the items from left to right */ 854 /* copy the items from left to right */
837 memcpy(right->items, left->items + left->header.nritems - push_items, 855 memcpy(right->items, left->items + left_nritems - push_items,
838 push_items * sizeof(struct item)); 856 push_items * sizeof(struct item));
839 857
840 /* update the item pointers */ 858 /* update the item pointers */
841 right->header.nritems += push_items; 859 right_nritems += push_items;
860 btrfs_set_header_nritems(&right->header, right_nritems);
842 push_space = LEAF_DATA_SIZE; 861 push_space = LEAF_DATA_SIZE;
843 for (i = 0; i < right->header.nritems; i++) { 862 for (i = 0; i < right_nritems; i++) {
844 right->items[i].offset = push_space - right->items[i].size; 863 right->items[i].offset = push_space - right->items[i].size;
845 push_space = right->items[i].offset; 864 push_space = right->items[i].offset;
846 } 865 }
847 left->header.nritems -= push_items; 866 left_nritems -= push_items;
867 btrfs_set_header_nritems(&left->header, left_nritems);
848 868
849 BUG_ON(list_empty(&left_buf->dirty)); 869 BUG_ON(list_empty(&left_buf->dirty));
850 BUG_ON(list_empty(&right_buf->dirty)); 870 BUG_ON(list_empty(&right_buf->dirty));
@@ -853,8 +873,8 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
853 BUG_ON(list_empty(&upper->dirty)); 873 BUG_ON(list_empty(&upper->dirty));
854 874
855 /* then fixup the leaf pointer in the path */ 875 /* then fixup the leaf pointer in the path */
856 if (path->slots[0] >= left->header.nritems) { 876 if (path->slots[0] >= left_nritems) {
857 path->slots[0] -= left->header.nritems; 877 path->slots[0] -= left_nritems;
858 tree_block_release(root, path->nodes[0]); 878 tree_block_release(root, path->nodes[0]);
859 path->nodes[0] = right_buf; 879 path->nodes[0] = right_buf;
860 path->slots[1] += 1; 880 path->slots[1] += 1;
@@ -880,7 +900,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
880 int push_space = 0; 900 int push_space = 0;
881 int push_items = 0; 901 int push_items = 0;
882 struct item *item; 902 struct item *item;
883 int old_left_nritems; 903 u32 old_left_nritems;
884 int ret = 0; 904 int ret = 0;
885 int wret; 905 int wret;
886 906
@@ -908,7 +928,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
908 return 1; 928 return 1;
909 } 929 }
910 930
911 for (i = 0; i < right->header.nritems; i++) { 931 for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
912 item = right->items + i; 932 item = right->items + i;
913 if (path->slots[0] == i) 933 if (path->slots[0] == i)
914 push_space += data_size + sizeof(*item); 934 push_space += data_size + sizeof(*item);
@@ -922,31 +942,34 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
922 return 1; 942 return 1;
923 } 943 }
924 /* push data from right to left */ 944 /* push data from right to left */
925 memcpy(left->items + left->header.nritems, 945 memcpy(left->items + btrfs_header_nritems(&left->header),
926 right->items, push_items * sizeof(struct item)); 946 right->items, push_items * sizeof(struct item));
927 push_space = LEAF_DATA_SIZE - right->items[push_items -1].offset; 947 push_space = LEAF_DATA_SIZE - right->items[push_items -1].offset;
928 memcpy(left->data + leaf_data_end(left) - push_space, 948 memcpy(left->data + leaf_data_end(left) - push_space,
929 right->data + right->items[push_items - 1].offset, 949 right->data + right->items[push_items - 1].offset,
930 push_space); 950 push_space);
931 old_left_nritems = left->header.nritems; 951 old_left_nritems = btrfs_header_nritems(&left->header);
932 BUG_ON(old_left_nritems < 0); 952 BUG_ON(old_left_nritems < 0);
933 953
934 for(i = old_left_nritems; i < old_left_nritems + push_items; i++) { 954 for(i = old_left_nritems; i < old_left_nritems + push_items; i++) {
935 left->items[i].offset -= LEAF_DATA_SIZE - 955 left->items[i].offset -= LEAF_DATA_SIZE -
936 left->items[old_left_nritems -1].offset; 956 left->items[old_left_nritems -1].offset;
937 } 957 }
938 left->header.nritems += push_items; 958 btrfs_set_header_nritems(&left->header, old_left_nritems + push_items);
939 959
940 /* fixup right node */ 960 /* fixup right node */
941 push_space = right->items[push_items-1].offset - leaf_data_end(right); 961 push_space = right->items[push_items-1].offset - leaf_data_end(right);
942 memmove(right->data + LEAF_DATA_SIZE - push_space, right->data + 962 memmove(right->data + LEAF_DATA_SIZE - push_space, right->data +
943 leaf_data_end(right), push_space); 963 leaf_data_end(right), push_space);
944 memmove(right->items, right->items + push_items, 964 memmove(right->items, right->items + push_items,
945 (right->header.nritems - push_items) * sizeof(struct item)); 965 (btrfs_header_nritems(&right->header) - push_items) *
946 right->header.nritems -= push_items; 966 sizeof(struct item));
967 btrfs_set_header_nritems(&right->header,
968 btrfs_header_nritems(&right->header) -
969 push_items);
947 push_space = LEAF_DATA_SIZE; 970 push_space = LEAF_DATA_SIZE;
948 971
949 for (i = 0; i < right->header.nritems; i++) { 972 for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
950 right->items[i].offset = push_space - right->items[i].size; 973 right->items[i].offset = push_space - right->items[i].size;
951 push_space = right->items[i].offset; 974 push_space = right->items[i].offset;
952 } 975 }
@@ -983,7 +1006,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
983{ 1006{
984 struct tree_buffer *l_buf; 1007 struct tree_buffer *l_buf;
985 struct leaf *l; 1008 struct leaf *l;
986 int nritems; 1009 u32 nritems;
987 int mid; 1010 int mid;
988 int slot; 1011 int slot;
989 struct leaf *right; 1012 struct leaf *right;
@@ -1008,7 +1031,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
1008 return ret; 1031 return ret;
1009 } 1032 }
1010 slot = path->slots[0]; 1033 slot = path->slots[0];
1011 nritems = l->header.nritems; 1034 nritems = btrfs_header_nritems(&l->header);
1012 mid = (nritems + 1)/ 2; 1035 mid = (nritems + 1)/ 2;
1013 right_buffer = alloc_free_block(root); 1036 right_buffer = alloc_free_block(root);
1014 BUG_ON(!right_buffer); 1037 BUG_ON(!right_buffer);
@@ -1026,10 +1049,11 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
1026 LEAF_DATA_SIZE) 1049 LEAF_DATA_SIZE)
1027 BUG(); 1050 BUG();
1028 } 1051 }
1029 right->header.nritems = nritems - mid; 1052 btrfs_set_header_nritems(&right->header, nritems - mid);
1030 right->header.blocknr = right_buffer->blocknr; 1053 btrfs_set_header_blocknr(&right->header, right_buffer->blocknr);
1031 right->header.flags = node_level(0); 1054 btrfs_set_header_level(&right->header, 0);
1032 right->header.parentid = root->node->node.header.parentid; 1055 btrfs_set_header_parentid(&right->header,
1056 btrfs_header_parentid(&root->node->node.header));
1033 data_copy_size = l->items[mid].offset + l->items[mid].size - 1057 data_copy_size = l->items[mid].offset + l->items[mid].size -
1034 leaf_data_end(l); 1058 leaf_data_end(l);
1035 memcpy(right->items, l->items + mid, 1059 memcpy(right->items, l->items + mid,
@@ -1039,10 +1063,10 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
1039 rt_data_off = LEAF_DATA_SIZE - 1063 rt_data_off = LEAF_DATA_SIZE -
1040 (l->items[mid].offset + l->items[mid].size); 1064 (l->items[mid].offset + l->items[mid].size);
1041 1065
1042 for (i = 0; i < right->header.nritems; i++) 1066 for (i = 0; i < btrfs_header_nritems(&right->header); i++)
1043 right->items[i].offset += rt_data_off; 1067 right->items[i].offset += rt_data_off;
1044 1068
1045 l->header.nritems = mid; 1069 btrfs_set_header_nritems(&l->header, mid);
1046 ret = 0; 1070 ret = 0;
1047 wret = insert_ptr(root, path, &right->items[0].key, 1071 wret = insert_ptr(root, path, &right->items[0].key,
1048 right_buffer->blocknr, path->slots[1] + 1, 1); 1072 right_buffer->blocknr, path->slots[1] + 1, 1);
@@ -1074,7 +1098,7 @@ int insert_item(struct ctree_root *root, struct key *key,
1074 int slot_orig; 1098 int slot_orig;
1075 struct leaf *leaf; 1099 struct leaf *leaf;
1076 struct tree_buffer *leaf_buf; 1100 struct tree_buffer *leaf_buf;
1077 unsigned int nritems; 1101 u32 nritems;
1078 unsigned int data_end; 1102 unsigned int data_end;
1079 struct ctree_path path; 1103 struct ctree_path path;
1080 1104
@@ -1094,7 +1118,7 @@ int insert_item(struct ctree_root *root, struct key *key,
1094 leaf_buf = path.nodes[0]; 1118 leaf_buf = path.nodes[0];
1095 leaf = &leaf_buf->leaf; 1119 leaf = &leaf_buf->leaf;
1096 1120
1097 nritems = leaf->header.nritems; 1121 nritems = btrfs_header_nritems(&leaf->header);
1098 data_end = leaf_data_end(leaf); 1122 data_end = leaf_data_end(leaf);
1099 1123
1100 if (leaf_free_space(leaf) < sizeof(struct item) + data_size) 1124 if (leaf_free_space(leaf) < sizeof(struct item) + data_size)
@@ -1128,7 +1152,7 @@ int insert_item(struct ctree_root *root, struct key *key,
1128 leaf->items[slot].offset = data_end - data_size; 1152 leaf->items[slot].offset = data_end - data_size;
1129 leaf->items[slot].size = data_size; 1153 leaf->items[slot].size = data_size;
1130 memcpy(leaf->data + data_end - data_size, data, data_size); 1154 memcpy(leaf->data + data_end - data_size, data, data_size);
1131 leaf->header.nritems += 1; 1155 btrfs_set_header_nritems(&leaf->header, nritems + 1);
1132 1156
1133 ret = 0; 1157 ret = 0;
1134 if (slot == 0) 1158 if (slot == 0)
@@ -1155,12 +1179,12 @@ static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level,
1155{ 1179{
1156 struct node *node; 1180 struct node *node;
1157 struct tree_buffer *parent = path->nodes[level]; 1181 struct tree_buffer *parent = path->nodes[level];
1158 int nritems; 1182 u32 nritems;
1159 int ret = 0; 1183 int ret = 0;
1160 int wret; 1184 int wret;
1161 1185
1162 node = &parent->node; 1186 node = &parent->node;
1163 nritems = node->header.nritems; 1187 nritems = btrfs_header_nritems(&node->header);
1164 if (slot != nritems -1) { 1188 if (slot != nritems -1) {
1165 memmove(node->keys + slot, node->keys + slot + 1, 1189 memmove(node->keys + slot, node->keys + slot + 1,
1166 sizeof(struct key) * (nritems - slot - 1)); 1190 sizeof(struct key) * (nritems - slot - 1));
@@ -1168,11 +1192,12 @@ static int del_ptr(struct ctree_root *root, struct ctree_path *path, int level,
1168 node->blockptrs + slot + 1, 1192 node->blockptrs + slot + 1,
1169 sizeof(u64) * (nritems - slot - 1)); 1193 sizeof(u64) * (nritems - slot - 1));
1170 } 1194 }
1171 node->header.nritems--; 1195 nritems--;
1172 if (node->header.nritems == 0 && parent == root->node) { 1196 btrfs_set_header_nritems(&node->header, nritems);
1173 BUG_ON(node_level(root->node->node.header.flags) != 1); 1197 if (nritems == 0 && parent == root->node) {
1198 BUG_ON(btrfs_header_level(&root->node->node.header) != 1);
1174 /* just turn the root into a leaf and break */ 1199 /* just turn the root into a leaf and break */
1175 root->node->node.header.flags = node_level(0); 1200 btrfs_set_header_level(&root->node->node.header, 0);
1176 } else if (slot == 0) { 1201 } else if (slot == 0) {
1177 wret = fixup_low_keys(root, path, node->keys, level + 1); 1202 wret = fixup_low_keys(root, path, node->keys, level + 1);
1178 if (wret) 1203 if (wret)
@@ -1195,30 +1220,33 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
1195 int dsize; 1220 int dsize;
1196 int ret = 0; 1221 int ret = 0;
1197 int wret; 1222 int wret;
1223 u32 nritems;
1198 1224
1199 leaf_buf = path->nodes[0]; 1225 leaf_buf = path->nodes[0];
1200 leaf = &leaf_buf->leaf; 1226 leaf = &leaf_buf->leaf;
1201 slot = path->slots[0]; 1227 slot = path->slots[0];
1202 doff = leaf->items[slot].offset; 1228 doff = leaf->items[slot].offset;
1203 dsize = leaf->items[slot].size; 1229 dsize = leaf->items[slot].size;
1230 nritems = btrfs_header_nritems(&leaf->header);
1204 1231
1205 if (slot != leaf->header.nritems - 1) { 1232 if (slot != nritems - 1) {
1206 int i; 1233 int i;
1207 int data_end = leaf_data_end(leaf); 1234 int data_end = leaf_data_end(leaf);
1208 memmove(leaf->data + data_end + dsize, 1235 memmove(leaf->data + data_end + dsize,
1209 leaf->data + data_end, 1236 leaf->data + data_end,
1210 doff - data_end); 1237 doff - data_end);
1211 for (i = slot + 1; i < leaf->header.nritems; i++) 1238 for (i = slot + 1; i < nritems; i++)
1212 leaf->items[i].offset += dsize; 1239 leaf->items[i].offset += dsize;
1213 memmove(leaf->items + slot, leaf->items + slot + 1, 1240 memmove(leaf->items + slot, leaf->items + slot + 1,
1214 sizeof(struct item) * 1241 sizeof(struct item) *
1215 (leaf->header.nritems - slot - 1)); 1242 (nritems - slot - 1));
1216 } 1243 }
1217 leaf->header.nritems -= 1; 1244 btrfs_set_header_nritems(&leaf->header, nritems - 1);
1245 nritems--;
1218 /* delete the leaf if we've emptied it */ 1246 /* delete the leaf if we've emptied it */
1219 if (leaf->header.nritems == 0) { 1247 if (nritems == 0) {
1220 if (leaf_buf == root->node) { 1248 if (leaf_buf == root->node) {
1221 leaf->header.flags = node_level(0); 1249 btrfs_set_header_level(&leaf->header, 0);
1222 BUG_ON(list_empty(&leaf_buf->dirty)); 1250 BUG_ON(list_empty(&leaf_buf->dirty));
1223 } else { 1251 } else {
1224 clean_tree_block(root, leaf_buf); 1252 clean_tree_block(root, leaf_buf);
@@ -1230,7 +1258,7 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
1230 ret = wret; 1258 ret = wret;
1231 } 1259 }
1232 } else { 1260 } else {
1233 int used = leaf_space_used(leaf, 0, leaf->header.nritems); 1261 int used = leaf_space_used(leaf, 0, nritems);
1234 if (slot == 0) { 1262 if (slot == 0) {
1235 wret = fixup_low_keys(root, path, 1263 wret = fixup_low_keys(root, path,
1236 &leaf->items[0].key, 1); 1264 &leaf->items[0].key, 1);
@@ -1251,12 +1279,12 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
1251 if (wret < 0) 1279 if (wret < 0)
1252 ret = wret; 1280 ret = wret;
1253 if (path->nodes[0] == leaf_buf && 1281 if (path->nodes[0] == leaf_buf &&
1254 leaf->header.nritems) { 1282 btrfs_header_nritems(&leaf->header)) {
1255 wret = push_leaf_right(root, path, 1); 1283 wret = push_leaf_right(root, path, 1);
1256 if (wret < 0) 1284 if (wret < 0)
1257 ret = wret; 1285 ret = wret;
1258 } 1286 }
1259 if (leaf->header.nritems == 0) { 1287 if (btrfs_header_nritems(&leaf->header) == 0) {
1260 u64 blocknr = leaf_buf->blocknr; 1288 u64 blocknr = leaf_buf->blocknr;
1261 clean_tree_block(root, leaf_buf); 1289 clean_tree_block(root, leaf_buf);
1262 wret = del_ptr(root, path, 1, slot); 1290 wret = del_ptr(root, path, 1, slot);
@@ -1292,7 +1320,7 @@ int next_leaf(struct ctree_root *root, struct ctree_path *path)
1292 return 1; 1320 return 1;
1293 slot = path->slots[level] + 1; 1321 slot = path->slots[level] + 1;
1294 c = path->nodes[level]; 1322 c = path->nodes[level];
1295 if (slot >= c->node.header.nritems) { 1323 if (slot >= btrfs_header_nritems(&c->node.header)) {
1296 level++; 1324 level++;
1297 continue; 1325 continue;
1298 } 1326 }
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 518326fa3694..60c21fe1566a 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -35,13 +35,10 @@ struct header {
35 /* generation flags to be added */ 35 /* generation flags to be added */
36} __attribute__ ((__packed__)); 36} __attribute__ ((__packed__));
37 37
38#define MAX_LEVEL 8
38#define NODEPTRS_PER_BLOCK ((CTREE_BLOCKSIZE - sizeof(struct header)) / \ 39#define NODEPTRS_PER_BLOCK ((CTREE_BLOCKSIZE - sizeof(struct header)) / \
39 (sizeof(struct key) + sizeof(u64))) 40 (sizeof(struct key) + sizeof(u64)))
40 41
41#define MAX_LEVEL 8
42#define node_level(f) ((f) & (MAX_LEVEL-1))
43#define is_leaf(f) (node_level(f) == 0)
44
45struct tree_buffer; 42struct tree_buffer;
46 43
47/* 44/*
@@ -144,6 +141,64 @@ struct ctree_path {
144 int slots[MAX_LEVEL]; 141 int slots[MAX_LEVEL];
145}; 142};
146 143
144static inline u64 btrfs_header_blocknr(struct header *h)
145{
146 return h->blocknr;
147}
148
149static inline void btrfs_set_header_blocknr(struct header *h, u64 blocknr)
150{
151 h->blocknr = blocknr;
152}
153
154static inline u64 btrfs_header_parentid(struct header *h)
155{
156 return h->parentid;
157}
158
159static inline void btrfs_set_header_parentid(struct header *h, u64 parentid)
160{
161 h->parentid = parentid;
162}
163
164static inline u32 btrfs_header_nritems(struct header *h)
165{
166 return h->nritems;
167}
168
169static inline void btrfs_set_header_nritems(struct header *h, u32 val)
170{
171 h->nritems = val;
172}
173
174static inline u32 btrfs_header_flags(struct header *h)
175{
176 return h->flags;
177}
178
179static inline void btrfs_set_header_flags(struct header *h, u32 val)
180{
181 h->flags = val;
182}
183
184static inline int btrfs_header_level(struct header *h)
185{
186 return btrfs_header_flags(h) & (MAX_LEVEL - 1);
187}
188
189static inline void btrfs_set_header_level(struct header *h, int level)
190{
191 u32 flags;
192 BUG_ON(level > MAX_LEVEL);
193 flags = btrfs_header_flags(h) & ~(MAX_LEVEL - 1);
194 btrfs_set_header_flags(h, flags | level);
195}
196
197static inline int btrfs_is_leaf(struct node *n)
198{
199 return (btrfs_header_level(&n->header) == 0);
200}
201
147struct tree_buffer *alloc_free_block(struct ctree_root *root); 202struct tree_buffer *alloc_free_block(struct ctree_root *root);
148int btrfs_inc_ref(struct ctree_root *root, struct tree_buffer *buf); 203int btrfs_inc_ref(struct ctree_root *root, struct tree_buffer *buf);
149int free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks); 204int free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index c9201ec81fef..065e888d2c0b 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -15,9 +15,10 @@ int cache_max = 10000;
15 15
16static int check_tree_block(struct ctree_root *root, struct tree_buffer *buf) 16static int check_tree_block(struct ctree_root *root, struct tree_buffer *buf)
17{ 17{
18 if (buf->blocknr != buf->node.header.blocknr) 18 if (buf->blocknr != btrfs_header_blocknr(&buf->node.header))
19 BUG(); 19 BUG();
20 if (root->node && buf->node.header.parentid != root->node->node.header.parentid) 20 if (root->node && btrfs_header_parentid(&buf->node.header) !=
21 btrfs_header_parentid(&root->node->node.header))
21 BUG(); 22 BUG();
22 return 0; 23 return 0;
23} 24}
@@ -129,7 +130,7 @@ int write_tree_block(struct ctree_root *root, struct tree_buffer *buf)
129 loff_t offset = blocknr * CTREE_BLOCKSIZE; 130 loff_t offset = blocknr * CTREE_BLOCKSIZE;
130 int ret; 131 int ret;
131 132
132 if (buf->blocknr != buf->node.header.blocknr) 133 if (buf->blocknr != btrfs_header_blocknr(&buf->node.header))
133 BUG(); 134 BUG();
134 ret = pwrite(root->fp, &buf->node, CTREE_BLOCKSIZE, offset); 135 ret = pwrite(root->fp, &buf->node, CTREE_BLOCKSIZE, offset);
135 if (ret != CTREE_BLOCKSIZE) 136 if (ret != CTREE_BLOCKSIZE)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index e7b8a70b5e52..524c11fea24a 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -79,10 +79,10 @@ int btrfs_inc_ref(struct ctree_root *root, struct tree_buffer *buf)
79 79
80 if (root == root->extent_root) 80 if (root == root->extent_root)
81 return 0; 81 return 0;
82 if (is_leaf(buf->node.header.flags)) 82 if (btrfs_is_leaf(&buf->node))
83 return 0; 83 return 0;
84 84
85 for (i = 0; i < buf->node.header.nritems; i++) { 85 for (i = 0; i < btrfs_header_nritems(&buf->node.header); i++) {
86 blocknr = buf->node.blockptrs[i]; 86 blocknr = buf->node.blockptrs[i];
87 inc_block_ref(root, blocknr); 87 inc_block_ref(root, blocknr);
88 } 88 }
@@ -119,7 +119,8 @@ static int finish_current_insert(struct ctree_root *extent_root)
119 int ret; 119 int ret;
120 120
121 extent_item.refs = 1; 121 extent_item.refs = 1;
122 extent_item.owner = extent_root->node->node.header.parentid; 122 extent_item.owner =
123 btrfs_header_parentid(&extent_root->node->node.header);
123 ins.offset = 1; 124 ins.offset = 1;
124 ins.flags = 0; 125 ins.flags = 0;
125 126
@@ -269,7 +270,7 @@ static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks,
269 struct ctree_root * root = orig_root->extent_root; 270 struct ctree_root * root = orig_root->extent_root;
270 int total_needed = num_blocks; 271 int total_needed = num_blocks;
271 272
272 total_needed += (node_level(root->node->node.header.flags) + 1) * 3; 273 total_needed += (btrfs_header_level(&root->node->node.header) + 1) * 3;
273 if (root->last_insert.objectid > search_start) 274 if (root->last_insert.objectid > search_start)
274 search_start = root->last_insert.objectid; 275 search_start = root->last_insert.objectid;
275check_failed: 276check_failed:
@@ -288,7 +289,7 @@ check_failed:
288 while (1) { 289 while (1) {
289 l = &path.nodes[0]->leaf; 290 l = &path.nodes[0]->leaf;
290 slot = path.slots[0]; 291 slot = path.slots[0];
291 if (slot >= l->header.nritems) { 292 if (slot >= btrfs_header_nritems(&l->header)) {
292 ret = next_leaf(root, &path); 293 ret = next_leaf(root, &path);
293 if (ret == 0) 294 if (ret == 0)
294 continue; 295 continue;
@@ -404,7 +405,7 @@ struct tree_buffer *alloc_free_block(struct ctree_root *root)
404 struct tree_buffer *buf; 405 struct tree_buffer *buf;
405 406
406 ret = alloc_extent(root, 1, 0, (unsigned long)-1, 407 ret = alloc_extent(root, 1, 0, (unsigned long)-1,
407 root->node->node.header.parentid, 408 btrfs_header_parentid(&root->node->node.header),
408 &ins); 409 &ins);
409 if (ret) { 410 if (ret) {
410 BUG(); 411 BUG();
@@ -429,7 +430,8 @@ int walk_down_tree(struct ctree_root *root, struct ctree_path *path, int *level)
429 goto out; 430 goto out;
430 while(*level > 0) { 431 while(*level > 0) {
431 cur = path->nodes[*level]; 432 cur = path->nodes[*level];
432 if (path->slots[*level] >= cur->node.header.nritems) 433 if (path->slots[*level] >=
434 btrfs_header_nritems(&cur->node.header))
433 break; 435 break;
434 blocknr = cur->node.blockptrs[path->slots[*level]]; 436 blocknr = cur->node.blockptrs[path->slots[*level]];
435 ret = lookup_block_ref(root, blocknr, &refs); 437 ret = lookup_block_ref(root, blocknr, &refs);
@@ -444,7 +446,7 @@ int walk_down_tree(struct ctree_root *root, struct ctree_path *path, int *level)
444 if (path->nodes[*level-1]) 446 if (path->nodes[*level-1])
445 tree_block_release(root, path->nodes[*level-1]); 447 tree_block_release(root, path->nodes[*level-1]);
446 path->nodes[*level-1] = next; 448 path->nodes[*level-1] = next;
447 *level = node_level(next->node.header.flags); 449 *level = btrfs_header_level(&next->node.header);
448 path->slots[*level] = 0; 450 path->slots[*level] = 0;
449 } 451 }
450out: 452out:
@@ -463,7 +465,8 @@ int walk_up_tree(struct ctree_root *root, struct ctree_path *path, int *level)
463 int ret; 465 int ret;
464 for(i = *level; i < MAX_LEVEL - 1 && path->nodes[i]; i++) { 466 for(i = *level; i < MAX_LEVEL - 1 && path->nodes[i]; i++) {
465 slot = path->slots[i]; 467 slot = path->slots[i];
466 if (slot < path->nodes[i]->node.header.nritems - 1) { 468 if (slot <
469 btrfs_header_nritems(&path->nodes[i]->node.header)- 1) {
467 path->slots[i]++; 470 path->slots[i]++;
468 *level = i; 471 *level = i;
469 return 0; 472 return 0;
@@ -489,7 +492,7 @@ int btrfs_drop_snapshot(struct ctree_root *root, struct tree_buffer *snap)
489 492
490 init_path(&path); 493 init_path(&path);
491 494
492 level = node_level(snap->node.header.flags); 495 level = btrfs_header_level(&snap->node.header);
493 orig_level = level; 496 orig_level = level;
494 path.nodes[level] = snap; 497 path.nodes[level] = snap;
495 path.slots[level] = 0; 498 path.slots[level] = 0;
@@ -509,33 +512,3 @@ int btrfs_drop_snapshot(struct ctree_root *root, struct tree_buffer *snap)
509 512
510 return 0; 513 return 0;
511} 514}
512
513
514#if 0
515int btrfs_drop_snapshot(struct ctree_root *root, struct tree_buffer *snap)
516{
517 int ret;
518 int level;
519 int refs;
520 u64 blocknr = snap->blocknr;
521
522 level = node_level(snap->node.header.flags);
523 ret = lookup_block_ref(root, snap->blocknr, &refs);
524 BUG_ON(ret);
525 if (refs == 1 && level != 0) {
526 struct node *n = &snap->node;
527 struct tree_buffer *b;
528 int i;
529 for (i = 0; i < n->header.nritems; i++) {
530 b = read_tree_block(root, n->blockptrs[i]);
531 /* FIXME, don't recurse here */
532 ret = btrfs_drop_snapshot(root, b);
533 BUG_ON(ret);
534 tree_block_release(root, b);
535 }
536 }
537 ret = free_extent(root, blocknr, 1);
538 BUG_ON(ret);
539 return 0;
540}
541#endif
diff --git a/fs/btrfs/mkfs.c b/fs/btrfs/mkfs.c
index fd4e5dea7e1b..b2ba94696297 100644
--- a/fs/btrfs/mkfs.c
+++ b/fs/btrfs/mkfs.c
@@ -34,15 +34,15 @@ int mkfs(int fd)
34 34
35 /* create leaves for the tree root and extent root */ 35 /* create leaves for the tree root and extent root */
36 memset(&empty_leaf, 0, sizeof(empty_leaf)); 36 memset(&empty_leaf, 0, sizeof(empty_leaf));
37 empty_leaf.header.parentid = 1; 37 btrfs_set_header_parentid(&empty_leaf.header, 1);
38 empty_leaf.header.blocknr = 17; 38 btrfs_set_header_blocknr(&empty_leaf.header, 17);
39 ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 17 * CTREE_BLOCKSIZE); 39 ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 17 * CTREE_BLOCKSIZE);
40 if (ret != sizeof(empty_leaf)) 40 if (ret != sizeof(empty_leaf))
41 return -1; 41 return -1;
42 42
43 empty_leaf.header.parentid = 2; 43 btrfs_set_header_parentid(&empty_leaf.header, 2);
44 empty_leaf.header.blocknr = 18; 44 btrfs_set_header_blocknr(&empty_leaf.header, 18);
45 empty_leaf.header.nritems = 3; 45 btrfs_set_header_nritems(&empty_leaf.header, 3);
46 46
47 /* item1, reserve blocks 0-16 */ 47 /* item1, reserve blocks 0-16 */
48 item.key.objectid = 0; 48 item.key.objectid = 0;
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index e32a959dd3e5..7df16b1e4733 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -8,11 +8,11 @@
8void print_leaf(struct leaf *l) 8void print_leaf(struct leaf *l)
9{ 9{
10 int i; 10 int i;
11 int nr = l->header.nritems; 11 u32 nr = btrfs_header_nritems(&l->header);
12 struct item *item; 12 struct item *item;
13 struct extent_item *ei; 13 struct extent_item *ei;
14 printf("leaf %Lu total ptrs %d free space %d\n", l->header.blocknr, nr, 14 printf("leaf %Lu total ptrs %d free space %d\n",
15 leaf_free_space(l)); 15 btrfs_header_blocknr(&l->header), nr, leaf_free_space(l));
16 fflush(stdout); 16 fflush(stdout);
17 for (i = 0 ; i < nr ; i++) { 17 for (i = 0 ; i < nr ; i++) {
18 item = l->items + i; 18 item = l->items + i;
@@ -32,22 +32,20 @@ void print_leaf(struct leaf *l)
32void print_tree(struct ctree_root *root, struct tree_buffer *t) 32void print_tree(struct ctree_root *root, struct tree_buffer *t)
33{ 33{
34 int i; 34 int i;
35 int nr; 35 u32 nr;
36 struct node *c; 36 struct node *c;
37 37
38 if (!t) 38 if (!t)
39 return; 39 return;
40 c = &t->node; 40 c = &t->node;
41 nr = c->header.nritems; 41 nr = btrfs_header_nritems(&c->header);
42 if (c->header.blocknr != t->blocknr) 42 if (btrfs_is_leaf(c)) {
43 BUG();
44 if (is_leaf(c->header.flags)) {
45 print_leaf((struct leaf *)c); 43 print_leaf((struct leaf *)c);
46 return; 44 return;
47 } 45 }
48 printf("node %Lu level %d total ptrs %d free spc %u\n", t->blocknr, 46 printf("node %Lu level %d total ptrs %d free spc %u\n", t->blocknr,
49 node_level(c->header.flags), c->header.nritems, 47 btrfs_header_level(&c->header), nr,
50 (u32)NODEPTRS_PER_BLOCK - c->header.nritems); 48 (u32)NODEPTRS_PER_BLOCK - nr);
51 fflush(stdout); 49 fflush(stdout);
52 for (i = 0; i < nr; i++) { 50 for (i = 0; i < nr; i++) {
53 printf("\tkey %d (%Lu %u %Lu) block %Lu\n", 51 printf("\tkey %d (%Lu %u %Lu) block %Lu\n",
@@ -60,11 +58,11 @@ void print_tree(struct ctree_root *root, struct tree_buffer *t)
60 struct tree_buffer *next_buf = read_tree_block(root, 58 struct tree_buffer *next_buf = read_tree_block(root,
61 c->blockptrs[i]); 59 c->blockptrs[i]);
62 struct node *next = &next_buf->node; 60 struct node *next = &next_buf->node;
63 if (is_leaf(next->header.flags) && 61 if (btrfs_is_leaf(next) &&
64 node_level(c->header.flags) != 1) 62 btrfs_header_level(&c->header) != 1)
65 BUG(); 63 BUG();
66 if (node_level(next->header.flags) != 64 if (btrfs_header_level(&next->header) !=
67 node_level(c->header.flags) - 1) 65 btrfs_header_level(&c->header) - 1)
68 BUG(); 66 BUG();
69 print_tree(root, next_buf); 67 print_tree(root, next_buf);
70 tree_block_release(root, next_buf); 68 tree_block_release(root, next_buf);
diff --git a/fs/btrfs/quick-test.c b/fs/btrfs/quick-test.c
index ccca9b2c14a3..07fd71b77627 100644
--- a/fs/btrfs/quick-test.c
+++ b/fs/btrfs/quick-test.c
@@ -71,9 +71,10 @@ int main(int ac, char **av) {
71 close_ctree(root, &super); 71 close_ctree(root, &super);
72 root = open_ctree("dbfile", &super); 72 root = open_ctree("dbfile", &super);
73 printf("node %p level %d total ptrs %d free spc %lu\n", root->node, 73 printf("node %p level %d total ptrs %d free spc %lu\n", root->node,
74 node_level(root->node->node.header.flags), 74 btrfs_header_level(&root->node->node.header),
75 root->node->node.header.nritems, 75 btrfs_header_nritems(&root->node->node.header),
76 NODEPTRS_PER_BLOCK - root->node->node.header.nritems); 76 NODEPTRS_PER_BLOCK -
77 btrfs_header_nritems(&root->node->node.header));
77 printf("all searches good, deleting some items\n"); 78 printf("all searches good, deleting some items\n");
78 i = 0; 79 i = 0;
79 srand(55); 80 srand(55);
@@ -126,7 +127,8 @@ int main(int ac, char **av) {
126 release_path(root, &path); 127 release_path(root, &path);
127 } 128 }
128 printf("starting big long delete run\n"); 129 printf("starting big long delete run\n");
129 while(root->node && root->node->node.header.nritems > 0) { 130 while(root->node &&
131 btrfs_header_nritems(&root->node->node.header) > 0) {
130 struct leaf *leaf; 132 struct leaf *leaf;
131 int slot; 133 int slot;
132 ins.objectid = (u64)-1; 134 ins.objectid = (u64)-1;
@@ -137,7 +139,7 @@ int main(int ac, char **av) {
137 139
138 leaf = &path.nodes[0]->leaf; 140 leaf = &path.nodes[0]->leaf;
139 slot = path.slots[0]; 141 slot = path.slots[0];
140 if (slot != leaf->header.nritems) 142 if (slot != btrfs_header_nritems(&leaf->header))
141 BUG(); 143 BUG();
142 while(path.slots[0] > 0) { 144 while(path.slots[0] > 0) {
143 path.slots[0] -= 1; 145 path.slots[0] -= 1;
diff --git a/fs/btrfs/random-test.c b/fs/btrfs/random-test.c
index 7b37b6bae105..5d99b730a69c 100644
--- a/fs/btrfs/random-test.c
+++ b/fs/btrfs/random-test.c
@@ -358,8 +358,8 @@ int main(int ac, char **av)
358 } 358 }
359 if (i && i % 5000 == 0) { 359 if (i && i % 5000 == 0) {
360 printf("open & close, root level %d nritems %d\n", 360 printf("open & close, root level %d nritems %d\n",
361 node_level(root->node->node.header.flags), 361 btrfs_header_level(&root->node->node.header),
362 root->node->node.header.nritems); 362 btrfs_header_nritems(&root->node->node.header));
363 close_ctree(root, &super); 363 close_ctree(root, &super);
364 root = open_ctree("dbfile", &super); 364 root = open_ctree("dbfile", &super);
365 } 365 }