aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.c225
-rw-r--r--fs/btrfs/ctree.h62
-rw-r--r--fs/btrfs/disk-io.c42
-rw-r--r--fs/btrfs/disk-io.h9
-rw-r--r--fs/btrfs/extent-tree.c6
-rw-r--r--fs/btrfs/mkfs.c171
-rw-r--r--fs/btrfs/print-tree.c15
-rw-r--r--fs/btrfs/print-tree.h2
-rw-r--r--fs/btrfs/quick-test.c2
-rw-r--r--fs/btrfs/root-tree.c4
10 files changed, 238 insertions, 300 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index dc620186e501..ece8de7f38ef 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -47,7 +47,7 @@ static int btrfs_cow_block(struct btrfs_root *root,
47 return 0; 47 return 0;
48 } 48 }
49 cow = btrfs_alloc_free_block(root); 49 cow = btrfs_alloc_free_block(root);
50 memcpy(&cow->node, &buf->node, sizeof(buf->node)); 50 memcpy(&cow->node, &buf->node, root->blocksize);
51 btrfs_set_header_blocknr(&cow->node.header, 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);
@@ -72,11 +72,12 @@ static int btrfs_cow_block(struct btrfs_root *root,
72 * this returns the address of the start of the last item, 72 * this returns the address of the start of the last item,
73 * which is the stop of the leaf data stack 73 * which is the stop of the leaf data stack
74 */ 74 */
75static inline unsigned int leaf_data_end(struct btrfs_leaf *leaf) 75static inline unsigned int leaf_data_end(struct btrfs_root *root,
76 struct btrfs_leaf *leaf)
76{ 77{
77 u32 nr = btrfs_header_nritems(&leaf->header); 78 u32 nr = btrfs_header_nritems(&leaf->header);
78 if (nr == 0) 79 if (nr == 0)
79 return sizeof(leaf->data); 80 return BTRFS_LEAF_DATA_SIZE(root);
80 return btrfs_item_offset(leaf->items + nr - 1); 81 return btrfs_item_offset(leaf->items + nr - 1);
81} 82}
82 83
@@ -85,12 +86,12 @@ static inline unsigned int leaf_data_end(struct btrfs_leaf *leaf)
85 * the start of the leaf data. IOW, how much room 86 * the start of the leaf data. IOW, how much room
86 * the leaf has left for both items and data 87 * the leaf has left for both items and data
87 */ 88 */
88int btrfs_leaf_free_space(struct btrfs_leaf *leaf) 89int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf)
89{ 90{
90 int data_end = leaf_data_end(leaf); 91 int data_end = leaf_data_end(root, leaf);
91 int nritems = btrfs_header_nritems(&leaf->header); 92 int nritems = btrfs_header_nritems(&leaf->header);
92 char *items_end = (char *)(leaf->items + nritems + 1); 93 char *items_end = (char *)(leaf->items + nritems + 1);
93 return (char *)(leaf->data + data_end) - (char *)items_end; 94 return (char *)(btrfs_leaf_data(leaf) + data_end) - (char *)items_end;
94} 95}
95 96
96/* 97/*
@@ -117,7 +118,8 @@ static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
117 return 0; 118 return 0;
118} 119}
119 120
120static int check_node(struct btrfs_path *path, int level) 121static int check_node(struct btrfs_root *root, struct btrfs_path *path,
122 int level)
121{ 123{
122 int i; 124 int i;
123 struct btrfs_node *parent = NULL; 125 struct btrfs_node *parent = NULL;
@@ -131,22 +133,23 @@ static int check_node(struct btrfs_path *path, int level)
131 BUG_ON(nritems == 0); 133 BUG_ON(nritems == 0);
132 if (parent) { 134 if (parent) {
133 struct btrfs_disk_key *parent_key; 135 struct btrfs_disk_key *parent_key;
134 parent_key = &parent->keys[parent_slot]; 136 parent_key = &parent->ptrs[parent_slot].key;
135 BUG_ON(memcmp(parent_key, node->keys, 137 BUG_ON(memcmp(parent_key, &node->ptrs[0].key,
136 sizeof(struct btrfs_disk_key))); 138 sizeof(struct btrfs_disk_key)));
137 BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 139 BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
138 btrfs_header_blocknr(&node->header)); 140 btrfs_header_blocknr(&node->header));
139 } 141 }
140 BUG_ON(nritems > NODEPTRS_PER_BLOCK); 142 BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
141 for (i = 0; nritems > 1 && i < nritems - 2; i++) { 143 for (i = 0; nritems > 1 && i < nritems - 2; i++) {
142 struct btrfs_key cpukey; 144 struct btrfs_key cpukey;
143 btrfs_disk_key_to_cpu(&cpukey, &node->keys[i + 1]); 145 btrfs_disk_key_to_cpu(&cpukey, &node->ptrs[i + 1].key);
144 BUG_ON(comp_keys(&node->keys[i], &cpukey) >= 0); 146 BUG_ON(comp_keys(&node->ptrs[i].key, &cpukey) >= 0);
145 } 147 }
146 return 0; 148 return 0;
147} 149}
148 150
149static int check_leaf(struct btrfs_path *path, int level) 151static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
152 int level)
150{ 153{
151 int i; 154 int i;
152 struct btrfs_leaf *leaf = &path->nodes[level]->leaf; 155 struct btrfs_leaf *leaf = &path->nodes[level]->leaf;
@@ -157,14 +160,14 @@ static int check_leaf(struct btrfs_path *path, int level)
157 if (path->nodes[level + 1]) 160 if (path->nodes[level + 1])
158 parent = &path->nodes[level + 1]->node; 161 parent = &path->nodes[level + 1]->node;
159 parent_slot = path->slots[level + 1]; 162 parent_slot = path->slots[level + 1];
160 BUG_ON(btrfs_leaf_free_space(leaf) < 0); 163 BUG_ON(btrfs_leaf_free_space(root, leaf) < 0);
161 164
162 if (nritems == 0) 165 if (nritems == 0)
163 return 0; 166 return 0;
164 167
165 if (parent) { 168 if (parent) {
166 struct btrfs_disk_key *parent_key; 169 struct btrfs_disk_key *parent_key;
167 parent_key = &parent->keys[parent_slot]; 170 parent_key = &parent->ptrs[parent_slot].key;
168 BUG_ON(memcmp(parent_key, &leaf->items[0].key, 171 BUG_ON(memcmp(parent_key, &leaf->items[0].key,
169 sizeof(struct btrfs_disk_key))); 172 sizeof(struct btrfs_disk_key)));
170 BUG_ON(btrfs_node_blockptr(parent, parent_slot) != 173 BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
@@ -180,17 +183,18 @@ static int check_leaf(struct btrfs_path *path, int level)
180 if (i == 0) { 183 if (i == 0) {
181 BUG_ON(btrfs_item_offset(leaf->items + i) + 184 BUG_ON(btrfs_item_offset(leaf->items + i) +
182 btrfs_item_size(leaf->items + i) != 185 btrfs_item_size(leaf->items + i) !=
183 LEAF_DATA_SIZE); 186 BTRFS_LEAF_DATA_SIZE(root));
184 } 187 }
185 } 188 }
186 return 0; 189 return 0;
187} 190}
188 191
189static int check_block(struct btrfs_path *path, int level) 192static int check_block(struct btrfs_root *root, struct btrfs_path *path,
193 int level)
190{ 194{
191 if (level == 0) 195 if (level == 0)
192 return check_leaf(path, level); 196 return check_leaf(root, path, level);
193 return check_node(path, level); 197 return check_node(root, path, level);
194} 198}
195 199
196/* 200/*
@@ -242,8 +246,8 @@ static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
242 key, btrfs_header_nritems(&c->header), 246 key, btrfs_header_nritems(&c->header),
243 slot); 247 slot);
244 } else { 248 } else {
245 return generic_bin_search((void *)c->keys, 249 return generic_bin_search((void *)c->ptrs,
246 sizeof(struct btrfs_disk_key), 250 sizeof(struct btrfs_key_ptr),
247 key, btrfs_header_nritems(&c->header), 251 key, btrfs_header_nritems(&c->header),
248 slot); 252 slot);
249 } 253 }
@@ -311,7 +315,8 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
311 } 315 }
312 parent = &parent_buf->node; 316 parent = &parent_buf->node;
313 317
314 if (btrfs_header_nritems(&mid->header) > NODEPTRS_PER_BLOCK / 4) 318 if (btrfs_header_nritems(&mid->header) >
319 BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
315 return 0; 320 return 0;
316 321
317 left_buf = read_node_slot(root, parent_buf, pslot - 1); 322 left_buf = read_node_slot(root, parent_buf, pslot - 1);
@@ -351,7 +356,8 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
351 if (wret) 356 if (wret)
352 ret = wret; 357 ret = wret;
353 } else { 358 } else {
354 memcpy(parent->keys + pslot + 1, right->keys, 359 memcpy(&parent->ptrs[pslot + 1].key,
360 &right->ptrs[0].key,
355 sizeof(struct btrfs_disk_key)); 361 sizeof(struct btrfs_disk_key));
356 BUG_ON(list_empty(&parent_buf->dirty)); 362 BUG_ON(list_empty(&parent_buf->dirty));
357 } 363 }
@@ -387,7 +393,7 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
387 ret = wret; 393 ret = wret;
388 } else { 394 } else {
389 /* update the parent key to reflect our changes */ 395 /* update the parent key to reflect our changes */
390 memcpy(parent->keys + pslot, mid->keys, 396 memcpy(&parent->ptrs[pslot].key, &mid->ptrs[0].key,
391 sizeof(struct btrfs_disk_key)); 397 sizeof(struct btrfs_disk_key));
392 BUG_ON(list_empty(&parent_buf->dirty)); 398 BUG_ON(list_empty(&parent_buf->dirty));
393 } 399 }
@@ -407,7 +413,7 @@ static int balance_level(struct btrfs_root *root, struct btrfs_path *path,
407 } 413 }
408 } 414 }
409 /* double check we haven't messed things up */ 415 /* double check we haven't messed things up */
410 check_block(path, level); 416 check_block(root, path, level);
411 if (orig_ptr != btrfs_node_blockptr(&path->nodes[level]->node, 417 if (orig_ptr != btrfs_node_blockptr(&path->nodes[level]->node,
412 path->slots[level])) 418 path->slots[level]))
413 BUG(); 419 BUG();
@@ -456,7 +462,7 @@ again:
456 BUG_ON(!cow && ins_len); 462 BUG_ON(!cow && ins_len);
457 c = &b->node; 463 c = &b->node;
458 p->nodes[level] = b; 464 p->nodes[level] = b;
459 ret = check_block(p, level); 465 ret = check_block(root, p, level);
460 if (ret) 466 if (ret)
461 return -1; 467 return -1;
462 ret = bin_search(c, key, &slot); 468 ret = bin_search(c, key, &slot);
@@ -465,7 +471,7 @@ again:
465 slot -= 1; 471 slot -= 1;
466 p->slots[level] = slot; 472 p->slots[level] = slot;
467 if (ins_len > 0 && btrfs_header_nritems(&c->header) == 473 if (ins_len > 0 && btrfs_header_nritems(&c->header) ==
468 NODEPTRS_PER_BLOCK) { 474 BTRFS_NODEPTRS_PER_BLOCK(root)) {
469 int sret = split_node(root, p, level); 475 int sret = split_node(root, p, level);
470 BUG_ON(sret > 0); 476 BUG_ON(sret > 0);
471 if (sret) 477 if (sret)
@@ -488,7 +494,7 @@ again:
488 } else { 494 } else {
489 struct btrfs_leaf *l = (struct btrfs_leaf *)c; 495 struct btrfs_leaf *l = (struct btrfs_leaf *)c;
490 p->slots[level] = slot; 496 p->slots[level] = slot;
491 if (ins_len > 0 && btrfs_leaf_free_space(l) < 497 if (ins_len > 0 && btrfs_leaf_free_space(root, l) <
492 sizeof(struct btrfs_item) + ins_len) { 498 sizeof(struct btrfs_item) + ins_len) {
493 int sret = split_leaf(root, p, ins_len); 499 int sret = split_leaf(root, p, ins_len);
494 BUG_ON(sret > 0); 500 BUG_ON(sret > 0);
@@ -525,7 +531,7 @@ static int fixup_low_keys(struct btrfs_root *root,
525 if (!path->nodes[i]) 531 if (!path->nodes[i])
526 break; 532 break;
527 t = &path->nodes[i]->node; 533 t = &path->nodes[i]->node;
528 memcpy(t->keys + tslot, key, sizeof(*key)); 534 memcpy(&t->ptrs[tslot].key, key, sizeof(*key));
529 BUG_ON(list_empty(&path->nodes[i]->dirty)); 535 BUG_ON(list_empty(&path->nodes[i]->dirty));
530 if (tslot != 0) 536 if (tslot != 0)
531 break; 537 break;
@@ -552,7 +558,7 @@ static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst_buf,
552 558
553 src_nritems = btrfs_header_nritems(&src->header); 559 src_nritems = btrfs_header_nritems(&src->header);
554 dst_nritems = btrfs_header_nritems(&dst->header); 560 dst_nritems = btrfs_header_nritems(&dst->header);
555 push_items = NODEPTRS_PER_BLOCK - dst_nritems; 561 push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
556 if (push_items <= 0) { 562 if (push_items <= 0) {
557 return 1; 563 return 1;
558 } 564 }
@@ -560,16 +566,12 @@ static int push_node_left(struct btrfs_root *root, struct btrfs_buffer *dst_buf,
560 if (src_nritems < push_items) 566 if (src_nritems < push_items)
561 push_items = src_nritems; 567 push_items = src_nritems;
562 568
563 memcpy(dst->keys + dst_nritems, src->keys, 569 memcpy(dst->ptrs + dst_nritems, src->ptrs,
564 push_items * sizeof(struct btrfs_disk_key)); 570 push_items * sizeof(struct btrfs_key_ptr));
565 memcpy(dst->blockptrs + dst_nritems, src->blockptrs,
566 push_items * sizeof(u64));
567 if (push_items < src_nritems) { 571 if (push_items < src_nritems) {
568 memmove(src->keys, src->keys + push_items, 572 memmove(src->ptrs, src->ptrs + push_items,
569 (src_nritems - push_items) * 573 (src_nritems - push_items) *
570 sizeof(struct btrfs_disk_key)); 574 sizeof(struct btrfs_key_ptr));
571 memmove(src->blockptrs, src->blockptrs + push_items,
572 (src_nritems - push_items) * sizeof(u64));
573 } 575 }
574 btrfs_set_header_nritems(&src->header, src_nritems - push_items); 576 btrfs_set_header_nritems(&src->header, src_nritems - push_items);
575 btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 577 btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
@@ -601,7 +603,7 @@ static int balance_node_right(struct btrfs_root *root,
601 603
602 src_nritems = btrfs_header_nritems(&src->header); 604 src_nritems = btrfs_header_nritems(&src->header);
603 dst_nritems = btrfs_header_nritems(&dst->header); 605 dst_nritems = btrfs_header_nritems(&dst->header);
604 push_items = NODEPTRS_PER_BLOCK - dst_nritems; 606 push_items = BTRFS_NODEPTRS_PER_BLOCK(root) - dst_nritems;
605 if (push_items <= 0) { 607 if (push_items <= 0) {
606 return 1; 608 return 1;
607 } 609 }
@@ -613,14 +615,10 @@ static int balance_node_right(struct btrfs_root *root,
613 if (max_push < push_items) 615 if (max_push < push_items)
614 push_items = max_push; 616 push_items = max_push;
615 617
616 memmove(dst->keys + push_items, dst->keys, 618 memmove(dst->ptrs + push_items, dst->ptrs,
617 dst_nritems * sizeof(struct btrfs_disk_key)); 619 dst_nritems * sizeof(struct btrfs_key_ptr));
618 memmove(dst->blockptrs + push_items, dst->blockptrs, 620 memcpy(dst->ptrs, src->ptrs + src_nritems - push_items,
619 dst_nritems * sizeof(u64)); 621 push_items * sizeof(struct btrfs_key_ptr));
620 memcpy(dst->keys, src->keys + src_nritems - push_items,
621 push_items * sizeof(struct btrfs_disk_key));
622 memcpy(dst->blockptrs, src->blockptrs + src_nritems - push_items,
623 push_items * sizeof(u64));
624 622
625 btrfs_set_header_nritems(&src->header, src_nritems - push_items); 623 btrfs_set_header_nritems(&src->header, src_nritems - push_items);
626 btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 624 btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
@@ -650,7 +648,7 @@ static int insert_new_root(struct btrfs_root *root,
650 648
651 t = btrfs_alloc_free_block(root); 649 t = btrfs_alloc_free_block(root);
652 c = &t->node; 650 c = &t->node;
653 memset(c, 0, sizeof(c)); 651 memset(c, 0, root->blocksize);
654 btrfs_set_header_nritems(&c->header, 1); 652 btrfs_set_header_nritems(&c->header, 1);
655 btrfs_set_header_level(&c->header, level); 653 btrfs_set_header_level(&c->header, level);
656 btrfs_set_header_blocknr(&c->header, t->blocknr); 654 btrfs_set_header_blocknr(&c->header, t->blocknr);
@@ -660,8 +658,8 @@ static int insert_new_root(struct btrfs_root *root,
660 if (btrfs_is_leaf(lower)) 658 if (btrfs_is_leaf(lower))
661 lower_key = &((struct btrfs_leaf *)lower)->items[0].key; 659 lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
662 else 660 else
663 lower_key = lower->keys; 661 lower_key = &lower->ptrs[0].key;
664 memcpy(c->keys, lower_key, sizeof(struct btrfs_disk_key)); 662 memcpy(&c->ptrs[0].key, lower_key, sizeof(struct btrfs_disk_key));
665 btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->blocknr); 663 btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->blocknr);
666 /* the super has an extra ref to root->node */ 664 /* the super has an extra ref to root->node */
667 btrfs_block_release(root, root->node); 665 btrfs_block_release(root, root->node);
@@ -693,19 +691,15 @@ static int insert_ptr(struct btrfs_root *root,
693 nritems = btrfs_header_nritems(&lower->header); 691 nritems = btrfs_header_nritems(&lower->header);
694 if (slot > nritems) 692 if (slot > nritems)
695 BUG(); 693 BUG();
696 if (nritems == NODEPTRS_PER_BLOCK) 694 if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
697 BUG(); 695 BUG();
698 if (slot != nritems) { 696 if (slot != nritems) {
699 memmove(lower->keys + slot + 1, lower->keys + slot, 697 memmove(lower->ptrs + slot + 1, lower->ptrs + slot,
700 (nritems - slot) * sizeof(struct btrfs_disk_key)); 698 (nritems - slot) * sizeof(struct btrfs_key_ptr));
701 memmove(lower->blockptrs + slot + 1, lower->blockptrs + slot,
702 (nritems - slot) * sizeof(u64));
703 } 699 }
704 memcpy(lower->keys + slot, key, sizeof(struct btrfs_disk_key)); 700 memcpy(&lower->ptrs[slot].key, key, sizeof(struct btrfs_disk_key));
705 btrfs_set_node_blockptr(lower, slot, blocknr); 701 btrfs_set_node_blockptr(lower, slot, blocknr);
706 btrfs_set_header_nritems(&lower->header, nritems + 1); 702 btrfs_set_header_nritems(&lower->header, nritems + 1);
707 if (lower->keys[1].objectid == 0)
708 BUG();
709 BUG_ON(list_empty(&path->nodes[level]->dirty)); 703 BUG_ON(list_empty(&path->nodes[level]->dirty));
710 return 0; 704 return 0;
711} 705}
@@ -747,17 +741,16 @@ static int split_node(struct btrfs_root *root, struct btrfs_path *path,
747 btrfs_set_header_parentid(&split->header, 741 btrfs_set_header_parentid(&split->header,
748 btrfs_header_parentid(&root->node->node.header)); 742 btrfs_header_parentid(&root->node->node.header));
749 mid = (c_nritems + 1) / 2; 743 mid = (c_nritems + 1) / 2;
750 memcpy(split->keys, c->keys + mid, 744 memcpy(split->ptrs, c->ptrs + mid,
751 (c_nritems - mid) * sizeof(struct btrfs_disk_key)); 745 (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
752 memcpy(split->blockptrs, c->blockptrs + mid,
753 (c_nritems - mid) * sizeof(u64));
754 btrfs_set_header_nritems(&split->header, c_nritems - mid); 746 btrfs_set_header_nritems(&split->header, c_nritems - mid);
755 btrfs_set_header_nritems(&c->header, mid); 747 btrfs_set_header_nritems(&c->header, mid);
756 ret = 0; 748 ret = 0;
757 749
758 BUG_ON(list_empty(&t->dirty)); 750 BUG_ON(list_empty(&t->dirty));
759 wret = insert_ptr(root, path, split->keys, split_buffer->blocknr, 751 wret = insert_ptr(root, path, &split->ptrs[0].key,
760 path->slots[level + 1] + 1, level + 1); 752 split_buffer->blocknr, path->slots[level + 1] + 1,
753 level + 1);
761 if (wret) 754 if (wret)
762 ret = wret; 755 ret = wret;
763 756
@@ -825,7 +818,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
825 right_buf = read_tree_block(root, btrfs_node_blockptr(&upper->node, 818 right_buf = read_tree_block(root, btrfs_node_blockptr(&upper->node,
826 slot + 1)); 819 slot + 1));
827 right = &right_buf->leaf; 820 right = &right_buf->leaf;
828 free_space = btrfs_leaf_free_space(right); 821 free_space = btrfs_leaf_free_space(root, right);
829 if (free_space < data_size + sizeof(struct btrfs_item)) { 822 if (free_space < data_size + sizeof(struct btrfs_item)) {
830 btrfs_block_release(root, right_buf); 823 btrfs_block_release(root, right_buf);
831 return 1; 824 return 1;
@@ -833,7 +826,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
833 /* cow and double check */ 826 /* cow and double check */
834 btrfs_cow_block(root, right_buf, upper, slot + 1, &right_buf); 827 btrfs_cow_block(root, right_buf, upper, slot + 1, &right_buf);
835 right = &right_buf->leaf; 828 right = &right_buf->leaf;
836 free_space = btrfs_leaf_free_space(right); 829 free_space = btrfs_leaf_free_space(root, right);
837 if (free_space < data_size + sizeof(struct btrfs_item)) { 830 if (free_space < data_size + sizeof(struct btrfs_item)) {
838 btrfs_block_release(root, right_buf); 831 btrfs_block_release(root, right_buf);
839 return 1; 832 return 1;
@@ -857,15 +850,14 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
857 right_nritems = btrfs_header_nritems(&right->header); 850 right_nritems = btrfs_header_nritems(&right->header);
858 /* push left to right */ 851 /* push left to right */
859 push_space = btrfs_item_end(left->items + left_nritems - push_items); 852 push_space = btrfs_item_end(left->items + left_nritems - push_items);
860 push_space -= leaf_data_end(left); 853 push_space -= leaf_data_end(root, left);
861 /* make room in the right data area */ 854 /* make room in the right data area */
862 memmove(right->data + leaf_data_end(right) - push_space, 855 memmove(btrfs_leaf_data(right) + leaf_data_end(root, right) -
863 right->data + leaf_data_end(right), 856 push_space, btrfs_leaf_data(right) + leaf_data_end(root, right),
864 LEAF_DATA_SIZE - leaf_data_end(right)); 857 BTRFS_LEAF_DATA_SIZE(root) - leaf_data_end(root, right));
865 /* copy from the left data area */ 858 /* copy from the left data area */
866 memcpy(right->data + LEAF_DATA_SIZE - push_space, 859 memcpy(btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) - push_space,
867 left->data + leaf_data_end(left), 860 btrfs_leaf_data(left) + leaf_data_end(root, left), push_space);
868 push_space);
869 memmove(right->items + push_items, right->items, 861 memmove(right->items + push_items, right->items,
870 right_nritems * sizeof(struct btrfs_item)); 862 right_nritems * sizeof(struct btrfs_item));
871 /* copy the items from left to right */ 863 /* copy the items from left to right */
@@ -875,7 +867,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
875 /* update the item pointers */ 867 /* update the item pointers */
876 right_nritems += push_items; 868 right_nritems += push_items;
877 btrfs_set_header_nritems(&right->header, right_nritems); 869 btrfs_set_header_nritems(&right->header, right_nritems);
878 push_space = LEAF_DATA_SIZE; 870 push_space = BTRFS_LEAF_DATA_SIZE(root);
879 for (i = 0; i < right_nritems; i++) { 871 for (i = 0; i < right_nritems; i++) {
880 btrfs_set_item_offset(right->items + i, push_space - 872 btrfs_set_item_offset(right->items + i, push_space -
881 btrfs_item_size(right->items + i)); 873 btrfs_item_size(right->items + i));
@@ -886,7 +878,7 @@ static int push_leaf_right(struct btrfs_root *root, struct btrfs_path *path,
886 878
887 BUG_ON(list_empty(&left_buf->dirty)); 879 BUG_ON(list_empty(&left_buf->dirty));
888 BUG_ON(list_empty(&right_buf->dirty)); 880 BUG_ON(list_empty(&right_buf->dirty));
889 memcpy(upper->node.keys + slot + 1, 881 memcpy(&upper->node.ptrs[slot + 1].key,
890 &right->items[0].key, sizeof(struct btrfs_disk_key)); 882 &right->items[0].key, sizeof(struct btrfs_disk_key));
891 BUG_ON(list_empty(&upper->dirty)); 883 BUG_ON(list_empty(&upper->dirty));
892 884
@@ -932,7 +924,7 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
932 t = read_tree_block(root, btrfs_node_blockptr(&path->nodes[1]->node, 924 t = read_tree_block(root, btrfs_node_blockptr(&path->nodes[1]->node,
933 slot - 1)); 925 slot - 1));
934 left = &t->leaf; 926 left = &t->leaf;
935 free_space = btrfs_leaf_free_space(left); 927 free_space = btrfs_leaf_free_space(root, left);
936 if (free_space < data_size + sizeof(struct btrfs_item)) { 928 if (free_space < data_size + sizeof(struct btrfs_item)) {
937 btrfs_block_release(root, t); 929 btrfs_block_release(root, t);
938 return 1; 930 return 1;
@@ -941,7 +933,7 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
941 /* cow and double check */ 933 /* cow and double check */
942 btrfs_cow_block(root, t, path->nodes[1], slot - 1, &t); 934 btrfs_cow_block(root, t, path->nodes[1], slot - 1, &t);
943 left = &t->leaf; 935 left = &t->leaf;
944 free_space = btrfs_leaf_free_space(left); 936 free_space = btrfs_leaf_free_space(root, left);
945 if (free_space < data_size + sizeof(struct btrfs_item)) { 937 if (free_space < data_size + sizeof(struct btrfs_item)) {
946 btrfs_block_release(root, t); 938 btrfs_block_release(root, t);
947 return 1; 939 return 1;
@@ -964,17 +956,19 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
964 /* push data from right to left */ 956 /* push data from right to left */
965 memcpy(left->items + btrfs_header_nritems(&left->header), 957 memcpy(left->items + btrfs_header_nritems(&left->header),
966 right->items, push_items * sizeof(struct btrfs_item)); 958 right->items, push_items * sizeof(struct btrfs_item));
967 push_space = LEAF_DATA_SIZE - 959 push_space = BTRFS_LEAF_DATA_SIZE(root) -
968 btrfs_item_offset(right->items + push_items -1); 960 btrfs_item_offset(right->items + push_items -1);
969 memcpy(left->data + leaf_data_end(left) - push_space, 961 memcpy(btrfs_leaf_data(left) + leaf_data_end(root, left) - push_space,
970 right->data + btrfs_item_offset(right->items + push_items - 1), 962 btrfs_leaf_data(right) +
963 btrfs_item_offset(right->items + push_items - 1),
971 push_space); 964 push_space);
972 old_left_nritems = btrfs_header_nritems(&left->header); 965 old_left_nritems = btrfs_header_nritems(&left->header);
973 BUG_ON(old_left_nritems < 0); 966 BUG_ON(old_left_nritems < 0);
974 967
975 for (i = old_left_nritems; i < old_left_nritems + push_items; i++) { 968 for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
976 u16 ioff = btrfs_item_offset(left->items + i); 969 u32 ioff = btrfs_item_offset(left->items + i);
977 btrfs_set_item_offset(left->items + i, ioff - (LEAF_DATA_SIZE - 970 btrfs_set_item_offset(left->items + i, ioff -
971 (BTRFS_LEAF_DATA_SIZE(root) -
978 btrfs_item_offset(left->items + 972 btrfs_item_offset(left->items +
979 old_left_nritems - 1))); 973 old_left_nritems - 1)));
980 } 974 }
@@ -982,16 +976,17 @@ static int push_leaf_left(struct btrfs_root *root, struct btrfs_path *path,
982 976
983 /* fixup right node */ 977 /* fixup right node */
984 push_space = btrfs_item_offset(right->items + push_items - 1) - 978 push_space = btrfs_item_offset(right->items + push_items - 1) -
985 leaf_data_end(right); 979 leaf_data_end(root, right);
986 memmove(right->data + LEAF_DATA_SIZE - push_space, right->data + 980 memmove(btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
987 leaf_data_end(right), push_space); 981 push_space, btrfs_leaf_data(right) +
982 leaf_data_end(root, right), push_space);
988 memmove(right->items, right->items + push_items, 983 memmove(right->items, right->items + push_items,
989 (btrfs_header_nritems(&right->header) - push_items) * 984 (btrfs_header_nritems(&right->header) - push_items) *
990 sizeof(struct btrfs_item)); 985 sizeof(struct btrfs_item));
991 btrfs_set_header_nritems(&right->header, 986 btrfs_set_header_nritems(&right->header,
992 btrfs_header_nritems(&right->header) - 987 btrfs_header_nritems(&right->header) -
993 push_items); 988 push_items);
994 push_space = LEAF_DATA_SIZE; 989 push_space = BTRFS_LEAF_DATA_SIZE(root);
995 990
996 for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 991 for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
997 btrfs_set_item_offset(right->items + i, push_space - 992 btrfs_set_item_offset(right->items + i, push_space -
@@ -1051,12 +1046,12 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
1051 if (wret < 0) 1046 if (wret < 0)
1052 return wret; 1047 return wret;
1053 } 1048 }
1054
1055 l_buf = path->nodes[0]; 1049 l_buf = path->nodes[0];
1056 l = &l_buf->leaf; 1050 l = &l_buf->leaf;
1057 1051
1058 /* did the pushes work? */ 1052 /* did the pushes work? */
1059 if (btrfs_leaf_free_space(l) >= sizeof(struct btrfs_item) + data_size) 1053 if (btrfs_leaf_free_space(root, l) >=
1054 sizeof(struct btrfs_item) + data_size)
1060 return 0; 1055 return 0;
1061 1056
1062 if (!path->nodes[1]) { 1057 if (!path->nodes[1]) {
@@ -1071,16 +1066,16 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
1071 BUG_ON(!right_buffer); 1066 BUG_ON(!right_buffer);
1072 BUG_ON(mid == nritems); 1067 BUG_ON(mid == nritems);
1073 right = &right_buffer->leaf; 1068 right = &right_buffer->leaf;
1074 memset(right, 0, sizeof(*right)); 1069 memset(&right->header, 0, sizeof(right->header));
1075 if (mid <= slot) { 1070 if (mid <= slot) {
1076 /* FIXME, just alloc a new leaf here */ 1071 /* FIXME, just alloc a new leaf here */
1077 if (leaf_space_used(l, mid, nritems - mid) + space_needed > 1072 if (leaf_space_used(l, mid, nritems - mid) + space_needed >
1078 LEAF_DATA_SIZE) 1073 BTRFS_LEAF_DATA_SIZE(root))
1079 BUG(); 1074 BUG();
1080 } else { 1075 } else {
1081 /* FIXME, just alloc a new leaf here */ 1076 /* FIXME, just alloc a new leaf here */
1082 if (leaf_space_used(l, 0, mid + 1) + space_needed > 1077 if (leaf_space_used(l, 0, mid + 1) + space_needed >
1083 LEAF_DATA_SIZE) 1078 BTRFS_LEAF_DATA_SIZE(root))
1084 BUG(); 1079 BUG();
1085 } 1080 }
1086 btrfs_set_header_nritems(&right->header, nritems - mid); 1081 btrfs_set_header_nritems(&right->header, nritems - mid);
@@ -1088,15 +1083,18 @@ static int split_leaf(struct btrfs_root *root, struct btrfs_path *path,
1088 btrfs_set_header_level(&right->header, 0); 1083 btrfs_set_header_level(&right->header, 0);
1089 btrfs_set_header_parentid(&right->header, 1084 btrfs_set_header_parentid(&right->header,
1090 btrfs_header_parentid(&root->node->node.header)); 1085 btrfs_header_parentid(&root->node->node.header));
1091 data_copy_size = btrfs_item_end(l->items + mid) - leaf_data_end(l); 1086 data_copy_size = btrfs_item_end(l->items + mid) -
1087 leaf_data_end(root, l);
1092 memcpy(right->items, l->items + mid, 1088 memcpy(right->items, l->items + mid,
1093 (nritems - mid) * sizeof(struct btrfs_item)); 1089 (nritems - mid) * sizeof(struct btrfs_item));
1094 memcpy(right->data + LEAF_DATA_SIZE - data_copy_size, 1090 memcpy(btrfs_leaf_data(right) + BTRFS_LEAF_DATA_SIZE(root) -
1095 l->data + leaf_data_end(l), data_copy_size); 1091 data_copy_size, btrfs_leaf_data(l) +
1096 rt_data_off = LEAF_DATA_SIZE - btrfs_item_end(l->items + mid); 1092 leaf_data_end(root, l), data_copy_size);
1093 rt_data_off = BTRFS_LEAF_DATA_SIZE(root) -
1094 btrfs_item_end(l->items + mid);
1097 1095
1098 for (i = 0; i < btrfs_header_nritems(&right->header); i++) { 1096 for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
1099 u16 ioff = btrfs_item_offset(right->items + i); 1097 u32 ioff = btrfs_item_offset(right->items + i);
1100 btrfs_set_item_offset(right->items + i, ioff + rt_data_off); 1098 btrfs_set_item_offset(right->items + i, ioff + rt_data_off);
1101 } 1099 }
1102 1100
@@ -1156,9 +1154,9 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
1156 leaf = &leaf_buf->leaf; 1154 leaf = &leaf_buf->leaf;
1157 1155
1158 nritems = btrfs_header_nritems(&leaf->header); 1156 nritems = btrfs_header_nritems(&leaf->header);
1159 data_end = leaf_data_end(leaf); 1157 data_end = leaf_data_end(root, leaf);
1160 1158
1161 if (btrfs_leaf_free_space(leaf) < 1159 if (btrfs_leaf_free_space(root, leaf) <
1162 sizeof(struct btrfs_item) + data_size) 1160 sizeof(struct btrfs_item) + data_size)
1163 BUG(); 1161 BUG();
1164 1162
@@ -1173,7 +1171,7 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
1173 */ 1171 */
1174 /* first correct the data pointers */ 1172 /* first correct the data pointers */
1175 for (i = slot; i < nritems; i++) { 1173 for (i = slot; i < nritems; i++) {
1176 u16 ioff = btrfs_item_offset(leaf->items + i); 1174 u32 ioff = btrfs_item_offset(leaf->items + i);
1177 btrfs_set_item_offset(leaf->items + i, 1175 btrfs_set_item_offset(leaf->items + i,
1178 ioff - data_size); 1176 ioff - data_size);
1179 } 1177 }
@@ -1183,7 +1181,8 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
1183 (nritems - slot) * sizeof(struct btrfs_item)); 1181 (nritems - slot) * sizeof(struct btrfs_item));
1184 1182
1185 /* shift the data */ 1183 /* shift the data */
1186 memmove(leaf->data + data_end - data_size, leaf->data + 1184 memmove(btrfs_leaf_data(leaf) + data_end - data_size,
1185 btrfs_leaf_data(leaf) +
1187 data_end, old_data - data_end); 1186 data_end, old_data - data_end);
1188 data_end = old_data; 1187 data_end = old_data;
1189 } 1188 }
@@ -1192,7 +1191,7 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
1192 sizeof(struct btrfs_disk_key)); 1191 sizeof(struct btrfs_disk_key));
1193 btrfs_set_item_offset(leaf->items + slot, data_end - data_size); 1192 btrfs_set_item_offset(leaf->items + slot, data_end - data_size);
1194 btrfs_set_item_size(leaf->items + slot, data_size); 1193 btrfs_set_item_size(leaf->items + slot, data_size);
1195 memcpy(leaf->data + data_end - data_size, data, data_size); 1194 memcpy(btrfs_leaf_data(leaf) + data_end - data_size, data, data_size);
1196 btrfs_set_header_nritems(&leaf->header, nritems + 1); 1195 btrfs_set_header_nritems(&leaf->header, nritems + 1);
1197 1196
1198 ret = 0; 1197 ret = 0;
@@ -1200,9 +1199,9 @@ int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *cpu_key,
1200 ret = fixup_low_keys(root, &path, &disk_key, 1); 1199 ret = fixup_low_keys(root, &path, &disk_key, 1);
1201 1200
1202 BUG_ON(list_empty(&leaf_buf->dirty)); 1201 BUG_ON(list_empty(&leaf_buf->dirty));
1203 if (btrfs_leaf_free_space(leaf) < 0) 1202 if (btrfs_leaf_free_space(root, leaf) < 0)
1204 BUG(); 1203 BUG();
1205 check_leaf(&path, 0); 1204 check_leaf(root, &path, 0);
1206out: 1205out:
1207 btrfs_release_path(root, &path); 1206 btrfs_release_path(root, &path);
1208 return ret; 1207 return ret;
@@ -1227,11 +1226,8 @@ static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level,
1227 node = &parent->node; 1226 node = &parent->node;
1228 nritems = btrfs_header_nritems(&node->header); 1227 nritems = btrfs_header_nritems(&node->header);
1229 if (slot != nritems -1) { 1228 if (slot != nritems -1) {
1230 memmove(node->keys + slot, node->keys + slot + 1, 1229 memmove(node->ptrs + slot, node->ptrs + slot + 1,
1231 sizeof(struct btrfs_disk_key) * (nritems - slot - 1)); 1230 sizeof(struct btrfs_key_ptr) * (nritems - slot - 1));
1232 memmove(node->blockptrs + slot,
1233 node->blockptrs + slot + 1,
1234 sizeof(u64) * (nritems - slot - 1));
1235 } 1231 }
1236 nritems--; 1232 nritems--;
1237 btrfs_set_header_nritems(&node->header, nritems); 1233 btrfs_set_header_nritems(&node->header, nritems);
@@ -1240,7 +1236,8 @@ static int del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level,
1240 /* just turn the root into a leaf and break */ 1236 /* just turn the root into a leaf and break */
1241 btrfs_set_header_level(&root->node->node.header, 0); 1237 btrfs_set_header_level(&root->node->node.header, 0);
1242 } else if (slot == 0) { 1238 } else if (slot == 0) {
1243 wret = fixup_low_keys(root, path, node->keys, level + 1); 1239 wret = fixup_low_keys(root, path, &node->ptrs[0].key,
1240 level + 1);
1244 if (wret) 1241 if (wret)
1245 ret = wret; 1242 ret = wret;
1246 } 1243 }
@@ -1272,12 +1269,12 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path)
1272 1269
1273 if (slot != nritems - 1) { 1270 if (slot != nritems - 1) {
1274 int i; 1271 int i;
1275 int data_end = leaf_data_end(leaf); 1272 int data_end = leaf_data_end(root, leaf);
1276 memmove(leaf->data + data_end + dsize, 1273 memmove(btrfs_leaf_data(leaf) + data_end + dsize,
1277 leaf->data + data_end, 1274 btrfs_leaf_data(leaf) + data_end,
1278 doff - data_end); 1275 doff - data_end);
1279 for (i = slot + 1; i < nritems; i++) { 1276 for (i = slot + 1; i < nritems; i++) {
1280 u16 ioff = btrfs_item_offset(leaf->items + i); 1277 u32 ioff = btrfs_item_offset(leaf->items + i);
1281 btrfs_set_item_offset(leaf->items + i, ioff + dsize); 1278 btrfs_set_item_offset(leaf->items + i, ioff + dsize);
1282 } 1279 }
1283 memmove(leaf->items + slot, leaf->items + slot + 1, 1280 memmove(leaf->items + slot, leaf->items + slot + 1,
@@ -1311,7 +1308,7 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path)
1311 BUG_ON(list_empty(&leaf_buf->dirty)); 1308 BUG_ON(list_empty(&leaf_buf->dirty));
1312 1309
1313 /* delete the leaf if it is mostly empty */ 1310 /* delete the leaf if it is mostly empty */
1314 if (used < LEAF_DATA_SIZE / 3) { 1311 if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
1315 /* push_leaf_left fixes the path. 1312 /* push_leaf_left fixes the path.
1316 * make sure the path still points to our leaf 1313 * make sure the path still points to our leaf
1317 * for possible call to del_ptr below 1314 * for possible call to del_ptr below
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 05c7707263f5..c61ad0f69be9 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -5,7 +5,6 @@
5#include "kerncompat.h" 5#include "kerncompat.h"
6 6
7#define BTRFS_MAGIC "_BtRfS_M" 7#define BTRFS_MAGIC "_BtRfS_M"
8#define BTRFS_BLOCKSIZE 1024
9 8
10#define BTRFS_ROOT_TREE_OBJECTID 1 9#define BTRFS_ROOT_TREE_OBJECTID 1
11#define BTRFS_EXTENT_TREE_OBJECTID 2 10#define BTRFS_EXTENT_TREE_OBJECTID 2
@@ -52,8 +51,11 @@ struct btrfs_header {
52} __attribute__ ((__packed__)); 51} __attribute__ ((__packed__));
53 52
54#define BTRFS_MAX_LEVEL 8 53#define BTRFS_MAX_LEVEL 8
55#define NODEPTRS_PER_BLOCK ((BTRFS_BLOCKSIZE - sizeof(struct btrfs_header)) / \ 54#define BTRFS_NODEPTRS_PER_BLOCK(r) (((r)->blocksize - \
56 (sizeof(struct btrfs_disk_key) + sizeof(u64))) 55 sizeof(struct btrfs_header)) / \
56 (sizeof(struct btrfs_disk_key) + sizeof(u64)))
57#define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header))
58#define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->blocksize))
57 59
58struct btrfs_buffer; 60struct btrfs_buffer;
59 61
@@ -86,6 +88,7 @@ struct btrfs_root {
86 int ref_cows; 88 int ref_cows;
87 struct btrfs_root_item root_item; 89 struct btrfs_root_item root_item;
88 struct btrfs_key root_key; 90 struct btrfs_key root_key;
91 u32 blocksize;
89}; 92};
90 93
91/* 94/*
@@ -97,7 +100,7 @@ struct btrfs_super_block {
97 __le64 blocknr; /* this block number */ 100 __le64 blocknr; /* this block number */
98 __le32 csum; 101 __le32 csum;
99 __le64 magic; 102 __le64 magic;
100 __le16 blocksize; 103 __le32 blocksize;
101 __le64 generation; 104 __le64 generation;
102 __le64 root; 105 __le64 root;
103 __le64 total_blocks; 106 __le64 total_blocks;
@@ -111,7 +114,7 @@ struct btrfs_super_block {
111 */ 114 */
112struct btrfs_item { 115struct btrfs_item {
113 struct btrfs_disk_key key; 116 struct btrfs_disk_key key;
114 __le16 offset; 117 __le32 offset;
115 __le16 size; 118 __le16 size;
116} __attribute__ ((__packed__)); 119} __attribute__ ((__packed__));
117 120
@@ -122,24 +125,23 @@ struct btrfs_item {
122 * The data is separate from the items to get the keys closer together 125 * The data is separate from the items to get the keys closer together
123 * during searches. 126 * during searches.
124 */ 127 */
125#define LEAF_DATA_SIZE (BTRFS_BLOCKSIZE - sizeof(struct btrfs_header))
126struct btrfs_leaf { 128struct btrfs_leaf {
127 struct btrfs_header header; 129 struct btrfs_header header;
128 union { 130 struct btrfs_item items[];
129 struct btrfs_item items[LEAF_DATA_SIZE/
130 sizeof(struct btrfs_item)];
131 u8 data[BTRFS_BLOCKSIZE - sizeof(struct btrfs_header)];
132 };
133} __attribute__ ((__packed__)); 131} __attribute__ ((__packed__));
134 132
135/* 133/*
136 * all non-leaf blocks are nodes, they hold only keys and pointers to 134 * all non-leaf blocks are nodes, they hold only keys and pointers to
137 * other blocks 135 * other blocks
138 */ 136 */
137struct btrfs_key_ptr {
138 struct btrfs_disk_key key;
139 __le64 blockptr;
140} __attribute__ ((__packed__));
141
139struct btrfs_node { 142struct btrfs_node {
140 struct btrfs_header header; 143 struct btrfs_header header;
141 struct btrfs_disk_key keys[NODEPTRS_PER_BLOCK]; 144 struct btrfs_key_ptr ptrs[];
142 __le64 blockptrs[NODEPTRS_PER_BLOCK];
143} __attribute__ ((__packed__)); 145} __attribute__ ((__packed__));
144 146
145/* 147/*
@@ -186,28 +188,28 @@ static inline void btrfs_set_extent_refs(struct btrfs_extent_item *ei, u32 val)
186 188
187static inline u64 btrfs_node_blockptr(struct btrfs_node *n, int nr) 189static inline u64 btrfs_node_blockptr(struct btrfs_node *n, int nr)
188{ 190{
189 return le64_to_cpu(n->blockptrs[nr]); 191 return le64_to_cpu(n->ptrs[nr].blockptr);
190} 192}
191 193
192static inline void btrfs_set_node_blockptr(struct btrfs_node *n, int nr, 194static inline void btrfs_set_node_blockptr(struct btrfs_node *n, int nr,
193 u64 val) 195 u64 val)
194{ 196{
195 n->blockptrs[nr] = cpu_to_le64(val); 197 n->ptrs[nr].blockptr = cpu_to_le64(val);
196} 198}
197 199
198static inline u16 btrfs_item_offset(struct btrfs_item *item) 200static inline u32 btrfs_item_offset(struct btrfs_item *item)
199{ 201{
200 return le16_to_cpu(item->offset); 202 return le32_to_cpu(item->offset);
201} 203}
202 204
203static inline void btrfs_set_item_offset(struct btrfs_item *item, u16 val) 205static inline void btrfs_set_item_offset(struct btrfs_item *item, u32 val)
204{ 206{
205 item->offset = cpu_to_le16(val); 207 item->offset = cpu_to_le32(val);
206} 208}
207 209
208static inline u16 btrfs_item_end(struct btrfs_item *item) 210static inline u32 btrfs_item_end(struct btrfs_item *item)
209{ 211{
210 return le16_to_cpu(item->offset) + le16_to_cpu(item->size); 212 return le32_to_cpu(item->offset) + le16_to_cpu(item->size);
211} 213}
212 214
213static inline u16 btrfs_item_size(struct btrfs_item *item) 215static inline u16 btrfs_item_size(struct btrfs_item *item)
@@ -390,20 +392,26 @@ static inline void btrfs_set_super_blocks_used(struct btrfs_super_block *s,
390 s->blocks_used = cpu_to_le64(val); 392 s->blocks_used = cpu_to_le64(val);
391} 393}
392 394
393static inline u16 btrfs_super_blocksize(struct btrfs_super_block *s) 395static inline u32 btrfs_super_blocksize(struct btrfs_super_block *s)
394{ 396{
395 return le16_to_cpu(s->blocksize); 397 return le32_to_cpu(s->blocksize);
396} 398}
397 399
398static inline void btrfs_set_super_blocksize(struct btrfs_super_block *s, 400static inline void btrfs_set_super_blocksize(struct btrfs_super_block *s,
399 u16 val) 401 u32 val)
402{
403 s->blocksize = cpu_to_le32(val);
404}
405
406static inline u8 *btrfs_leaf_data(struct btrfs_leaf *l)
400{ 407{
401 s->blocksize = cpu_to_le16(val); 408 return (u8 *)l->items;
402} 409}
403 410
404/* helper function to cast into the data area of the leaf. */ 411/* helper function to cast into the data area of the leaf. */
405#define btrfs_item_ptr(leaf, slot, type) \ 412#define btrfs_item_ptr(leaf, slot, type) \
406 ((type *)((leaf)->data + btrfs_item_offset((leaf)->items + (slot)))) 413 ((type *)(btrfs_leaf_data(leaf) + \
414 btrfs_item_offset((leaf)->items + (slot))))
407 415
408struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root); 416struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root);
409int btrfs_inc_ref(struct btrfs_root *root, struct btrfs_buffer *buf); 417int btrfs_inc_ref(struct btrfs_root *root, struct btrfs_buffer *buf);
@@ -416,7 +424,7 @@ int btrfs_del_item(struct btrfs_root *root, struct btrfs_path *path);
416int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *key, 424int btrfs_insert_item(struct btrfs_root *root, struct btrfs_key *key,
417 void *data, int data_size); 425 void *data, int data_size);
418int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); 426int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
419int btrfs_leaf_free_space(struct btrfs_leaf *leaf); 427int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf);
420int btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_buffer *snap); 428int btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_buffer *snap);
421int btrfs_finish_extent_commit(struct btrfs_root *root); 429int btrfs_finish_extent_commit(struct btrfs_root *root);
422int btrfs_del_root(struct btrfs_root *root, struct btrfs_key *key); 430int btrfs_del_root(struct btrfs_root *root, struct btrfs_key *key);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 3d4bf6833f2a..8d9457b5aef5 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -46,7 +46,8 @@ struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr)
46{ 46{
47 struct btrfs_buffer *buf; 47 struct btrfs_buffer *buf;
48 int ret; 48 int ret;
49 buf = malloc(sizeof(struct btrfs_buffer)); 49
50 buf = malloc(sizeof(struct btrfs_buffer) + root->blocksize);
50 if (!buf) 51 if (!buf)
51 return buf; 52 return buf;
52 allocated_blocks++; 53 allocated_blocks++;
@@ -84,7 +85,7 @@ struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 blocknr)
84 85
85struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr) 86struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
86{ 87{
87 loff_t offset = blocknr * BTRFS_BLOCKSIZE; 88 loff_t offset = blocknr * root->blocksize;
88 struct btrfs_buffer *buf; 89 struct btrfs_buffer *buf;
89 int ret; 90 int ret;
90 91
@@ -95,8 +96,8 @@ struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
95 buf = alloc_tree_block(root, blocknr); 96 buf = alloc_tree_block(root, blocknr);
96 if (!buf) 97 if (!buf)
97 return NULL; 98 return NULL;
98 ret = pread(root->fp, &buf->node, BTRFS_BLOCKSIZE, offset); 99 ret = pread(root->fp, &buf->node, root->blocksize, offset);
99 if (ret != BTRFS_BLOCKSIZE) { 100 if (ret != root->blocksize) {
100 free(buf); 101 free(buf);
101 return NULL; 102 return NULL;
102 } 103 }
@@ -127,13 +128,13 @@ int clean_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
127int write_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf) 128int write_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
128{ 129{
129 u64 blocknr = buf->blocknr; 130 u64 blocknr = buf->blocknr;
130 loff_t offset = blocknr * BTRFS_BLOCKSIZE; 131 loff_t offset = blocknr * root->blocksize;
131 int ret; 132 int ret;
132 133
133 if (buf->blocknr != btrfs_header_blocknr(&buf->node.header)) 134 if (buf->blocknr != btrfs_header_blocknr(&buf->node.header))
134 BUG(); 135 BUG();
135 ret = pwrite(root->fp, &buf->node, BTRFS_BLOCKSIZE, offset); 136 ret = pwrite(root->fp, &buf->node, root->blocksize, offset);
136 if (ret != BTRFS_BLOCKSIZE) 137 if (ret != root->blocksize)
137 return ret; 138 return ret;
138 return 0; 139 return 0;
139} 140}
@@ -215,7 +216,8 @@ int btrfs_commit_transaction(struct btrfs_root *root,
215 return ret; 216 return ret;
216} 217}
217 218
218static int __setup_root(struct btrfs_root *root, u64 objectid, int fp) 219static int __setup_root(struct btrfs_super_block *super,
220 struct btrfs_root *root, u64 objectid, int fp)
219{ 221{
220 INIT_LIST_HEAD(&root->trans); 222 INIT_LIST_HEAD(&root->trans);
221 INIT_LIST_HEAD(&root->cache); 223 INIT_LIST_HEAD(&root->cache);
@@ -223,6 +225,8 @@ static int __setup_root(struct btrfs_root *root, u64 objectid, int fp)
223 root->fp = fp; 225 root->fp = fp;
224 root->node = NULL; 226 root->node = NULL;
225 root->commit_root = NULL; 227 root->commit_root = NULL;
228 root->blocksize = btrfs_super_blocksize(super);
229 root->ref_cows = 0;
226 memset(&root->current_insert, 0, sizeof(root->current_insert)); 230 memset(&root->current_insert, 0, sizeof(root->current_insert));
227 memset(&root->last_insert, 0, sizeof(root->last_insert)); 231 memset(&root->last_insert, 0, sizeof(root->last_insert));
228 memset(&root->root_key, 0, sizeof(root->root_key)); 232 memset(&root->root_key, 0, sizeof(root->root_key));
@@ -230,19 +234,19 @@ static int __setup_root(struct btrfs_root *root, u64 objectid, int fp)
230 return 0; 234 return 0;
231} 235}
232 236
233static int find_and_setup_root(struct btrfs_root *tree_root, u64 objectid, 237static int find_and_setup_root(struct btrfs_super_block *super,
234 struct btrfs_root *root, int fp) 238 struct btrfs_root *tree_root, u64 objectid,
239 struct btrfs_root *root, int fp)
235{ 240{
236 int ret; 241 int ret;
237 242
238 __setup_root(root, objectid, fp); 243 __setup_root(super, root, objectid, fp);
239 ret = btrfs_find_last_root(tree_root, objectid, 244 ret = btrfs_find_last_root(tree_root, objectid,
240 &root->root_item, &root->root_key); 245 &root->root_item, &root->root_key);
241 BUG_ON(ret); 246 BUG_ON(ret);
242 247
243 root->node = read_tree_block(root, 248 root->node = read_tree_block(root,
244 btrfs_root_blocknr(&root->root_item)); 249 btrfs_root_blocknr(&root->root_item));
245 root->ref_cows = 0;
246 BUG_ON(!root->node); 250 BUG_ON(!root->node);
247 return 0; 251 return 0;
248} 252}
@@ -277,28 +281,28 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super)
277 INIT_RADIX_TREE(&tree_root->cache_radix, GFP_KERNEL); 281 INIT_RADIX_TREE(&tree_root->cache_radix, GFP_KERNEL);
278 282
279 ret = pread(fp, super, sizeof(struct btrfs_super_block), 283 ret = pread(fp, super, sizeof(struct btrfs_super_block),
280 BTRFS_SUPER_INFO_OFFSET(BTRFS_BLOCKSIZE)); 284 BTRFS_SUPER_INFO_OFFSET);
281 if (ret == 0 || btrfs_super_root(super) == 0) { 285 if (ret == 0 || btrfs_super_root(super) == 0) {
282 printf("making new FS!\n"); 286 printf("making new FS!\n");
283 ret = mkfs(fp, 0, BTRFS_BLOCKSIZE); 287 ret = mkfs(fp, 0, 1024);
284 if (ret) 288 if (ret)
285 return NULL; 289 return NULL;
286 ret = pread(fp, super, sizeof(struct btrfs_super_block), 290 ret = pread(fp, super, sizeof(struct btrfs_super_block),
287 BTRFS_SUPER_INFO_OFFSET(BTRFS_BLOCKSIZE)); 291 BTRFS_SUPER_INFO_OFFSET);
288 if (ret != sizeof(struct btrfs_super_block)) 292 if (ret != sizeof(struct btrfs_super_block))
289 return NULL; 293 return NULL;
290 } 294 }
291 BUG_ON(ret < 0); 295 BUG_ON(ret < 0);
292 296
293 __setup_root(tree_root, BTRFS_ROOT_TREE_OBJECTID, fp); 297 __setup_root(super, tree_root, BTRFS_ROOT_TREE_OBJECTID, fp);
294 tree_root->node = read_tree_block(tree_root, btrfs_super_root(super)); 298 tree_root->node = read_tree_block(tree_root, btrfs_super_root(super));
295 BUG_ON(!tree_root->node); 299 BUG_ON(!tree_root->node);
296 300
297 ret = find_and_setup_root(tree_root, BTRFS_EXTENT_TREE_OBJECTID, 301 ret = find_and_setup_root(super, tree_root, BTRFS_EXTENT_TREE_OBJECTID,
298 extent_root, fp); 302 extent_root, fp);
299 BUG_ON(ret); 303 BUG_ON(ret);
300 304
301 ret = find_and_setup_root(tree_root, BTRFS_FS_TREE_OBJECTID, 305 ret = find_and_setup_root(super, tree_root, BTRFS_FS_TREE_OBJECTID,
302 root, fp); 306 root, fp);
303 BUG_ON(ret); 307 BUG_ON(ret);
304 308
@@ -313,7 +317,7 @@ int write_ctree_super(struct btrfs_root *root, struct btrfs_super_block *s)
313 int ret; 317 int ret;
314 btrfs_set_super_root(s, root->tree_root->node->blocknr); 318 btrfs_set_super_root(s, root->tree_root->node->blocknr);
315 ret = pwrite(root->fp, s, sizeof(*s), 319 ret = pwrite(root->fp, s, sizeof(*s),
316 BTRFS_SUPER_INFO_OFFSET(BTRFS_BLOCKSIZE)); 320 BTRFS_SUPER_INFO_OFFSET);
317 if (ret != sizeof(*s)) { 321 if (ret != sizeof(*s)) {
318 fprintf(stderr, "failed to write new super block err %d\n", ret); 322 fprintf(stderr, "failed to write new super block err %d\n", ret);
319 return ret; 323 return ret;
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index c22a61f9233f..5771bb90acb2 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -5,12 +5,12 @@
5struct btrfs_buffer { 5struct btrfs_buffer {
6 u64 blocknr; 6 u64 blocknr;
7 int count; 7 int count;
8 struct list_head dirty;
9 struct list_head cache;
8 union { 10 union {
9 struct btrfs_node node; 11 struct btrfs_node node;
10 struct btrfs_leaf leaf; 12 struct btrfs_leaf leaf;
11 }; 13 };
12 struct list_head dirty;
13 struct list_head cache;
14}; 14};
15 15
16struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr); 16struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr);
@@ -24,9 +24,8 @@ struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *s);
24int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s); 24int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s);
25void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf); 25void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf);
26int write_ctree_super(struct btrfs_root *root, struct btrfs_super_block *s); 26int write_ctree_super(struct btrfs_root *root, struct btrfs_super_block *s);
27int mkfs(int fd, u64 num_blocks, u16 blocksize); 27int mkfs(int fd, u64 num_blocks, u32 blocksize);
28
29 28
30#define BTRFS_SUPER_INFO_OFFSET(bs) (16 * (bs)) 29#define BTRFS_SUPER_INFO_OFFSET (16 * 1024)
31 30
32#endif 31#endif
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 3767744f659e..d4f1ec328399 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -143,7 +143,6 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks)
143 struct btrfs_key key; 143 struct btrfs_key key;
144 struct btrfs_root *extent_root = root->extent_root; 144 struct btrfs_root *extent_root = root->extent_root;
145 int ret; 145 int ret;
146 struct btrfs_item *item;
147 struct btrfs_extent_item *ei; 146 struct btrfs_extent_item *ei;
148 struct btrfs_key ins; 147 struct btrfs_key ins;
149 u32 refs; 148 u32 refs;
@@ -161,9 +160,8 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks)
161 printf("failed to find %Lu\n", key.objectid); 160 printf("failed to find %Lu\n", key.objectid);
162 BUG(); 161 BUG();
163 } 162 }
164 item = path.nodes[0]->leaf.items + path.slots[0]; 163 ei = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0],
165 ei = (struct btrfs_extent_item *)(path.nodes[0]->leaf.data + 164 struct btrfs_extent_item);
166 btrfs_item_offset(item));
167 BUG_ON(ei->refs == 0); 165 BUG_ON(ei->refs == 0);
168 refs = btrfs_extent_refs(ei) - 1; 166 refs = btrfs_extent_refs(ei) - 1;
169 btrfs_set_extent_refs(ei, refs); 167 btrfs_set_extent_refs(ei, refs);
diff --git a/fs/btrfs/mkfs.c b/fs/btrfs/mkfs.c
index dd14ed4fea6c..317d20ce759d 100644
--- a/fs/btrfs/mkfs.c
+++ b/fs/btrfs/mkfs.c
@@ -10,19 +10,20 @@
10#include "ctree.h" 10#include "ctree.h"
11#include "disk-io.h" 11#include "disk-io.h"
12 12
13int mkfs(int fd, u64 num_blocks, u16 blocksize) 13int mkfs(int fd, u64 num_blocks, u32 blocksize)
14{ 14{
15 struct btrfs_super_block super; 15 struct btrfs_super_block super;
16 struct btrfs_leaf empty_leaf; 16 struct btrfs_leaf *empty_leaf;
17 struct btrfs_root_item root_item; 17 struct btrfs_root_item root_item;
18 struct btrfs_item item; 18 struct btrfs_item item;
19 struct btrfs_extent_item extent_item; 19 struct btrfs_extent_item extent_item;
20 char *block; 20 char *block;
21 int ret; 21 int ret;
22 u16 itemoff; 22 u32 itemoff;
23 u32 start_block = BTRFS_SUPER_INFO_OFFSET / blocksize;
23 24
24 btrfs_set_super_blocknr(&super, 16); 25 btrfs_set_super_blocknr(&super, start_block);
25 btrfs_set_super_root(&super, 17); 26 btrfs_set_super_root(&super, start_block + 1);
26 strcpy((char *)(&super.magic), BTRFS_MAGIC); 27 strcpy((char *)(&super.magic), BTRFS_MAGIC);
27 btrfs_set_super_blocksize(&super, blocksize); 28 btrfs_set_super_blocksize(&super, blocksize);
28 btrfs_set_super_total_blocks(&super, num_blocks); 29 btrfs_set_super_total_blocks(&super, num_blocks);
@@ -32,168 +33,98 @@ int mkfs(int fd, u64 num_blocks, u16 blocksize)
32 memset(block, 0, blocksize); 33 memset(block, 0, blocksize);
33 BUG_ON(sizeof(super) > blocksize); 34 BUG_ON(sizeof(super) > blocksize);
34 memcpy(block, &super, sizeof(super)); 35 memcpy(block, &super, sizeof(super));
35 ret = pwrite(fd, block, blocksize, BTRFS_SUPER_INFO_OFFSET(blocksize)); 36 ret = pwrite(fd, block, blocksize, BTRFS_SUPER_INFO_OFFSET);
36 BUG_ON(ret != blocksize); 37 BUG_ON(ret != blocksize);
37 38
38 /* create the tree of root objects */ 39 /* create the tree of root objects */
39 memset(&empty_leaf, 0, sizeof(empty_leaf)); 40 empty_leaf = malloc(blocksize);
40 btrfs_set_header_parentid(&empty_leaf.header, BTRFS_ROOT_TREE_OBJECTID); 41 memset(empty_leaf, 0, blocksize);
41 btrfs_set_header_blocknr(&empty_leaf.header, 17); 42 btrfs_set_header_parentid(&empty_leaf->header,
42 btrfs_set_header_nritems(&empty_leaf.header, 2); 43 BTRFS_ROOT_TREE_OBJECTID);
44 btrfs_set_header_blocknr(&empty_leaf->header, start_block + 1);
45 btrfs_set_header_nritems(&empty_leaf->header, 2);
43 46
44 /* create the items for the root tree */ 47 /* create the items for the root tree */
45 btrfs_set_root_blocknr(&root_item, 18); 48 btrfs_set_root_blocknr(&root_item, start_block + 2);
46 btrfs_set_root_refs(&root_item, 1); 49 btrfs_set_root_refs(&root_item, 1);
47 itemoff = LEAF_DATA_SIZE - sizeof(root_item); 50 itemoff = __BTRFS_LEAF_DATA_SIZE(blocksize) - sizeof(root_item);
48 btrfs_set_item_offset(&item, itemoff); 51 btrfs_set_item_offset(&item, itemoff);
49 btrfs_set_item_size(&item, sizeof(root_item)); 52 btrfs_set_item_size(&item, sizeof(root_item));
50 btrfs_set_key_objectid(&item.key, BTRFS_EXTENT_TREE_OBJECTID); 53 btrfs_set_key_objectid(&item.key, BTRFS_EXTENT_TREE_OBJECTID);
51 btrfs_set_key_offset(&item.key, 0); 54 btrfs_set_key_offset(&item.key, 0);
52 btrfs_set_key_flags(&item.key, 0); 55 btrfs_set_key_flags(&item.key, 0);
53 memcpy(empty_leaf.items, &item, sizeof(item)); 56 memcpy(empty_leaf->items, &item, sizeof(item));
54 memcpy(empty_leaf.data + itemoff, &root_item, sizeof(root_item)); 57 memcpy(btrfs_leaf_data(empty_leaf) + itemoff,
58 &root_item, sizeof(root_item));
55 59
56 btrfs_set_root_blocknr(&root_item, 19); 60 btrfs_set_root_blocknr(&root_item, start_block + 3);
57 itemoff = itemoff - sizeof(root_item); 61 itemoff = itemoff - sizeof(root_item);
58 btrfs_set_item_offset(&item, itemoff); 62 btrfs_set_item_offset(&item, itemoff);
59 btrfs_set_key_objectid(&item.key, BTRFS_FS_TREE_OBJECTID); 63 btrfs_set_key_objectid(&item.key, BTRFS_FS_TREE_OBJECTID);
60 memcpy(empty_leaf.items + 1, &item, sizeof(item)); 64 memcpy(empty_leaf->items + 1, &item, sizeof(item));
61 memcpy(empty_leaf.data + itemoff, &root_item, sizeof(root_item)); 65 memcpy(btrfs_leaf_data(empty_leaf) + itemoff,
62 ret = pwrite(fd, &empty_leaf, blocksize, 17 * blocksize); 66 &root_item, sizeof(root_item));
67 ret = pwrite(fd, empty_leaf, blocksize, (start_block + 1) * blocksize);
63 68
64 /* create the items for the extent tree */ 69 /* create the items for the extent tree */
65 btrfs_set_header_parentid(&empty_leaf.header, 70 btrfs_set_header_parentid(&empty_leaf->header,
66 BTRFS_EXTENT_TREE_OBJECTID); 71 BTRFS_EXTENT_TREE_OBJECTID);
67 btrfs_set_header_blocknr(&empty_leaf.header, 18); 72 btrfs_set_header_blocknr(&empty_leaf->header, start_block + 2);
68 btrfs_set_header_nritems(&empty_leaf.header, 4); 73 btrfs_set_header_nritems(&empty_leaf->header, 4);
69 74
70 /* item1, reserve blocks 0-16 */ 75 /* item1, reserve blocks 0-16 */
71 btrfs_set_key_objectid(&item.key, 0); 76 btrfs_set_key_objectid(&item.key, 0);
72 btrfs_set_key_offset(&item.key, 17); 77 btrfs_set_key_offset(&item.key, start_block + 1);
73 btrfs_set_key_flags(&item.key, 0); 78 btrfs_set_key_flags(&item.key, 0);
74 itemoff = LEAF_DATA_SIZE - sizeof(struct btrfs_extent_item); 79 itemoff = __BTRFS_LEAF_DATA_SIZE(blocksize) -
80 sizeof(struct btrfs_extent_item);
75 btrfs_set_item_offset(&item, itemoff); 81 btrfs_set_item_offset(&item, itemoff);
76 btrfs_set_item_size(&item, sizeof(struct btrfs_extent_item)); 82 btrfs_set_item_size(&item, sizeof(struct btrfs_extent_item));
77 btrfs_set_extent_refs(&extent_item, 1); 83 btrfs_set_extent_refs(&extent_item, 1);
78 btrfs_set_extent_owner(&extent_item, 0); 84 btrfs_set_extent_owner(&extent_item, 0);
79 memcpy(empty_leaf.items, &item, sizeof(item)); 85 memcpy(empty_leaf->items, &item, sizeof(item));
80 memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item, 86 memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
81 btrfs_item_size(&item)); 87 &extent_item, btrfs_item_size(&item));
82 88
83 /* item2, give block 17 to the root */ 89 /* item2, give block 17 to the root */
84 btrfs_set_key_objectid(&item.key, 17); 90 btrfs_set_key_objectid(&item.key, start_block + 1);
85 btrfs_set_key_offset(&item.key, 1); 91 btrfs_set_key_offset(&item.key, 1);
86 itemoff = itemoff - sizeof(struct btrfs_extent_item); 92 itemoff = itemoff - sizeof(struct btrfs_extent_item);
87 btrfs_set_item_offset(&item, itemoff); 93 btrfs_set_item_offset(&item, itemoff);
88 btrfs_set_extent_owner(&extent_item, BTRFS_ROOT_TREE_OBJECTID); 94 btrfs_set_extent_owner(&extent_item, BTRFS_ROOT_TREE_OBJECTID);
89 memcpy(empty_leaf.items + 1, &item, sizeof(item)); 95 memcpy(empty_leaf->items + 1, &item, sizeof(item));
90 memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item, 96 memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
91 btrfs_item_size(&item)); 97 &extent_item, btrfs_item_size(&item));
92 98
93 /* item3, give block 18 to the extent root */ 99 /* item3, give block 18 to the extent root */
94 btrfs_set_key_objectid(&item.key, 18); 100 btrfs_set_key_objectid(&item.key, start_block + 2);
95 btrfs_set_key_offset(&item.key, 1); 101 btrfs_set_key_offset(&item.key, 1);
96 itemoff = itemoff - sizeof(struct btrfs_extent_item); 102 itemoff = itemoff - sizeof(struct btrfs_extent_item);
97 btrfs_set_item_offset(&item, itemoff); 103 btrfs_set_item_offset(&item, itemoff);
98 btrfs_set_extent_owner(&extent_item, BTRFS_EXTENT_TREE_OBJECTID); 104 btrfs_set_extent_owner(&extent_item, BTRFS_EXTENT_TREE_OBJECTID);
99 memcpy(empty_leaf.items + 2, &item, sizeof(item)); 105 memcpy(empty_leaf->items + 2, &item, sizeof(item));
100 memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item, 106 memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
101 btrfs_item_size(&item)); 107 &extent_item, btrfs_item_size(&item));
102 108
103 /* item4, give block 19 to the FS root */ 109 /* item4, give block 19 to the FS root */
104 btrfs_set_key_objectid(&item.key, 19); 110 btrfs_set_key_objectid(&item.key, start_block + 3);
105 btrfs_set_key_offset(&item.key, 1); 111 btrfs_set_key_offset(&item.key, 1);
106 itemoff = itemoff - sizeof(struct btrfs_extent_item); 112 itemoff = itemoff - sizeof(struct btrfs_extent_item);
107 btrfs_set_item_offset(&item, itemoff); 113 btrfs_set_item_offset(&item, itemoff);
108 btrfs_set_extent_owner(&extent_item, BTRFS_FS_TREE_OBJECTID); 114 btrfs_set_extent_owner(&extent_item, BTRFS_FS_TREE_OBJECTID);
109 memcpy(empty_leaf.items + 3, &item, sizeof(item)); 115 memcpy(empty_leaf->items + 3, &item, sizeof(item));
110 memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item, 116 memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
111 btrfs_item_size(&item)); 117 &extent_item, btrfs_item_size(&item));
112 ret = pwrite(fd, &empty_leaf, blocksize, 18 * blocksize); 118 ret = pwrite(fd, empty_leaf, blocksize, (start_block + 2) * blocksize);
113 if (ret != sizeof(empty_leaf)) 119 if (ret != blocksize)
114 return -1; 120 return -1;
115 121
116 /* finally create the FS root */ 122 /* finally create the FS root */
117 btrfs_set_header_parentid(&empty_leaf.header, BTRFS_FS_TREE_OBJECTID); 123 btrfs_set_header_parentid(&empty_leaf->header, BTRFS_FS_TREE_OBJECTID);
118 btrfs_set_header_blocknr(&empty_leaf.header, 19); 124 btrfs_set_header_blocknr(&empty_leaf->header, start_block + 3);
119 btrfs_set_header_nritems(&empty_leaf.header, 0); 125 btrfs_set_header_nritems(&empty_leaf->header, 0);
120 ret = pwrite(fd, &empty_leaf, blocksize, 19 * blocksize); 126 ret = pwrite(fd, empty_leaf, blocksize, (start_block + 3) * blocksize);
121 if (ret != sizeof(empty_leaf)) 127 if (ret != blocksize)
122 return -1; 128 return -1;
123 return 0; 129 return 0;
124} 130}
125
126#if 0
127int mkfs(int fd)
128{
129 struct btrfs_root_info info[2];
130 struct btrfs_leaf empty_leaf;
131 struct btrfs_item item;
132 struct btrfs_extent_item extent_item;
133 int ret;
134
135 /* setup the super block area */
136 memset(info, 0, sizeof(info));
137 btrfs_set_root_blocknr(info, 16);
138 btrfs_set_root_objectid(info, 1);
139 btrfs_set_root_tree_root(info, 17);
140
141 btrfs_set_root_blocknr(info + 1, 16);
142 btrfs_set_root_objectid(info + 1, 2);
143 btrfs_set_root_tree_root(info + 1, 18);
144
145 ret = pwrite(fd, info, sizeof(info),
146 BTRFS_SUPER_INFO_OFFSET(BTRFS_BLOCKSIZE));
147 if (ret != sizeof(info))
148 return -1;
149
150 /* create leaves for the tree root and extent root */
151 memset(&empty_leaf, 0, sizeof(empty_leaf));
152 btrfs_set_header_parentid(&empty_leaf.header, 1);
153 btrfs_set_header_blocknr(&empty_leaf.header, 17);
154 ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 17 * BTRFS_BLOCKSIZE);
155 if (ret != sizeof(empty_leaf))
156 return -1;
157
158 btrfs_set_header_parentid(&empty_leaf.header, 2);
159 btrfs_set_header_blocknr(&empty_leaf.header, 18);
160 btrfs_set_header_nritems(&empty_leaf.header, 3);
161
162 /* item1, reserve blocks 0-16 */
163 btrfs_set_key_objectid(&item.key, 0);
164 btrfs_set_key_offset(&item.key, 17);
165 btrfs_set_key_flags(&item.key, 0);
166 btrfs_set_item_offset(&item, LEAF_DATA_SIZE -
167 sizeof(struct btrfs_extent_item));
168 btrfs_set_item_size(&item, sizeof(struct btrfs_extent_item));
169 btrfs_set_extent_refs(&extent_item, 1);
170 btrfs_set_extent_owner(&extent_item, 0);
171 memcpy(empty_leaf.items, &item, sizeof(item));
172 memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
173 btrfs_item_size(&item));
174
175 /* item2, give block 17 to the root */
176 btrfs_set_key_objectid(&item.key, 17);
177 btrfs_set_key_offset(&item.key, 1);
178 btrfs_set_item_offset(&item, LEAF_DATA_SIZE -
179 sizeof(struct btrfs_extent_item) * 2);
180 btrfs_set_extent_owner(&extent_item, 1);
181 memcpy(empty_leaf.items + 1, &item, sizeof(item));
182 memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
183 btrfs_item_size(&item));
184
185 /* item3, give block 18 for the extent root */
186 btrfs_set_key_objectid(&item.key, 18);
187 btrfs_set_key_offset(&item.key, 1);
188 btrfs_set_item_offset(&item, LEAF_DATA_SIZE -
189 sizeof(struct btrfs_extent_item) * 3);
190 btrfs_set_extent_owner(&extent_item, 2);
191 memcpy(empty_leaf.items + 2, &item, sizeof(item));
192 memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
193 btrfs_item_size(&item));
194 ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 18 * BTRFS_BLOCKSIZE);
195 if (ret != sizeof(empty_leaf))
196 return -1;
197 return 0;
198}
199#endif
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index e769f36cf051..7a189eaa589f 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -5,7 +5,7 @@
5#include "ctree.h" 5#include "ctree.h"
6#include "disk-io.h" 6#include "disk-io.h"
7 7
8void btrfs_print_leaf(struct btrfs_leaf *l) 8void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
9{ 9{
10 int i; 10 int i;
11 u32 nr = btrfs_header_nritems(&l->header); 11 u32 nr = btrfs_header_nritems(&l->header);
@@ -13,7 +13,8 @@ void btrfs_print_leaf(struct btrfs_leaf *l)
13 struct btrfs_extent_item *ei; 13 struct btrfs_extent_item *ei;
14 struct btrfs_root_item *ri; 14 struct btrfs_root_item *ri;
15 printf("leaf %Lu total ptrs %d free space %d\n", 15 printf("leaf %Lu total ptrs %d free space %d\n",
16 btrfs_header_blocknr(&l->header), nr, btrfs_leaf_free_space(l)); 16 btrfs_header_blocknr(&l->header), nr,
17 btrfs_leaf_free_space(root, l));
17 fflush(stdout); 18 fflush(stdout);
18 for (i = 0 ; i < nr ; i++) { 19 for (i = 0 ; i < nr ; i++) {
19 item = l->items + i; 20 item = l->items + i;
@@ -25,7 +26,7 @@ void btrfs_print_leaf(struct btrfs_leaf *l)
25 btrfs_item_offset(item), 26 btrfs_item_offset(item),
26 btrfs_item_size(item)); 27 btrfs_item_size(item));
27 printf("\t\titem data %.*s\n", btrfs_item_size(item), 28 printf("\t\titem data %.*s\n", btrfs_item_size(item),
28 l->data + btrfs_item_offset(item)); 29 btrfs_leaf_data(l) + btrfs_item_offset(item));
29 ei = btrfs_item_ptr(l, i, struct btrfs_extent_item); 30 ei = btrfs_item_ptr(l, i, struct btrfs_extent_item);
30 printf("\t\textent data refs %u owner %Lu\n", 31 printf("\t\textent data refs %u owner %Lu\n",
31 btrfs_extent_refs(ei), btrfs_extent_owner(ei)); 32 btrfs_extent_refs(ei), btrfs_extent_owner(ei));
@@ -46,18 +47,18 @@ void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t)
46 c = &t->node; 47 c = &t->node;
47 nr = btrfs_header_nritems(&c->header); 48 nr = btrfs_header_nritems(&c->header);
48 if (btrfs_is_leaf(c)) { 49 if (btrfs_is_leaf(c)) {
49 btrfs_print_leaf((struct btrfs_leaf *)c); 50 btrfs_print_leaf(root, (struct btrfs_leaf *)c);
50 return; 51 return;
51 } 52 }
52 printf("node %Lu level %d total ptrs %d free spc %u\n", t->blocknr, 53 printf("node %Lu level %d total ptrs %d free spc %u\n", t->blocknr,
53 btrfs_header_level(&c->header), nr, 54 btrfs_header_level(&c->header), nr,
54 (u32)NODEPTRS_PER_BLOCK - nr); 55 (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr);
55 fflush(stdout); 56 fflush(stdout);
56 for (i = 0; i < nr; i++) { 57 for (i = 0; i < nr; i++) {
57 printf("\tkey %d (%Lu %u %Lu) block %Lu\n", 58 printf("\tkey %d (%Lu %u %Lu) block %Lu\n",
58 i, 59 i,
59 c->keys[i].objectid, c->keys[i].flags, c->keys[i].offset, 60 c->ptrs[i].key.objectid, c->ptrs[i].key.flags,
60 btrfs_node_blockptr(c, i)); 61 c->ptrs[i].key.offset, btrfs_node_blockptr(c, i));
61 fflush(stdout); 62 fflush(stdout);
62 } 63 }
63 for (i = 0; i < nr; i++) { 64 for (i = 0; i < nr; i++) {
diff --git a/fs/btrfs/print-tree.h b/fs/btrfs/print-tree.h
index e8d0b847c023..9236abda2a74 100644
--- a/fs/btrfs/print-tree.h
+++ b/fs/btrfs/print-tree.h
@@ -1,3 +1,3 @@
1 1
2void btrfs_print_leaf(struct btrfs_leaf *l); 2void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l);
3void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t); 3void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t);
diff --git a/fs/btrfs/quick-test.c b/fs/btrfs/quick-test.c
index 66bdc57905d7..d9287cad35c9 100644
--- a/fs/btrfs/quick-test.c
+++ b/fs/btrfs/quick-test.c
@@ -73,7 +73,7 @@ int main(int ac, char **av) {
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 btrfs_header_level(&root->node->node.header), 74 btrfs_header_level(&root->node->node.header),
75 btrfs_header_nritems(&root->node->node.header), 75 btrfs_header_nritems(&root->node->node.header),
76 NODEPTRS_PER_BLOCK - 76 BTRFS_NODEPTRS_PER_BLOCK(root) -
77 btrfs_header_nritems(&root->node->node.header)); 77 btrfs_header_nritems(&root->node->node.header));
78 printf("all searches good, deleting some items\n"); 78 printf("all searches good, deleting some items\n");
79 i = 0; 79 i = 0;
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 0ab90cfea98f..03aa7c2c6336 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -31,7 +31,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
31 ret = 1; 31 ret = 1;
32 goto out; 32 goto out;
33 } 33 }
34 memcpy(item, l->data + btrfs_item_offset(l->items + slot), 34 memcpy(item, btrfs_item_ptr(l, slot, struct btrfs_root_item),
35 sizeof(*item)); 35 sizeof(*item));
36 btrfs_disk_key_to_cpu(key, &l->items[slot].key); 36 btrfs_disk_key_to_cpu(key, &l->items[slot].key);
37 btrfs_release_path(root, &path); 37 btrfs_release_path(root, &path);
@@ -55,7 +55,7 @@ int btrfs_update_root(struct btrfs_root *root, struct btrfs_key *key,
55 BUG_ON(ret != 0); 55 BUG_ON(ret != 0);
56 l = &path.nodes[0]->leaf; 56 l = &path.nodes[0]->leaf;
57 slot = path.slots[0]; 57 slot = path.slots[0];
58 memcpy(l->data + btrfs_item_offset(l->items + slot), item, 58 memcpy(btrfs_item_ptr(l, slot, struct btrfs_root_item), item,
59 sizeof(*item)); 59 sizeof(*item));
60out: 60out:
61 btrfs_release_path(root, &path); 61 btrfs_release_path(root, &path);