aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-22 12:13:20 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-22 12:13:20 -0400
commite20d96d64f9cf9288ffecc9ad4714e91c3b97ca8 (patch)
treefbe07d48bc7997226075169118ffa2a2e63f5d51
parent2e635a278354a1a7951e16cfea4c247d6d0e7c99 (diff)
Mountable btrfs, with readdir
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/Makefile5
-rw-r--r--fs/btrfs/ctree.c273
-rw-r--r--fs/btrfs/ctree.h62
-rw-r--r--fs/btrfs/dir-item.c17
-rw-r--r--fs/btrfs/disk-io.c281
-rw-r--r--fs/btrfs/disk-io.h51
-rw-r--r--fs/btrfs/extent-tree.c144
-rw-r--r--fs/btrfs/hash.c9
-rw-r--r--fs/btrfs/inode-map.c8
-rw-r--r--fs/btrfs/print-tree.c20
-rw-r--r--fs/btrfs/print-tree.h2
-rw-r--r--fs/btrfs/root-tree.c4
-rw-r--r--fs/btrfs/super.c261
-rw-r--r--fs/btrfs/transaction.h4
14 files changed, 651 insertions, 490 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile
index 99e45a54ebd6..1a0fb7422393 100644
--- a/fs/btrfs/Makefile
+++ b/fs/btrfs/Makefile
@@ -2,7 +2,8 @@ ifneq ($(KERNELRELEASE),)
2# kbuild part of makefile 2# kbuild part of makefile
3 3
4obj-m := btrfs.o 4obj-m := btrfs.o
5btrfs-y := super.o 5btrfs-y := super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \
6 hash.o file-item.o inode-item.o inode-map.o disk-io.o
6 7
7#btrfs-y := ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \ 8#btrfs-y := ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
8# root-tree.o dir-item.o hash.o file-item.o inode-item.o \ 9# root-tree.o dir-item.o hash.o file-item.o inode-item.o \
@@ -14,7 +15,7 @@ else
14 15
15KERNELDIR := /lib/modules/`uname -r`/build 16KERNELDIR := /lib/modules/`uname -r`/build
16all:: 17all::
17 $(MAKE) -C $(KERNELDIR) M=`pwd` modules 18 $(MAKE) C=1 -C $(KERNELDIR) M=`pwd` modules
18clean:: 19clean::
19 rm *.o btrfs.ko 20 rm *.o btrfs.ko
20endif 21endif
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 9fbd07c37fde..e690e2bb47d2 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -7,11 +7,11 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
7static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 7static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
8 *root, struct btrfs_path *path, int data_size); 8 *root, struct btrfs_path *path, int data_size);
9static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 9static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
10 *root, struct btrfs_buffer *dst, struct btrfs_buffer 10 *root, struct buffer_head *dst, struct buffer_head
11 *src); 11 *src);
12static int balance_node_right(struct btrfs_trans_handle *trans, struct 12static int balance_node_right(struct btrfs_trans_handle *trans, struct
13 btrfs_root *root, struct btrfs_buffer *dst_buf, 13 btrfs_root *root, struct buffer_head *dst_buf,
14 struct btrfs_buffer *src_buf); 14 struct buffer_head *src_buf);
15static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 15static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
16 struct btrfs_path *path, int level, int slot); 16 struct btrfs_path *path, int level, int slot);
17 17
@@ -32,32 +32,34 @@ void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
32} 32}
33 33
34static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root 34static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
35 *root, struct btrfs_buffer *buf, struct btrfs_buffer 35 *root, struct buffer_head *buf, struct buffer_head
36 *parent, int parent_slot, struct btrfs_buffer 36 *parent, int parent_slot, struct buffer_head
37 **cow_ret) 37 **cow_ret)
38{ 38{
39 struct btrfs_buffer *cow; 39 struct buffer_head *cow;
40 struct btrfs_node *cow_node;
40 41
41 if (!list_empty(&buf->dirty)) { 42 if (!buffer_dirty(buf)) {
42 *cow_ret = buf; 43 *cow_ret = buf;
43 return 0; 44 return 0;
44 } 45 }
45 cow = btrfs_alloc_free_block(trans, root); 46 cow = btrfs_alloc_free_block(trans, root);
46 memcpy(&cow->node, &buf->node, root->blocksize); 47 cow_node = btrfs_buffer_node(cow);
47 btrfs_set_header_blocknr(&cow->node.header, cow->blocknr); 48 memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
49 btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr);
48 *cow_ret = cow; 50 *cow_ret = cow;
49 btrfs_inc_ref(trans, root, buf); 51 btrfs_inc_ref(trans, root, buf);
50 if (buf == root->node) { 52 if (buf == root->node) {
51 root->node = cow; 53 root->node = cow;
52 cow->count++; 54 get_bh(cow);
53 if (buf != root->commit_root) 55 if (buf != root->commit_root)
54 btrfs_free_extent(trans, root, buf->blocknr, 1, 1); 56 btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1);
55 btrfs_block_release(root, buf); 57 btrfs_block_release(root, buf);
56 } else { 58 } else {
57 btrfs_set_node_blockptr(&parent->node, parent_slot, 59 btrfs_set_node_blockptr(btrfs_buffer_node(parent), parent_slot,
58 cow->blocknr); 60 cow->b_blocknr);
59 BUG_ON(list_empty(&parent->dirty)); 61 BUG_ON(!buffer_dirty(parent));
60 btrfs_free_extent(trans, root, buf->blocknr, 1, 1); 62 btrfs_free_extent(trans, root, buf->b_blocknr, 1, 1);
61 } 63 }
62 btrfs_block_release(root, buf); 64 btrfs_block_release(root, buf);
63 return 0; 65 return 0;
@@ -119,12 +121,12 @@ static int check_node(struct btrfs_root *root, struct btrfs_path *path,
119{ 121{
120 int i; 122 int i;
121 struct btrfs_node *parent = NULL; 123 struct btrfs_node *parent = NULL;
122 struct btrfs_node *node = &path->nodes[level]->node; 124 struct btrfs_node *node = btrfs_buffer_node(path->nodes[level]);
123 int parent_slot; 125 int parent_slot;
124 u32 nritems = btrfs_header_nritems(&node->header); 126 u32 nritems = btrfs_header_nritems(&node->header);
125 127
126 if (path->nodes[level + 1]) 128 if (path->nodes[level + 1])
127 parent = &path->nodes[level + 1]->node; 129 parent = btrfs_buffer_node(path->nodes[level + 1]);
128 parent_slot = path->slots[level + 1]; 130 parent_slot = path->slots[level + 1];
129 BUG_ON(nritems == 0); 131 BUG_ON(nritems == 0);
130 if (parent) { 132 if (parent) {
@@ -148,13 +150,13 @@ static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
148 int level) 150 int level)
149{ 151{
150 int i; 152 int i;
151 struct btrfs_leaf *leaf = &path->nodes[level]->leaf; 153 struct btrfs_leaf *leaf = btrfs_buffer_leaf(path->nodes[level]);
152 struct btrfs_node *parent = NULL; 154 struct btrfs_node *parent = NULL;
153 int parent_slot; 155 int parent_slot;
154 u32 nritems = btrfs_header_nritems(&leaf->header); 156 u32 nritems = btrfs_header_nritems(&leaf->header);
155 157
156 if (path->nodes[level + 1]) 158 if (path->nodes[level + 1])
157 parent = &path->nodes[level + 1]->node; 159 parent = btrfs_buffer_node(path->nodes[level + 1]);
158 parent_slot = path->slots[level + 1]; 160 parent_slot = path->slots[level + 1];
159 BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); 161 BUG_ON(btrfs_leaf_free_space(root, leaf) < 0);
160 162
@@ -250,11 +252,11 @@ static int bin_search(struct btrfs_node *c, struct btrfs_key *key, int *slot)
250 return -1; 252 return -1;
251} 253}
252 254
253static struct btrfs_buffer *read_node_slot(struct btrfs_root *root, 255static struct buffer_head *read_node_slot(struct btrfs_root *root,
254 struct btrfs_buffer *parent_buf, 256 struct buffer_head *parent_buf,
255 int slot) 257 int slot)
256{ 258{
257 struct btrfs_node *node = &parent_buf->node; 259 struct btrfs_node *node = btrfs_buffer_node(parent_buf);
258 if (slot < 0) 260 if (slot < 0)
259 return NULL; 261 return NULL;
260 if (slot >= btrfs_header_nritems(&node->header)) 262 if (slot >= btrfs_header_nritems(&node->header))
@@ -265,10 +267,10 @@ static struct btrfs_buffer *read_node_slot(struct btrfs_root *root,
265static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root 267static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
266 *root, struct btrfs_path *path, int level) 268 *root, struct btrfs_path *path, int level)
267{ 269{
268 struct btrfs_buffer *right_buf; 270 struct buffer_head *right_buf;
269 struct btrfs_buffer *mid_buf; 271 struct buffer_head *mid_buf;
270 struct btrfs_buffer *left_buf; 272 struct buffer_head *left_buf;
271 struct btrfs_buffer *parent_buf = NULL; 273 struct buffer_head *parent_buf = NULL;
272 struct btrfs_node *right = NULL; 274 struct btrfs_node *right = NULL;
273 struct btrfs_node *mid; 275 struct btrfs_node *mid;
274 struct btrfs_node *left = NULL; 276 struct btrfs_node *left = NULL;
@@ -283,7 +285,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
283 return 0; 285 return 0;
284 286
285 mid_buf = path->nodes[level]; 287 mid_buf = path->nodes[level];
286 mid = &mid_buf->node; 288 mid = btrfs_buffer_node(mid_buf);
287 orig_ptr = btrfs_node_blockptr(mid, orig_slot); 289 orig_ptr = btrfs_node_blockptr(mid, orig_slot);
288 290
289 if (level < BTRFS_MAX_LEVEL - 1) 291 if (level < BTRFS_MAX_LEVEL - 1)
@@ -295,8 +297,8 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
295 * by promoting the node below to a root 297 * by promoting the node below to a root
296 */ 298 */
297 if (!parent_buf) { 299 if (!parent_buf) {
298 struct btrfs_buffer *child; 300 struct buffer_head *child;
299 u64 blocknr = mid_buf->blocknr; 301 u64 blocknr = mid_buf->b_blocknr;
300 302
301 if (btrfs_header_nritems(&mid->header) != 1) 303 if (btrfs_header_nritems(&mid->header) != 1)
302 return 0; 304 return 0;
@@ -313,7 +315,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
313 clean_tree_block(trans, root, mid_buf); 315 clean_tree_block(trans, root, mid_buf);
314 return btrfs_free_extent(trans, root, blocknr, 1, 1); 316 return btrfs_free_extent(trans, root, blocknr, 1, 1);
315 } 317 }
316 parent = &parent_buf->node; 318 parent = btrfs_buffer_node(parent_buf);
317 319
318 if (btrfs_header_nritems(&mid->header) > 320 if (btrfs_header_nritems(&mid->header) >
319 BTRFS_NODEPTRS_PER_BLOCK(root) / 4) 321 BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
@@ -326,7 +328,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
326 if (left_buf) { 328 if (left_buf) {
327 btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1, 329 btrfs_cow_block(trans, root, left_buf, parent_buf, pslot - 1,
328 &left_buf); 330 &left_buf);
329 left = &left_buf->node; 331 left = btrfs_buffer_node(left_buf);
330 orig_slot += btrfs_header_nritems(&left->header); 332 orig_slot += btrfs_header_nritems(&left->header);
331 wret = push_node_left(trans, root, left_buf, mid_buf); 333 wret = push_node_left(trans, root, left_buf, mid_buf);
332 if (wret < 0) 334 if (wret < 0)
@@ -339,12 +341,12 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
339 if (right_buf) { 341 if (right_buf) {
340 btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1, 342 btrfs_cow_block(trans, root, right_buf, parent_buf, pslot + 1,
341 &right_buf); 343 &right_buf);
342 right = &right_buf->node; 344 right = btrfs_buffer_node(right_buf);
343 wret = push_node_left(trans, root, mid_buf, right_buf); 345 wret = push_node_left(trans, root, mid_buf, right_buf);
344 if (wret < 0) 346 if (wret < 0)
345 ret = wret; 347 ret = wret;
346 if (btrfs_header_nritems(&right->header) == 0) { 348 if (btrfs_header_nritems(&right->header) == 0) {
347 u64 blocknr = right_buf->blocknr; 349 u64 blocknr = right_buf->b_blocknr;
348 btrfs_block_release(root, right_buf); 350 btrfs_block_release(root, right_buf);
349 clean_tree_block(trans, root, right_buf); 351 clean_tree_block(trans, root, right_buf);
350 right_buf = NULL; 352 right_buf = NULL;
@@ -360,7 +362,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
360 memcpy(&parent->ptrs[pslot + 1].key, 362 memcpy(&parent->ptrs[pslot + 1].key,
361 &right->ptrs[0].key, 363 &right->ptrs[0].key,
362 sizeof(struct btrfs_disk_key)); 364 sizeof(struct btrfs_disk_key));
363 BUG_ON(list_empty(&parent_buf->dirty)); 365 BUG_ON(!buffer_dirty(parent_buf));
364 } 366 }
365 } 367 }
366 if (btrfs_header_nritems(&mid->header) == 1) { 368 if (btrfs_header_nritems(&mid->header) == 1) {
@@ -381,7 +383,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
381 } 383 }
382 if (btrfs_header_nritems(&mid->header) == 0) { 384 if (btrfs_header_nritems(&mid->header) == 0) {
383 /* we've managed to empty the middle node, drop it */ 385 /* we've managed to empty the middle node, drop it */
384 u64 blocknr = mid_buf->blocknr; 386 u64 blocknr = mid_buf->b_blocknr;
385 btrfs_block_release(root, mid_buf); 387 btrfs_block_release(root, mid_buf);
386 clean_tree_block(trans, root, mid_buf); 388 clean_tree_block(trans, root, mid_buf);
387 mid_buf = NULL; 389 mid_buf = NULL;
@@ -396,13 +398,13 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
396 /* update the parent key to reflect our changes */ 398 /* update the parent key to reflect our changes */
397 memcpy(&parent->ptrs[pslot].key, &mid->ptrs[0].key, 399 memcpy(&parent->ptrs[pslot].key, &mid->ptrs[0].key,
398 sizeof(struct btrfs_disk_key)); 400 sizeof(struct btrfs_disk_key));
399 BUG_ON(list_empty(&parent_buf->dirty)); 401 BUG_ON(!buffer_dirty(parent_buf));
400 } 402 }
401 403
402 /* update the path */ 404 /* update the path */
403 if (left_buf) { 405 if (left_buf) {
404 if (btrfs_header_nritems(&left->header) > orig_slot) { 406 if (btrfs_header_nritems(&left->header) > orig_slot) {
405 left_buf->count++; // released below 407 get_bh(left_buf);
406 path->nodes[level] = left_buf; 408 path->nodes[level] = left_buf;
407 path->slots[level + 1] -= 1; 409 path->slots[level + 1] -= 1;
408 path->slots[level] = orig_slot; 410 path->slots[level] = orig_slot;
@@ -415,8 +417,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
415 } 417 }
416 /* double check we haven't messed things up */ 418 /* double check we haven't messed things up */
417 check_block(root, path, level); 419 check_block(root, path, level);
418 if (orig_ptr != btrfs_node_blockptr(&path->nodes[level]->node, 420 if (orig_ptr !=
419 path->slots[level])) 421 btrfs_node_blockptr(btrfs_buffer_node(path->nodes[level]),
422 path->slots[level]))
420 BUG(); 423 BUG();
421 424
422 if (right_buf) 425 if (right_buf)
@@ -443,8 +446,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
443 *root, struct btrfs_key *key, struct btrfs_path *p, int 446 *root, struct btrfs_key *key, struct btrfs_path *p, int
444 ins_len, int cow) 447 ins_len, int cow)
445{ 448{
446 struct btrfs_buffer *b; 449 struct buffer_head *b;
447 struct btrfs_buffer *cow_buf; 450 struct buffer_head *cow_buf;
448 struct btrfs_node *c; 451 struct btrfs_node *c;
449 int slot; 452 int slot;
450 int ret; 453 int ret;
@@ -452,18 +455,20 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
452 455
453again: 456again:
454 b = root->node; 457 b = root->node;
455 b->count++; 458 get_bh(b);
456 while (b) { 459 while (b) {
457 level = btrfs_header_level(&b->node.header); 460 c = btrfs_buffer_node(b);
461 level = btrfs_header_level(&c->header);
458 if (cow) { 462 if (cow) {
459 int wret; 463 int wret;
460 wret = btrfs_cow_block(trans, root, b, p->nodes[level + 464 wret = btrfs_cow_block(trans, root, b,
461 1], p->slots[level + 1], 465 p->nodes[level + 1],
466 p->slots[level + 1],
462 &cow_buf); 467 &cow_buf);
463 b = cow_buf; 468 b = cow_buf;
464 } 469 }
465 BUG_ON(!cow && ins_len); 470 BUG_ON(!cow && ins_len);
466 c = &b->node; 471 c = btrfs_buffer_node(b);
467 p->nodes[level] = b; 472 p->nodes[level] = b;
468 ret = check_block(root, p, level); 473 ret = check_block(root, p, level);
469 if (ret) 474 if (ret)
@@ -480,7 +485,7 @@ again:
480 if (sret) 485 if (sret)
481 return sret; 486 return sret;
482 b = p->nodes[level]; 487 b = p->nodes[level];
483 c = &b->node; 488 c = btrfs_buffer_node(b);
484 slot = p->slots[level]; 489 slot = p->slots[level];
485 } else if (ins_len < 0) { 490 } else if (ins_len < 0) {
486 int sret = balance_level(trans, root, p, 491 int sret = balance_level(trans, root, p,
@@ -490,7 +495,7 @@ again:
490 b = p->nodes[level]; 495 b = p->nodes[level];
491 if (!b) 496 if (!b)
492 goto again; 497 goto again;
493 c = &b->node; 498 c = btrfs_buffer_node(b);
494 slot = p->slots[level]; 499 slot = p->slots[level];
495 BUG_ON(btrfs_header_nritems(&c->header) == 1); 500 BUG_ON(btrfs_header_nritems(&c->header) == 1);
496 } 501 }
@@ -505,11 +510,9 @@ again:
505 if (sret) 510 if (sret)
506 return sret; 511 return sret;
507 } 512 }
508 BUG_ON(root->node->count == 1);
509 return ret; 513 return ret;
510 } 514 }
511 } 515 }
512 BUG_ON(root->node->count == 1);
513 return 1; 516 return 1;
514} 517}
515 518
@@ -534,9 +537,9 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root
534 int tslot = path->slots[i]; 537 int tslot = path->slots[i];
535 if (!path->nodes[i]) 538 if (!path->nodes[i])
536 break; 539 break;
537 t = &path->nodes[i]->node; 540 t = btrfs_buffer_node(path->nodes[i]);
538 memcpy(&t->ptrs[tslot].key, key, sizeof(*key)); 541 memcpy(&t->ptrs[tslot].key, key, sizeof(*key));
539 BUG_ON(list_empty(&path->nodes[i]->dirty)); 542 BUG_ON(!buffer_dirty(path->nodes[i]));
540 if (tslot != 0) 543 if (tslot != 0)
541 break; 544 break;
542 } 545 }
@@ -551,11 +554,11 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans, struct btrfs_root
551 * error, and > 0 if there was no room in the left hand block. 554 * error, and > 0 if there was no room in the left hand block.
552 */ 555 */
553static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root 556static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
554 *root, struct btrfs_buffer *dst_buf, struct 557 *root, struct buffer_head *dst_buf, struct
555 btrfs_buffer *src_buf) 558 buffer_head *src_buf)
556{ 559{
557 struct btrfs_node *src = &src_buf->node; 560 struct btrfs_node *src = btrfs_buffer_node(src_buf);
558 struct btrfs_node *dst = &dst_buf->node; 561 struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
559 int push_items = 0; 562 int push_items = 0;
560 int src_nritems; 563 int src_nritems;
561 int dst_nritems; 564 int dst_nritems;
@@ -580,8 +583,8 @@ static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
580 } 583 }
581 btrfs_set_header_nritems(&src->header, src_nritems - push_items); 584 btrfs_set_header_nritems(&src->header, src_nritems - push_items);
582 btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 585 btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
583 BUG_ON(list_empty(&src_buf->dirty)); 586 BUG_ON(!buffer_dirty(src_buf));
584 BUG_ON(list_empty(&dst_buf->dirty)); 587 BUG_ON(!buffer_dirty(dst_buf));
585 return ret; 588 return ret;
586} 589}
587 590
@@ -595,11 +598,11 @@ static int push_node_left(struct btrfs_trans_handle *trans, struct btrfs_root
595 * this will only push up to 1/2 the contents of the left node over 598 * this will only push up to 1/2 the contents of the left node over
596 */ 599 */
597static int balance_node_right(struct btrfs_trans_handle *trans, struct 600static int balance_node_right(struct btrfs_trans_handle *trans, struct
598 btrfs_root *root, struct btrfs_buffer *dst_buf, 601 btrfs_root *root, struct buffer_head *dst_buf,
599 struct btrfs_buffer *src_buf) 602 struct buffer_head *src_buf)
600{ 603{
601 struct btrfs_node *src = &src_buf->node; 604 struct btrfs_node *src = btrfs_buffer_node(src_buf);
602 struct btrfs_node *dst = &dst_buf->node; 605 struct btrfs_node *dst = btrfs_buffer_node(dst_buf);
603 int push_items = 0; 606 int push_items = 0;
604 int max_push; 607 int max_push;
605 int src_nritems; 608 int src_nritems;
@@ -628,8 +631,8 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct
628 btrfs_set_header_nritems(&src->header, src_nritems - push_items); 631 btrfs_set_header_nritems(&src->header, src_nritems - push_items);
629 btrfs_set_header_nritems(&dst->header, dst_nritems + push_items); 632 btrfs_set_header_nritems(&dst->header, dst_nritems + push_items);
630 633
631 BUG_ON(list_empty(&src_buf->dirty)); 634 BUG_ON(!buffer_dirty(src_buf));
632 BUG_ON(list_empty(&dst_buf->dirty)); 635 BUG_ON(!buffer_dirty(dst_buf));
633 return ret; 636 return ret;
634} 637}
635 638
@@ -643,7 +646,7 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct
643static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root 646static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
644 *root, struct btrfs_path *path, int level) 647 *root, struct btrfs_path *path, int level)
645{ 648{
646 struct btrfs_buffer *t; 649 struct buffer_head *t;
647 struct btrfs_node *lower; 650 struct btrfs_node *lower;
648 struct btrfs_node *c; 651 struct btrfs_node *c;
649 struct btrfs_disk_key *lower_key; 652 struct btrfs_disk_key *lower_key;
@@ -652,24 +655,24 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
652 BUG_ON(path->nodes[level-1] != root->node); 655 BUG_ON(path->nodes[level-1] != root->node);
653 656
654 t = btrfs_alloc_free_block(trans, root); 657 t = btrfs_alloc_free_block(trans, root);
655 c = &t->node; 658 c = btrfs_buffer_node(t);
656 memset(c, 0, root->blocksize); 659 memset(c, 0, root->blocksize);
657 btrfs_set_header_nritems(&c->header, 1); 660 btrfs_set_header_nritems(&c->header, 1);
658 btrfs_set_header_level(&c->header, level); 661 btrfs_set_header_level(&c->header, level);
659 btrfs_set_header_blocknr(&c->header, t->blocknr); 662 btrfs_set_header_blocknr(&c->header, t->b_blocknr);
660 btrfs_set_header_parentid(&c->header, 663 btrfs_set_header_parentid(&c->header,
661 btrfs_header_parentid(&root->node->node.header)); 664 btrfs_header_parentid(btrfs_buffer_header(root->node)));
662 lower = &path->nodes[level-1]->node; 665 lower = btrfs_buffer_node(path->nodes[level-1]);
663 if (btrfs_is_leaf(lower)) 666 if (btrfs_is_leaf(lower))
664 lower_key = &((struct btrfs_leaf *)lower)->items[0].key; 667 lower_key = &((struct btrfs_leaf *)lower)->items[0].key;
665 else 668 else
666 lower_key = &lower->ptrs[0].key; 669 lower_key = &lower->ptrs[0].key;
667 memcpy(&c->ptrs[0].key, lower_key, sizeof(struct btrfs_disk_key)); 670 memcpy(&c->ptrs[0].key, lower_key, sizeof(struct btrfs_disk_key));
668 btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->blocknr); 671 btrfs_set_node_blockptr(c, 0, path->nodes[level - 1]->b_blocknr);
669 /* the super has an extra ref to root->node */ 672 /* the super has an extra ref to root->node */
670 btrfs_block_release(root, root->node); 673 btrfs_block_release(root, root->node);
671 root->node = t; 674 root->node = t;
672 t->count++; 675 get_bh(t);
673 path->nodes[level] = t; 676 path->nodes[level] = t;
674 path->slots[level] = 0; 677 path->slots[level] = 0;
675 return 0; 678 return 0;
@@ -692,7 +695,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
692 int nritems; 695 int nritems;
693 696
694 BUG_ON(!path->nodes[level]); 697 BUG_ON(!path->nodes[level]);
695 lower = &path->nodes[level]->node; 698 lower = btrfs_buffer_node(path->nodes[level]);
696 nritems = btrfs_header_nritems(&lower->header); 699 nritems = btrfs_header_nritems(&lower->header);
697 if (slot > nritems) 700 if (slot > nritems)
698 BUG(); 701 BUG();
@@ -705,7 +708,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
705 memcpy(&lower->ptrs[slot].key, key, sizeof(struct btrfs_disk_key)); 708 memcpy(&lower->ptrs[slot].key, key, sizeof(struct btrfs_disk_key));
706 btrfs_set_node_blockptr(lower, slot, blocknr); 709 btrfs_set_node_blockptr(lower, slot, blocknr);
707 btrfs_set_header_nritems(&lower->header, nritems + 1); 710 btrfs_set_header_nritems(&lower->header, nritems + 1);
708 BUG_ON(list_empty(&path->nodes[level]->dirty)); 711 BUG_ON(!buffer_dirty(path->nodes[level]));
709 return 0; 712 return 0;
710} 713}
711 714
@@ -721,9 +724,9 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
721static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 724static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
722 *root, struct btrfs_path *path, int level) 725 *root, struct btrfs_path *path, int level)
723{ 726{
724 struct btrfs_buffer *t; 727 struct buffer_head *t;
725 struct btrfs_node *c; 728 struct btrfs_node *c;
726 struct btrfs_buffer *split_buffer; 729 struct buffer_head *split_buffer;
727 struct btrfs_node *split; 730 struct btrfs_node *split;
728 int mid; 731 int mid;
729 int ret; 732 int ret;
@@ -731,7 +734,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
731 u32 c_nritems; 734 u32 c_nritems;
732 735
733 t = path->nodes[level]; 736 t = path->nodes[level];
734 c = &t->node; 737 c = btrfs_buffer_node(t);
735 if (t == root->node) { 738 if (t == root->node) {
736 /* trying to split the root, lets make a new one */ 739 /* trying to split the root, lets make a new one */
737 ret = insert_new_root(trans, root, path, level + 1); 740 ret = insert_new_root(trans, root, path, level + 1);
@@ -740,11 +743,11 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
740 } 743 }
741 c_nritems = btrfs_header_nritems(&c->header); 744 c_nritems = btrfs_header_nritems(&c->header);
742 split_buffer = btrfs_alloc_free_block(trans, root); 745 split_buffer = btrfs_alloc_free_block(trans, root);
743 split = &split_buffer->node; 746 split = btrfs_buffer_node(split_buffer);
744 btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 747 btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
745 btrfs_set_header_blocknr(&split->header, split_buffer->blocknr); 748 btrfs_set_header_blocknr(&split->header, split_buffer->b_blocknr);
746 btrfs_set_header_parentid(&split->header, 749 btrfs_set_header_parentid(&split->header,
747 btrfs_header_parentid(&root->node->node.header)); 750 btrfs_header_parentid(btrfs_buffer_header(root->node)));
748 mid = (c_nritems + 1) / 2; 751 mid = (c_nritems + 1) / 2;
749 memcpy(split->ptrs, c->ptrs + mid, 752 memcpy(split->ptrs, c->ptrs + mid,
750 (c_nritems - mid) * sizeof(struct btrfs_key_ptr)); 753 (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
@@ -752,9 +755,9 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
752 btrfs_set_header_nritems(&c->header, mid); 755 btrfs_set_header_nritems(&c->header, mid);
753 ret = 0; 756 ret = 0;
754 757
755 BUG_ON(list_empty(&t->dirty)); 758 BUG_ON(!buffer_dirty(t));
756 wret = insert_ptr(trans, root, path, &split->ptrs[0].key, 759 wret = insert_ptr(trans, root, path, &split->ptrs[0].key,
757 split_buffer->blocknr, path->slots[level + 1] + 1, 760 split_buffer->b_blocknr, path->slots[level + 1] + 1,
758 level + 1); 761 level + 1);
759 if (wret) 762 if (wret)
760 ret = wret; 763 ret = wret;
@@ -798,11 +801,12 @@ static int leaf_space_used(struct btrfs_leaf *l, int start, int nr)
798static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root 801static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
799 *root, struct btrfs_path *path, int data_size) 802 *root, struct btrfs_path *path, int data_size)
800{ 803{
801 struct btrfs_buffer *left_buf = path->nodes[0]; 804 struct buffer_head *left_buf = path->nodes[0];
802 struct btrfs_leaf *left = &left_buf->leaf; 805 struct btrfs_leaf *left = btrfs_buffer_leaf(left_buf);
803 struct btrfs_leaf *right; 806 struct btrfs_leaf *right;
804 struct btrfs_buffer *right_buf; 807 struct buffer_head *right_buf;
805 struct btrfs_buffer *upper; 808 struct buffer_head *upper;
809 struct btrfs_node *upper_node;
806 int slot; 810 int slot;
807 int i; 811 int i;
808 int free_space; 812 int free_space;
@@ -817,12 +821,13 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
817 return 1; 821 return 1;
818 } 822 }
819 upper = path->nodes[1]; 823 upper = path->nodes[1];
820 if (slot >= btrfs_header_nritems(&upper->node.header) - 1) { 824 upper_node = btrfs_buffer_node(upper);
825 if (slot >= btrfs_header_nritems(&upper_node->header) - 1) {
821 return 1; 826 return 1;
822 } 827 }
823 right_buf = read_tree_block(root, btrfs_node_blockptr(&upper->node, 828 right_buf = read_tree_block(root,
824 slot + 1)); 829 btrfs_node_blockptr(btrfs_buffer_node(upper), slot + 1));
825 right = &right_buf->leaf; 830 right = btrfs_buffer_leaf(right_buf);
826 free_space = btrfs_leaf_free_space(root, right); 831 free_space = btrfs_leaf_free_space(root, right);
827 if (free_space < data_size + sizeof(struct btrfs_item)) { 832 if (free_space < data_size + sizeof(struct btrfs_item)) {
828 btrfs_block_release(root, right_buf); 833 btrfs_block_release(root, right_buf);
@@ -830,7 +835,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
830 } 835 }
831 /* cow and double check */ 836 /* cow and double check */
832 btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf); 837 btrfs_cow_block(trans, root, right_buf, upper, slot + 1, &right_buf);
833 right = &right_buf->leaf; 838 right = btrfs_buffer_leaf(right_buf);
834 free_space = btrfs_leaf_free_space(root, right); 839 free_space = btrfs_leaf_free_space(root, right);
835 if (free_space < data_size + sizeof(struct btrfs_item)) { 840 if (free_space < data_size + sizeof(struct btrfs_item)) {
836 btrfs_block_release(root, right_buf); 841 btrfs_block_release(root, right_buf);
@@ -881,11 +886,11 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
881 left_nritems -= push_items; 886 left_nritems -= push_items;
882 btrfs_set_header_nritems(&left->header, left_nritems); 887 btrfs_set_header_nritems(&left->header, left_nritems);
883 888
884 BUG_ON(list_empty(&left_buf->dirty)); 889 BUG_ON(!buffer_dirty(left_buf));
885 BUG_ON(list_empty(&right_buf->dirty)); 890 BUG_ON(!buffer_dirty(right_buf));
886 memcpy(&upper->node.ptrs[slot + 1].key, 891 memcpy(&upper_node->ptrs[slot + 1].key,
887 &right->items[0].key, sizeof(struct btrfs_disk_key)); 892 &right->items[0].key, sizeof(struct btrfs_disk_key));
888 BUG_ON(list_empty(&upper->dirty)); 893 BUG_ON(!buffer_dirty(upper));
889 894
890 /* then fixup the leaf pointer in the path */ 895 /* then fixup the leaf pointer in the path */
891 if (path->slots[0] >= left_nritems) { 896 if (path->slots[0] >= left_nritems) {
@@ -905,9 +910,9 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
905static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root 910static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
906 *root, struct btrfs_path *path, int data_size) 911 *root, struct btrfs_path *path, int data_size)
907{ 912{
908 struct btrfs_buffer *right_buf = path->nodes[0]; 913 struct buffer_head *right_buf = path->nodes[0];
909 struct btrfs_leaf *right = &right_buf->leaf; 914 struct btrfs_leaf *right = btrfs_buffer_leaf(right_buf);
910 struct btrfs_buffer *t; 915 struct buffer_head *t;
911 struct btrfs_leaf *left; 916 struct btrfs_leaf *left;
912 int slot; 917 int slot;
913 int i; 918 int i;
@@ -926,9 +931,9 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
926 if (!path->nodes[1]) { 931 if (!path->nodes[1]) {
927 return 1; 932 return 1;
928 } 933 }
929 t = read_tree_block(root, btrfs_node_blockptr(&path->nodes[1]->node, 934 t = read_tree_block(root,
930 slot - 1)); 935 btrfs_node_blockptr(btrfs_buffer_node(path->nodes[1]), slot - 1));
931 left = &t->leaf; 936 left = btrfs_buffer_leaf(t);
932 free_space = btrfs_leaf_free_space(root, left); 937 free_space = btrfs_leaf_free_space(root, left);
933 if (free_space < data_size + sizeof(struct btrfs_item)) { 938 if (free_space < data_size + sizeof(struct btrfs_item)) {
934 btrfs_block_release(root, t); 939 btrfs_block_release(root, t);
@@ -937,7 +942,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
937 942
938 /* cow and double check */ 943 /* cow and double check */
939 btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t); 944 btrfs_cow_block(trans, root, t, path->nodes[1], slot - 1, &t);
940 left = &t->leaf; 945 left = btrfs_buffer_leaf(t);
941 free_space = btrfs_leaf_free_space(root, left); 946 free_space = btrfs_leaf_free_space(root, left);
942 if (free_space < data_size + sizeof(struct btrfs_item)) { 947 if (free_space < data_size + sizeof(struct btrfs_item)) {
943 btrfs_block_release(root, t); 948 btrfs_block_release(root, t);
@@ -999,8 +1004,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
999 push_space = btrfs_item_offset(right->items + i); 1004 push_space = btrfs_item_offset(right->items + i);
1000 } 1005 }
1001 1006
1002 BUG_ON(list_empty(&t->dirty)); 1007 BUG_ON(!buffer_dirty(t));
1003 BUG_ON(list_empty(&right_buf->dirty)); 1008 BUG_ON(!buffer_dirty(right_buf));
1004 1009
1005 wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1); 1010 wret = fixup_low_keys(trans, root, path, &right->items[0].key, 1);
1006 if (wret) 1011 if (wret)
@@ -1029,13 +1034,13 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
1029static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root 1034static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1030 *root, struct btrfs_path *path, int data_size) 1035 *root, struct btrfs_path *path, int data_size)
1031{ 1036{
1032 struct btrfs_buffer *l_buf; 1037 struct buffer_head *l_buf;
1033 struct btrfs_leaf *l; 1038 struct btrfs_leaf *l;
1034 u32 nritems; 1039 u32 nritems;
1035 int mid; 1040 int mid;
1036 int slot; 1041 int slot;
1037 struct btrfs_leaf *right; 1042 struct btrfs_leaf *right;
1038 struct btrfs_buffer *right_buffer; 1043 struct buffer_head *right_buffer;
1039 int space_needed = data_size + sizeof(struct btrfs_item); 1044 int space_needed = data_size + sizeof(struct btrfs_item);
1040 int data_copy_size; 1045 int data_copy_size;
1041 int rt_data_off; 1046 int rt_data_off;
@@ -1053,7 +1058,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1053 return wret; 1058 return wret;
1054 } 1059 }
1055 l_buf = path->nodes[0]; 1060 l_buf = path->nodes[0];
1056 l = &l_buf->leaf; 1061 l = btrfs_buffer_leaf(l_buf);
1057 1062
1058 /* did the pushes work? */ 1063 /* did the pushes work? */
1059 if (btrfs_leaf_free_space(root, l) >= 1064 if (btrfs_leaf_free_space(root, l) >=
@@ -1071,7 +1076,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1071 right_buffer = btrfs_alloc_free_block(trans, root); 1076 right_buffer = btrfs_alloc_free_block(trans, root);
1072 BUG_ON(!right_buffer); 1077 BUG_ON(!right_buffer);
1073 BUG_ON(mid == nritems); 1078 BUG_ON(mid == nritems);
1074 right = &right_buffer->leaf; 1079 right = btrfs_buffer_leaf(right_buffer);
1075 memset(&right->header, 0, sizeof(right->header)); 1080 memset(&right->header, 0, sizeof(right->header));
1076 if (mid <= slot) { 1081 if (mid <= slot) {
1077 /* FIXME, just alloc a new leaf here */ 1082 /* FIXME, just alloc a new leaf here */
@@ -1085,10 +1090,10 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1085 BUG(); 1090 BUG();
1086 } 1091 }
1087 btrfs_set_header_nritems(&right->header, nritems - mid); 1092 btrfs_set_header_nritems(&right->header, nritems - mid);
1088 btrfs_set_header_blocknr(&right->header, right_buffer->blocknr); 1093 btrfs_set_header_blocknr(&right->header, right_buffer->b_blocknr);
1089 btrfs_set_header_level(&right->header, 0); 1094 btrfs_set_header_level(&right->header, 0);
1090 btrfs_set_header_parentid(&right->header, 1095 btrfs_set_header_parentid(&right->header,
1091 btrfs_header_parentid(&root->node->node.header)); 1096 btrfs_header_parentid(btrfs_buffer_header(root->node)));
1092 data_copy_size = btrfs_item_end(l->items + mid) - 1097 data_copy_size = btrfs_item_end(l->items + mid) -
1093 leaf_data_end(root, l); 1098 leaf_data_end(root, l);
1094 memcpy(right->items, l->items + mid, 1099 memcpy(right->items, l->items + mid,
@@ -1107,11 +1112,11 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1107 btrfs_set_header_nritems(&l->header, mid); 1112 btrfs_set_header_nritems(&l->header, mid);
1108 ret = 0; 1113 ret = 0;
1109 wret = insert_ptr(trans, root, path, &right->items[0].key, 1114 wret = insert_ptr(trans, root, path, &right->items[0].key,
1110 right_buffer->blocknr, path->slots[1] + 1, 1); 1115 right_buffer->b_blocknr, path->slots[1] + 1, 1);
1111 if (wret) 1116 if (wret)
1112 ret = wret; 1117 ret = wret;
1113 BUG_ON(list_empty(&right_buffer->dirty)); 1118 BUG_ON(!buffer_dirty(right_buffer));
1114 BUG_ON(list_empty(&l_buf->dirty)); 1119 BUG_ON(!buffer_dirty(l_buf));
1115 BUG_ON(path->slots[0] != slot); 1120 BUG_ON(path->slots[0] != slot);
1116 if (mid <= slot) { 1121 if (mid <= slot) {
1117 btrfs_block_release(root, path->nodes[0]); 1122 btrfs_block_release(root, path->nodes[0]);
@@ -1136,7 +1141,7 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
1136 int slot; 1141 int slot;
1137 int slot_orig; 1142 int slot_orig;
1138 struct btrfs_leaf *leaf; 1143 struct btrfs_leaf *leaf;
1139 struct btrfs_buffer *leaf_buf; 1144 struct buffer_head *leaf_buf;
1140 u32 nritems; 1145 u32 nritems;
1141 unsigned int data_end; 1146 unsigned int data_end;
1142 struct btrfs_disk_key disk_key; 1147 struct btrfs_disk_key disk_key;
@@ -1156,7 +1161,7 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
1156 1161
1157 slot_orig = path->slots[0]; 1162 slot_orig = path->slots[0];
1158 leaf_buf = path->nodes[0]; 1163 leaf_buf = path->nodes[0];
1159 leaf = &leaf_buf->leaf; 1164 leaf = btrfs_buffer_leaf(leaf_buf);
1160 1165
1161 nritems = btrfs_header_nritems(&leaf->header); 1166 nritems = btrfs_header_nritems(&leaf->header);
1162 data_end = leaf_data_end(root, leaf); 1167 data_end = leaf_data_end(root, leaf);
@@ -1202,7 +1207,7 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
1202 if (slot == 0) 1207 if (slot == 0)
1203 ret = fixup_low_keys(trans, root, path, &disk_key, 1); 1208 ret = fixup_low_keys(trans, root, path, &disk_key, 1);
1204 1209
1205 BUG_ON(list_empty(&leaf_buf->dirty)); 1210 BUG_ON(!buffer_dirty(leaf_buf));
1206 if (btrfs_leaf_free_space(root, leaf) < 0) 1211 if (btrfs_leaf_free_space(root, leaf) < 0)
1207 BUG(); 1212 BUG();
1208 check_leaf(root, path, 0); 1213 check_leaf(root, path, 0);
@@ -1225,7 +1230,8 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
1225 btrfs_init_path(&path); 1230 btrfs_init_path(&path);
1226 ret = btrfs_insert_empty_item(trans, root, &path, cpu_key, data_size); 1231 ret = btrfs_insert_empty_item(trans, root, &path, cpu_key, data_size);
1227 if (!ret) { 1232 if (!ret) {
1228 ptr = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0], u8); 1233 ptr = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]),
1234 path.slots[0], u8);
1229 memcpy(ptr, data, data_size); 1235 memcpy(ptr, data, data_size);
1230 } 1236 }
1231 btrfs_release_path(root, &path); 1237 btrfs_release_path(root, &path);
@@ -1243,12 +1249,12 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1243 struct btrfs_path *path, int level, int slot) 1249 struct btrfs_path *path, int level, int slot)
1244{ 1250{
1245 struct btrfs_node *node; 1251 struct btrfs_node *node;
1246 struct btrfs_buffer *parent = path->nodes[level]; 1252 struct buffer_head *parent = path->nodes[level];
1247 u32 nritems; 1253 u32 nritems;
1248 int ret = 0; 1254 int ret = 0;
1249 int wret; 1255 int wret;
1250 1256
1251 node = &parent->node; 1257 node = btrfs_buffer_node(parent);
1252 nritems = btrfs_header_nritems(&node->header); 1258 nritems = btrfs_header_nritems(&node->header);
1253 if (slot != nritems -1) { 1259 if (slot != nritems -1) {
1254 memmove(node->ptrs + slot, node->ptrs + slot + 1, 1260 memmove(node->ptrs + slot, node->ptrs + slot + 1,
@@ -1257,16 +1263,17 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1257 nritems--; 1263 nritems--;
1258 btrfs_set_header_nritems(&node->header, nritems); 1264 btrfs_set_header_nritems(&node->header, nritems);
1259 if (nritems == 0 && parent == root->node) { 1265 if (nritems == 0 && parent == root->node) {
1260 BUG_ON(btrfs_header_level(&root->node->node.header) != 1); 1266 struct btrfs_header *header = btrfs_buffer_header(root->node);
1267 BUG_ON(btrfs_header_level(header) != 1);
1261 /* just turn the root into a leaf and break */ 1268 /* just turn the root into a leaf and break */
1262 btrfs_set_header_level(&root->node->node.header, 0); 1269 btrfs_set_header_level(header, 0);
1263 } else if (slot == 0) { 1270 } else if (slot == 0) {
1264 wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key, 1271 wret = fixup_low_keys(trans, root, path, &node->ptrs[0].key,
1265 level + 1); 1272 level + 1);
1266 if (wret) 1273 if (wret)
1267 ret = wret; 1274 ret = wret;
1268 } 1275 }
1269 BUG_ON(list_empty(&parent->dirty)); 1276 BUG_ON(!buffer_dirty(parent));
1270 return ret; 1277 return ret;
1271} 1278}
1272 1279
@@ -1279,7 +1286,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1279{ 1286{
1280 int slot; 1287 int slot;
1281 struct btrfs_leaf *leaf; 1288 struct btrfs_leaf *leaf;
1282 struct btrfs_buffer *leaf_buf; 1289 struct buffer_head *leaf_buf;
1283 int doff; 1290 int doff;
1284 int dsize; 1291 int dsize;
1285 int ret = 0; 1292 int ret = 0;
@@ -1287,7 +1294,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1287 u32 nritems; 1294 u32 nritems;
1288 1295
1289 leaf_buf = path->nodes[0]; 1296 leaf_buf = path->nodes[0];
1290 leaf = &leaf_buf->leaf; 1297 leaf = btrfs_buffer_leaf(leaf_buf);
1291 slot = path->slots[0]; 1298 slot = path->slots[0];
1292 doff = btrfs_item_offset(leaf->items + slot); 1299 doff = btrfs_item_offset(leaf->items + slot);
1293 dsize = btrfs_item_size(leaf->items + slot); 1300 dsize = btrfs_item_size(leaf->items + slot);
@@ -1313,14 +1320,13 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1313 if (nritems == 0) { 1320 if (nritems == 0) {
1314 if (leaf_buf == root->node) { 1321 if (leaf_buf == root->node) {
1315 btrfs_set_header_level(&leaf->header, 0); 1322 btrfs_set_header_level(&leaf->header, 0);
1316 BUG_ON(list_empty(&leaf_buf->dirty));
1317 } else { 1323 } else {
1318 clean_tree_block(trans, root, leaf_buf); 1324 clean_tree_block(trans, root, leaf_buf);
1319 wret = del_ptr(trans, root, path, 1, path->slots[1]); 1325 wret = del_ptr(trans, root, path, 1, path->slots[1]);
1320 if (wret) 1326 if (wret)
1321 ret = wret; 1327 ret = wret;
1322 wret = btrfs_free_extent(trans, root, 1328 wret = btrfs_free_extent(trans, root,
1323 leaf_buf->blocknr, 1, 1); 1329 leaf_buf->b_blocknr, 1, 1);
1324 if (wret) 1330 if (wret)
1325 ret = wret; 1331 ret = wret;
1326 } 1332 }
@@ -1332,7 +1338,6 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1332 if (wret) 1338 if (wret)
1333 ret = wret; 1339 ret = wret;
1334 } 1340 }
1335 BUG_ON(list_empty(&leaf_buf->dirty));
1336 1341
1337 /* delete the leaf if it is mostly empty */ 1342 /* delete the leaf if it is mostly empty */
1338 if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) { 1343 if (used < BTRFS_LEAF_DATA_SIZE(root) / 3) {
@@ -1341,7 +1346,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1341 * for possible call to del_ptr below 1346 * for possible call to del_ptr below
1342 */ 1347 */
1343 slot = path->slots[1]; 1348 slot = path->slots[1];
1344 leaf_buf->count++; 1349 get_bh(leaf_buf);
1345 wret = push_leaf_left(trans, root, path, 1); 1350 wret = push_leaf_left(trans, root, path, 1);
1346 if (wret < 0) 1351 if (wret < 0)
1347 ret = wret; 1352 ret = wret;
@@ -1352,7 +1357,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
1352 ret = wret; 1357 ret = wret;
1353 } 1358 }
1354 if (btrfs_header_nritems(&leaf->header) == 0) { 1359 if (btrfs_header_nritems(&leaf->header) == 0) {
1355 u64 blocknr = leaf_buf->blocknr; 1360 u64 blocknr = leaf_buf->b_blocknr;
1356 clean_tree_block(trans, root, leaf_buf); 1361 clean_tree_block(trans, root, leaf_buf);
1357 wret = del_ptr(trans, root, path, 1, slot); 1362 wret = del_ptr(trans, root, path, 1, slot);
1358 if (wret) 1363 if (wret)
@@ -1380,19 +1385,21 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
1380 int slot; 1385 int slot;
1381 int level = 1; 1386 int level = 1;
1382 u64 blocknr; 1387 u64 blocknr;
1383 struct btrfs_buffer *c; 1388 struct buffer_head *c;
1384 struct btrfs_buffer *next = NULL; 1389 struct btrfs_node *c_node;
1390 struct buffer_head *next = NULL;
1385 1391
1386 while(level < BTRFS_MAX_LEVEL) { 1392 while(level < BTRFS_MAX_LEVEL) {
1387 if (!path->nodes[level]) 1393 if (!path->nodes[level])
1388 return 1; 1394 return 1;
1389 slot = path->slots[level] + 1; 1395 slot = path->slots[level] + 1;
1390 c = path->nodes[level]; 1396 c = path->nodes[level];
1391 if (slot >= btrfs_header_nritems(&c->node.header)) { 1397 c_node = btrfs_buffer_node(c);
1398 if (slot >= btrfs_header_nritems(&c_node->header)) {
1392 level++; 1399 level++;
1393 continue; 1400 continue;
1394 } 1401 }
1395 blocknr = btrfs_node_blockptr(&c->node, slot); 1402 blocknr = btrfs_node_blockptr(c_node, slot);
1396 if (next) 1403 if (next)
1397 btrfs_block_release(root, next); 1404 btrfs_block_release(root, next);
1398 next = read_tree_block(root, blocknr); 1405 next = read_tree_block(root, blocknr);
@@ -1408,7 +1415,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
1408 if (!level) 1415 if (!level)
1409 break; 1416 break;
1410 next = read_tree_block(root, 1417 next = read_tree_block(root,
1411 btrfs_node_blockptr(&next->node, 0)); 1418 btrfs_node_blockptr(btrfs_buffer_node(next), 0));
1412 } 1419 }
1413 return 0; 1420 return 0;
1414} 1421}
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index ae8518cb94bf..7748eecd9304 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1,6 +1,9 @@
1#ifndef __BTRFS__ 1#ifndef __BTRFS__
2#define __BTRFS__ 2#define __BTRFS__
3 3
4#include <linux/radix-tree.h>
5#include <linux/fs.h>
6
4struct btrfs_trans_handle; 7struct btrfs_trans_handle;
5 8
6#define BTRFS_MAGIC "_BtRfS_M" 9#define BTRFS_MAGIC "_BtRfS_M"
@@ -11,6 +14,12 @@ struct btrfs_trans_handle;
11#define BTRFS_FS_TREE_OBJECTID 4 14#define BTRFS_FS_TREE_OBJECTID 4
12 15
13/* 16/*
17 * we can actually store much bigger names, but lets not confuse the rest
18 * of linux
19 */
20#define BTRFS_NAME_LEN 255
21
22/*
14 * the key defines the order in the tree, and so it also defines (optimal) 23 * the key defines the order in the tree, and so it also defines (optimal)
15 * block layout. objectid corresonds to the inode number. The flags 24 * block layout. objectid corresonds to the inode number. The flags
16 * tells us things about the object, and is a kind of stream selector. 25 * tells us things about the object, and is a kind of stream selector.
@@ -57,7 +66,7 @@ struct btrfs_header {
57#define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header)) 66#define __BTRFS_LEAF_DATA_SIZE(bs) ((bs) - sizeof(struct btrfs_header))
58#define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->blocksize)) 67#define BTRFS_LEAF_DATA_SIZE(r) (__BTRFS_LEAF_DATA_SIZE(r->blocksize))
59 68
60struct btrfs_buffer; 69struct buffer_head;
61/* 70/*
62 * the super block basically lists the main trees of the FS 71 * the super block basically lists the main trees of the FS
63 * it currently lacks any block count etc etc 72 * it currently lacks any block count etc etc
@@ -120,7 +129,7 @@ struct btrfs_node {
120 * used while walking the tree. 129 * used while walking the tree.
121 */ 130 */
122struct btrfs_path { 131struct btrfs_path {
123 struct btrfs_buffer *nodes[BTRFS_MAX_LEVEL]; 132 struct buffer_head *nodes[BTRFS_MAX_LEVEL];
124 int slots[BTRFS_MAX_LEVEL]; 133 int slots[BTRFS_MAX_LEVEL];
125}; 134};
126 135
@@ -211,17 +220,14 @@ struct btrfs_fs_info {
211 struct btrfs_root *inode_root; 220 struct btrfs_root *inode_root;
212 struct btrfs_key current_insert; 221 struct btrfs_key current_insert;
213 struct btrfs_key last_insert; 222 struct btrfs_key last_insert;
214 struct radix_tree_root cache_radix;
215 struct radix_tree_root pinned_radix; 223 struct radix_tree_root pinned_radix;
216 struct list_head trans;
217 struct list_head cache;
218 u64 last_inode_alloc; 224 u64 last_inode_alloc;
219 u64 last_inode_alloc_dirid; 225 u64 last_inode_alloc_dirid;
220 u64 generation; 226 u64 generation;
221 int cache_size;
222 int fp;
223 struct btrfs_trans_handle *running_transaction; 227 struct btrfs_trans_handle *running_transaction;
224 struct btrfs_super_block *disk_super; 228 struct btrfs_super_block *disk_super;
229 struct buffer_head *sb_buffer;
230 struct super_block *sb;
225}; 231};
226 232
227/* 233/*
@@ -230,8 +236,8 @@ struct btrfs_fs_info {
230 * only for the extent tree. 236 * only for the extent tree.
231 */ 237 */
232struct btrfs_root { 238struct btrfs_root {
233 struct btrfs_buffer *node; 239 struct buffer_head *node;
234 struct btrfs_buffer *commit_root; 240 struct buffer_head *commit_root;
235 struct btrfs_root_item root_item; 241 struct btrfs_root_item root_item;
236 struct btrfs_key root_key; 242 struct btrfs_key root_key;
237 struct btrfs_fs_info *fs_info; 243 struct btrfs_fs_info *fs_info;
@@ -389,6 +395,29 @@ static inline void btrfs_set_inode_compat_flags(struct btrfs_inode_item *i,
389 i->compat_flags = cpu_to_le16(val); 395 i->compat_flags = cpu_to_le16(val);
390} 396}
391 397
398static inline u32 btrfs_timespec_sec(struct btrfs_inode_timespec *ts)
399{
400 return le32_to_cpu(ts->sec);
401}
402
403static inline void btrfs_set_timespec_sec(struct btrfs_inode_timespec *ts,
404 u32 val)
405{
406 ts->sec = cpu_to_le32(val);
407}
408
409static inline u32 btrfs_timespec_nsec(struct btrfs_inode_timespec *ts)
410{
411 return le32_to_cpu(ts->nsec);
412}
413
414static inline void btrfs_set_timespec_nsec(struct btrfs_inode_timespec *ts,
415 u32 val)
416{
417 ts->nsec = cpu_to_le32(val);
418}
419
420
392 421
393static inline u64 btrfs_extent_owner(struct btrfs_extent_item *ei) 422static inline u64 btrfs_extent_owner(struct btrfs_extent_item *ei)
394{ 423{
@@ -757,15 +786,20 @@ static inline void btrfs_set_file_extent_num_blocks(struct
757 e->num_blocks = cpu_to_le64(val); 786 e->num_blocks = cpu_to_le64(val);
758} 787}
759 788
789static inline struct btrfs_root *btrfs_sb(struct super_block *sb)
790{
791 return sb->s_fs_info;
792}
793
760/* helper function to cast into the data area of the leaf. */ 794/* helper function to cast into the data area of the leaf. */
761#define btrfs_item_ptr(leaf, slot, type) \ 795#define btrfs_item_ptr(leaf, slot, type) \
762 ((type *)(btrfs_leaf_data(leaf) + \ 796 ((type *)(btrfs_leaf_data(leaf) + \
763 btrfs_item_offset((leaf)->items + (slot)))) 797 btrfs_item_offset((leaf)->items + (slot))))
764 798
765struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, 799struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
766 struct btrfs_root *root); 800 struct btrfs_root *root);
767int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, 801int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
768 struct btrfs_buffer *buf); 802 struct buffer_head *buf);
769int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root 803int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
770 *root, u64 blocknr, u64 num_blocks, int pin); 804 *root, u64 blocknr, u64 num_blocks, int pin);
771int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root 805int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
@@ -783,7 +817,7 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, struct btrfs_root
783int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); 817int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
784int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf); 818int btrfs_leaf_free_space(struct btrfs_root *root, struct btrfs_leaf *leaf);
785int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root 819int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
786 *root, struct btrfs_buffer *snap); 820 *root, struct buffer_head *snap);
787int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct 821int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
788 btrfs_root *root); 822 btrfs_root *root);
789int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, 823int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
@@ -800,8 +834,8 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
800 *root, char *name, int name_len, u64 dir, u64 834 *root, char *name, int name_len, u64 dir, u64
801 objectid, u8 type); 835 objectid, u8 type);
802int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root 836int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
803 *root, struct btrfs_path *path, u64 dir, char *name, 837 *root, struct btrfs_path *path, u64 dir,
804 int name_len, int mod); 838 const char *name, int name_len, int mod);
805int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path, 839int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path,
806 char *name, int name_len); 840 char *name, int name_len);
807int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, 841int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index 4d8083d92fa0..75d6e373e98d 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -18,12 +18,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
18 key.objectid = dir; 18 key.objectid = dir;
19 key.flags = 0; 19 key.flags = 0;
20 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); 20 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
21 if (name_len == 1 && *name == '.') 21 ret = btrfs_name_hash(name, name_len, &key.offset);
22 key.offset = 1;
23 else if (name_len == 2 && name[0] == '.' && name[1] == '.')
24 key.offset = 2;
25 else
26 ret = btrfs_name_hash(name, name_len, &key.offset);
27 BUG_ON(ret); 22 BUG_ON(ret);
28 btrfs_init_path(&path); 23 btrfs_init_path(&path);
29 data_size = sizeof(*dir_item) + name_len; 24 data_size = sizeof(*dir_item) + name_len;
@@ -31,7 +26,8 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
31 if (ret) 26 if (ret)
32 goto out; 27 goto out;
33 28
34 dir_item = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0], 29 dir_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]),
30 path.slots[0],
35 struct btrfs_dir_item); 31 struct btrfs_dir_item);
36 btrfs_set_dir_objectid(dir_item, objectid); 32 btrfs_set_dir_objectid(dir_item, objectid);
37 btrfs_set_dir_type(dir_item, type); 33 btrfs_set_dir_type(dir_item, type);
@@ -45,8 +41,8 @@ out:
45} 41}
46 42
47int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root 43int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
48 *root, struct btrfs_path *path, u64 dir, char *name, 44 *root, struct btrfs_path *path, u64 dir,
49 int name_len, int mod) 45 const char *name, int name_len, int mod)
50{ 46{
51 int ret; 47 int ret;
52 struct btrfs_key key; 48 struct btrfs_key key;
@@ -69,7 +65,8 @@ int btrfs_match_dir_item_name(struct btrfs_root *root,
69 struct btrfs_dir_item *dir_item; 65 struct btrfs_dir_item *dir_item;
70 char *name_ptr; 66 char *name_ptr;
71 67
72 dir_item = btrfs_item_ptr(&path->nodes[0]->leaf, path->slots[0], 68 dir_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
69 path->slots[0],
73 struct btrfs_dir_item); 70 struct btrfs_dir_item);
74 if (btrfs_dir_name_len(dir_item) != name_len) 71 if (btrfs_dir_name_len(dir_item) != name_len)
75 return 0; 72 return 0;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 05637f9fd7c7..df2061a735cd 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1,165 +1,67 @@
1#define _XOPEN_SOURCE 500 1#include <linux/module.h>
2#include <stdio.h> 2#include <linux/fs.h>
3#include <stdlib.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <fcntl.h>
7#include <unistd.h>
8#include "kerncompat.h"
9#include "radix-tree.h"
10#include "ctree.h" 3#include "ctree.h"
11#include "disk-io.h" 4#include "disk-io.h"
12#include "transaction.h" 5#include "transaction.h"
13 6
14static int allocated_blocks = 0; 7static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf)
15int cache_max = 10000;
16
17static int check_tree_block(struct btrfs_root *root, struct btrfs_buffer *buf)
18{ 8{
19 if (buf->blocknr != btrfs_header_blocknr(&buf->node.header)) 9 struct btrfs_node *node = btrfs_buffer_node(buf);
10 if (buf->b_blocknr != btrfs_header_blocknr(&node->header))
20 BUG(); 11 BUG();
21 if (root->node && btrfs_header_parentid(&buf->node.header) != 12 if (root->node && btrfs_header_parentid(&node->header) !=
22 btrfs_header_parentid(&root->node->node.header)) 13 btrfs_header_parentid(btrfs_buffer_header(root->node)))
23 BUG(); 14 BUG();
24 return 0; 15 return 0;
25} 16}
26 17
27static int free_some_buffers(struct btrfs_root *root) 18struct buffer_head *alloc_tree_block(struct btrfs_root *root, u64 blocknr)
28{ 19{
29 struct list_head *node, *next; 20 return sb_getblk(root->fs_info->sb, blocknr);
30 struct btrfs_buffer *b;
31 if (root->fs_info->cache_size < cache_max)
32 return 0;
33 list_for_each_safe(node, next, &root->fs_info->cache) {
34 b = list_entry(node, struct btrfs_buffer, cache);
35 if (b->count == 1) {
36 BUG_ON(!list_empty(&b->dirty));
37 list_del_init(&b->cache);
38 btrfs_block_release(root, b);
39 if (root->fs_info->cache_size < cache_max)
40 break;
41 }
42 }
43 return 0;
44} 21}
45 22
46struct btrfs_buffer *alloc_tree_block(struct btrfs_root *root, u64 blocknr) 23struct buffer_head *find_tree_block(struct btrfs_root *root, u64 blocknr)
47{ 24{
48 struct btrfs_buffer *buf; 25 return sb_getblk(root->fs_info->sb, blocknr);
49 int ret;
50
51 buf = malloc(sizeof(struct btrfs_buffer) + root->blocksize);
52 if (!buf)
53 return buf;
54 allocated_blocks++;
55 buf->blocknr = blocknr;
56 buf->count = 2;
57 INIT_LIST_HEAD(&buf->dirty);
58 free_some_buffers(root);
59 radix_tree_preload(GFP_KERNEL);
60 ret = radix_tree_insert(&root->fs_info->cache_radix, blocknr, buf);
61 radix_tree_preload_end();
62 list_add_tail(&buf->cache, &root->fs_info->cache);
63 root->fs_info->cache_size++;
64 if (ret) {
65 free(buf);
66 return NULL;
67 }
68 return buf;
69} 26}
70 27
71struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 blocknr) 28struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr)
72{ 29{
73 struct btrfs_buffer *buf; 30 struct buffer_head *buf = sb_bread(root->fs_info->sb, blocknr);
74 buf = radix_tree_lookup(&root->fs_info->cache_radix, blocknr);
75 if (buf) {
76 buf->count++;
77 } else {
78 buf = alloc_tree_block(root, blocknr);
79 if (!buf) {
80 BUG();
81 return NULL;
82 }
83 }
84 return buf;
85}
86
87struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr)
88{
89 loff_t offset = blocknr * root->blocksize;
90 struct btrfs_buffer *buf;
91 int ret;
92 31
93 buf = radix_tree_lookup(&root->fs_info->cache_radix, blocknr); 32 if (!buf)
94 if (buf) { 33 return buf;
95 buf->count++;
96 } else {
97 buf = alloc_tree_block(root, blocknr);
98 if (!buf)
99 return NULL;
100 ret = pread(root->fs_info->fp, &buf->node, root->blocksize,
101 offset);
102 if (ret != root->blocksize) {
103 free(buf);
104 return NULL;
105 }
106 }
107 if (check_tree_block(root, buf)) 34 if (check_tree_block(root, buf))
108 BUG(); 35 BUG();
109 return buf; 36 return buf;
110} 37}
111 38
112int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, 39int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
113 struct btrfs_buffer *buf) 40 struct buffer_head *buf)
114{ 41{
115 if (!list_empty(&buf->dirty)) 42 mark_buffer_dirty(buf);
116 return 0;
117 list_add_tail(&buf->dirty, &root->fs_info->trans);
118 buf->count++;
119 return 0; 43 return 0;
120} 44}
121 45
122int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, 46int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
123 struct btrfs_buffer *buf) 47 struct buffer_head *buf)
124{ 48{
125 if (!list_empty(&buf->dirty)) { 49 clear_buffer_dirty(buf);
126 list_del_init(&buf->dirty);
127 btrfs_block_release(root, buf);
128 }
129 return 0; 50 return 0;
130} 51}
131 52
132int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, 53int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
133 struct btrfs_buffer *buf) 54 struct buffer_head *buf)
134{ 55{
135 u64 blocknr = buf->blocknr; 56 mark_buffer_dirty(buf);
136 loff_t offset = blocknr * root->blocksize;
137 int ret;
138
139 if (buf->blocknr != btrfs_header_blocknr(&buf->node.header))
140 BUG();
141 ret = pwrite(root->fs_info->fp, &buf->node, root->blocksize, offset);
142 if (ret != root->blocksize)
143 return ret;
144 return 0; 57 return 0;
145} 58}
146 59
147static int __commit_transaction(struct btrfs_trans_handle *trans, struct 60static int __commit_transaction(struct btrfs_trans_handle *trans, struct
148 btrfs_root *root) 61 btrfs_root *root)
149{ 62{
150 struct btrfs_buffer *b; 63 filemap_write_and_wait(root->fs_info->sb->s_bdev->bd_inode->i_mapping);
151 int ret = 0; 64 return 0;
152 int wret;
153 while(!list_empty(&root->fs_info->trans)) {
154 b = list_entry(root->fs_info->trans.next, struct btrfs_buffer,
155 dirty);
156 list_del_init(&b->dirty);
157 wret = write_tree_block(trans, root, b);
158 if (wret)
159 ret = wret;
160 btrfs_block_release(root, b);
161 }
162 return ret;
163} 65}
164 66
165static int commit_tree_roots(struct btrfs_trans_handle *trans, 67static int commit_tree_roots(struct btrfs_trans_handle *trans,
@@ -172,17 +74,17 @@ static int commit_tree_roots(struct btrfs_trans_handle *trans,
172 struct btrfs_root *inode_root = fs_info->inode_root; 74 struct btrfs_root *inode_root = fs_info->inode_root;
173 75
174 btrfs_set_root_blocknr(&inode_root->root_item, 76 btrfs_set_root_blocknr(&inode_root->root_item,
175 inode_root->node->blocknr); 77 inode_root->node->b_blocknr);
176 ret = btrfs_update_root(trans, tree_root, 78 ret = btrfs_update_root(trans, tree_root,
177 &inode_root->root_key, 79 &inode_root->root_key,
178 &inode_root->root_item); 80 &inode_root->root_item);
179 BUG_ON(ret); 81 BUG_ON(ret);
180 while(1) { 82 while(1) {
181 old_extent_block = btrfs_root_blocknr(&extent_root->root_item); 83 old_extent_block = btrfs_root_blocknr(&extent_root->root_item);
182 if (old_extent_block == extent_root->node->blocknr) 84 if (old_extent_block == extent_root->node->b_blocknr)
183 break; 85 break;
184 btrfs_set_root_blocknr(&extent_root->root_item, 86 btrfs_set_root_blocknr(&extent_root->root_item,
185 extent_root->node->blocknr); 87 extent_root->node->b_blocknr);
186 ret = btrfs_update_root(trans, tree_root, 88 ret = btrfs_update_root(trans, tree_root,
187 &extent_root->root_key, 89 &extent_root->root_key,
188 &extent_root->root_item); 90 &extent_root->root_item);
@@ -195,7 +97,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
195 btrfs_root *root, struct btrfs_super_block *s) 97 btrfs_root *root, struct btrfs_super_block *s)
196{ 98{
197 int ret = 0; 99 int ret = 0;
198 struct btrfs_buffer *snap = root->commit_root; 100 struct buffer_head *snap = root->commit_root;
199 struct btrfs_key snap_key; 101 struct btrfs_key snap_key;
200 102
201 if (root->commit_root == root->node) 103 if (root->commit_root == root->node)
@@ -204,7 +106,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
204 memcpy(&snap_key, &root->root_key, sizeof(snap_key)); 106 memcpy(&snap_key, &root->root_key, sizeof(snap_key));
205 root->root_key.offset++; 107 root->root_key.offset++;
206 108
207 btrfs_set_root_blocknr(&root->root_item, root->node->blocknr); 109 btrfs_set_root_blocknr(&root->root_item, root->node->b_blocknr);
208 ret = btrfs_insert_root(trans, root->fs_info->tree_root, 110 ret = btrfs_insert_root(trans, root->fs_info->tree_root,
209 &root->root_key, &root->root_item); 111 &root->root_key, &root->root_item);
210 BUG_ON(ret); 112 BUG_ON(ret);
@@ -220,7 +122,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
220 btrfs_finish_extent_commit(trans, root->fs_info->tree_root); 122 btrfs_finish_extent_commit(trans, root->fs_info->tree_root);
221 123
222 root->commit_root = root->node; 124 root->commit_root = root->node;
223 root->node->count++; 125 get_bh(root->node);
224 ret = btrfs_drop_snapshot(trans, root, snap); 126 ret = btrfs_drop_snapshot(trans, root, snap);
225 BUG_ON(ret); 127 BUG_ON(ret);
226 128
@@ -234,7 +136,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct
234static int __setup_root(struct btrfs_super_block *super, 136static int __setup_root(struct btrfs_super_block *super,
235 struct btrfs_root *root, 137 struct btrfs_root *root,
236 struct btrfs_fs_info *fs_info, 138 struct btrfs_fs_info *fs_info,
237 u64 objectid, int fp) 139 u64 objectid)
238{ 140{
239 root->node = NULL; 141 root->node = NULL;
240 root->commit_root = NULL; 142 root->commit_root = NULL;
@@ -250,11 +152,11 @@ static int find_and_setup_root(struct btrfs_super_block *super,
250 struct btrfs_root *tree_root, 152 struct btrfs_root *tree_root,
251 struct btrfs_fs_info *fs_info, 153 struct btrfs_fs_info *fs_info,
252 u64 objectid, 154 u64 objectid,
253 struct btrfs_root *root, int fp) 155 struct btrfs_root *root)
254{ 156{
255 int ret; 157 int ret;
256 158
257 __setup_root(super, root, fs_info, objectid, fp); 159 __setup_root(super, root, fs_info, objectid);
258 ret = btrfs_find_last_root(tree_root, objectid, 160 ret = btrfs_find_last_root(tree_root, objectid,
259 &root->root_item, &root->root_key); 161 &root->root_item, &root->root_key);
260 BUG_ON(ret); 162 BUG_ON(ret);
@@ -265,32 +167,26 @@ static int find_and_setup_root(struct btrfs_super_block *super,
265 return 0; 167 return 0;
266} 168}
267 169
268struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *super) 170struct btrfs_root *open_ctree(struct super_block *sb,
171 struct buffer_head *sb_buffer,
172 struct btrfs_super_block *disk_super)
269{ 173{
270 int fp; 174 struct btrfs_root *root = kmalloc(sizeof(struct btrfs_root),
271 175 GFP_NOFS);
272 fp = open(filename, O_CREAT | O_RDWR, 0600); 176 struct btrfs_root *extent_root = kmalloc(sizeof(struct btrfs_root),
273 if (fp < 0) { 177 GFP_NOFS);
274 return NULL; 178 struct btrfs_root *tree_root = kmalloc(sizeof(struct btrfs_root),
275 } 179 GFP_NOFS);
276 return open_ctree_fd(fp, super); 180 struct btrfs_root *inode_root = kmalloc(sizeof(struct btrfs_root),
277} 181 GFP_NOFS);
278 182 struct btrfs_fs_info *fs_info = kmalloc(sizeof(*fs_info),
279struct btrfs_root *open_ctree_fd(int fp, struct btrfs_super_block *super) 183 GFP_NOFS);
280{
281 struct btrfs_root *root = malloc(sizeof(struct btrfs_root));
282 struct btrfs_root *extent_root = malloc(sizeof(struct btrfs_root));
283 struct btrfs_root *tree_root = malloc(sizeof(struct btrfs_root));
284 struct btrfs_root *inode_root = malloc(sizeof(struct btrfs_root));
285 struct btrfs_fs_info *fs_info = malloc(sizeof(*fs_info));
286 int ret; 184 int ret;
287 185
288 INIT_RADIX_TREE(&fs_info->cache_radix, GFP_KERNEL); 186 /* FIXME: don't be stupid */
187 if (!btrfs_super_root(disk_super))
188 return NULL;
289 INIT_RADIX_TREE(&fs_info->pinned_radix, GFP_KERNEL); 189 INIT_RADIX_TREE(&fs_info->pinned_radix, GFP_KERNEL);
290 INIT_LIST_HEAD(&fs_info->trans);
291 INIT_LIST_HEAD(&fs_info->cache);
292 fs_info->cache_size = 0;
293 fs_info->fp = fp;
294 fs_info->running_transaction = NULL; 190 fs_info->running_transaction = NULL;
295 fs_info->fs_root = root; 191 fs_info->fs_root = root;
296 fs_info->tree_root = tree_root; 192 fs_info->tree_root = tree_root;
@@ -298,36 +194,31 @@ struct btrfs_root *open_ctree_fd(int fp, struct btrfs_super_block *super)
298 fs_info->inode_root = inode_root; 194 fs_info->inode_root = inode_root;
299 fs_info->last_inode_alloc = 0; 195 fs_info->last_inode_alloc = 0;
300 fs_info->last_inode_alloc_dirid = 0; 196 fs_info->last_inode_alloc_dirid = 0;
301 fs_info->disk_super = super; 197 fs_info->disk_super = disk_super;
198 fs_info->sb_buffer = sb_buffer;
199 fs_info->sb = sb;
302 memset(&fs_info->current_insert, 0, sizeof(fs_info->current_insert)); 200 memset(&fs_info->current_insert, 0, sizeof(fs_info->current_insert));
303 memset(&fs_info->last_insert, 0, sizeof(fs_info->last_insert)); 201 memset(&fs_info->last_insert, 0, sizeof(fs_info->last_insert));
304 202
305 ret = pread(fp, super, sizeof(struct btrfs_super_block), 203 __setup_root(disk_super, tree_root, fs_info, BTRFS_ROOT_TREE_OBJECTID);
306 BTRFS_SUPER_INFO_OFFSET); 204 tree_root->node = read_tree_block(tree_root,
307 if (ret == 0 || btrfs_super_root(super) == 0) { 205 btrfs_super_root(disk_super));
308 BUG();
309 return NULL;
310 }
311 BUG_ON(ret < 0);
312
313 __setup_root(super, tree_root, fs_info, BTRFS_ROOT_TREE_OBJECTID, fp);
314 tree_root->node = read_tree_block(tree_root, btrfs_super_root(super));
315 BUG_ON(!tree_root->node); 206 BUG_ON(!tree_root->node);
316 207
317 ret = find_and_setup_root(super, tree_root, fs_info, 208 ret = find_and_setup_root(disk_super, tree_root, fs_info,
318 BTRFS_EXTENT_TREE_OBJECTID, extent_root, fp); 209 BTRFS_EXTENT_TREE_OBJECTID, extent_root);
319 BUG_ON(ret); 210 BUG_ON(ret);
320 211
321 ret = find_and_setup_root(super, tree_root, fs_info, 212 ret = find_and_setup_root(disk_super, tree_root, fs_info,
322 BTRFS_INODE_MAP_OBJECTID, inode_root, fp); 213 BTRFS_INODE_MAP_OBJECTID, inode_root);
323 BUG_ON(ret); 214 BUG_ON(ret);
324 215
325 ret = find_and_setup_root(super, tree_root, fs_info, 216 ret = find_and_setup_root(disk_super, tree_root, fs_info,
326 BTRFS_FS_TREE_OBJECTID, root, fp); 217 BTRFS_FS_TREE_OBJECTID, root);
327 BUG_ON(ret); 218 BUG_ON(ret);
328 219
329 root->commit_root = root->node; 220 root->commit_root = root->node;
330 root->node->count++; 221 get_bh(root->node);
331 root->ref_cows = 1; 222 root->ref_cows = 1;
332 root->fs_info->generation = root->root_key.offset + 1; 223 root->fs_info->generation = root->root_key.offset + 1;
333 return root; 224 return root;
@@ -336,8 +227,11 @@ struct btrfs_root *open_ctree_fd(int fp, struct btrfs_super_block *super)
336int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root 227int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
337 *root, struct btrfs_super_block *s) 228 *root, struct btrfs_super_block *s)
338{ 229{
230 return 0;
231#if 0
339 int ret; 232 int ret;
340 btrfs_set_super_root(s, root->fs_info->tree_root->node->blocknr); 233 btrfs_set_super_root(s, root->fs_info->tree_root->node->b_blocknr);
234
341 ret = pwrite(root->fs_info->fp, s, sizeof(*s), 235 ret = pwrite(root->fs_info->fp, s, sizeof(*s),
342 BTRFS_SUPER_INFO_OFFSET); 236 BTRFS_SUPER_INFO_OFFSET);
343 if (ret != sizeof(*s)) { 237 if (ret != sizeof(*s)) {
@@ -345,35 +239,38 @@ int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
345 return ret; 239 return ret;
346 } 240 }
347 return 0; 241 return 0;
242#endif
348} 243}
349 244
350static int drop_cache(struct btrfs_root *root) 245static int drop_cache(struct btrfs_root *root)
351{ 246{
247 return 0;
248#if 0
352 while(!list_empty(&root->fs_info->cache)) { 249 while(!list_empty(&root->fs_info->cache)) {
353 struct btrfs_buffer *b = list_entry(root->fs_info->cache.next, 250 struct buffer_head *b = list_entry(root->fs_info->cache.next,
354 struct btrfs_buffer, 251 struct buffer_head,
355 cache); 252 cache);
356 list_del_init(&b->cache); 253 list_del_init(&b->cache);
357 btrfs_block_release(root, b); 254 btrfs_block_release(root, b);
358 } 255 }
359 return 0; 256 return 0;
257#endif
360} 258}
361int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s) 259
260int close_ctree(struct btrfs_root *root)
362{ 261{
363 int ret; 262 int ret;
364 struct btrfs_trans_handle *trans; 263 struct btrfs_trans_handle *trans;
365 264
366 trans = root->fs_info->running_transaction; 265 trans = root->fs_info->running_transaction;
367 btrfs_commit_transaction(trans, root, s); 266 btrfs_commit_transaction(trans, root, root->fs_info->disk_super);
368 ret = commit_tree_roots(trans, root->fs_info); 267 ret = commit_tree_roots(trans, root->fs_info);
369 BUG_ON(ret); 268 BUG_ON(ret);
370 ret = __commit_transaction(trans, root); 269 ret = __commit_transaction(trans, root);
371 BUG_ON(ret); 270 BUG_ON(ret);
372 write_ctree_super(trans, root, s); 271 write_ctree_super(trans, root, root->fs_info->disk_super);
373 drop_cache(root); 272 drop_cache(root);
374 BUG_ON(!list_empty(&root->fs_info->trans));
375 273
376 close(root->fs_info->fp);
377 if (root->node) 274 if (root->node)
378 btrfs_block_release(root, root->node); 275 btrfs_block_release(root, root->node);
379 if (root->fs_info->extent_root->node) 276 if (root->fs_info->extent_root->node)
@@ -386,29 +283,17 @@ int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s)
386 btrfs_block_release(root->fs_info->tree_root, 283 btrfs_block_release(root->fs_info->tree_root,
387 root->fs_info->tree_root->node); 284 root->fs_info->tree_root->node);
388 btrfs_block_release(root, root->commit_root); 285 btrfs_block_release(root, root->commit_root);
389 free(root); 286 btrfs_block_release(root, root->fs_info->sb_buffer);
390 printf("on close %d blocks are allocated\n", allocated_blocks); 287 kfree(root->fs_info->extent_root);
288 kfree(root->fs_info->inode_root);
289 kfree(root->fs_info->tree_root);
290 kfree(root->fs_info);
291 kfree(root);
391 return 0; 292 return 0;
392} 293}
393 294
394void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf) 295void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf)
395{ 296{
396 buf->count--; 297 brelse(buf);
397 if (buf->count < 0)
398 BUG();
399 if (buf->count == 0) {
400 BUG_ON(!list_empty(&buf->cache));
401 BUG_ON(!list_empty(&buf->dirty));
402 if (!radix_tree_lookup(&root->fs_info->cache_radix,
403 buf->blocknr))
404 BUG();
405 radix_tree_delete(&root->fs_info->cache_radix, buf->blocknr);
406 memset(buf, 0, sizeof(*buf));
407 free(buf);
408 BUG_ON(allocated_blocks == 0);
409 allocated_blocks--;
410 BUG_ON(root->fs_info->cache_size == 0);
411 root->fs_info->cache_size--;
412 }
413} 298}
414 299
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index d888cf5c350b..7f4bb729b734 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -1,36 +1,41 @@
1#ifndef __DISKIO__ 1#ifndef __DISKIO__
2#define __DISKIO__ 2#define __DISKIO__
3#include "list.h"
4 3
5struct btrfs_buffer { 4#include <linux/buffer_head.h>
6 u64 blocknr;
7 int count;
8 struct list_head dirty;
9 struct list_head cache;
10 union {
11 struct btrfs_node node;
12 struct btrfs_leaf leaf;
13 };
14};
15 5
16struct btrfs_buffer *read_tree_block(struct btrfs_root *root, u64 blocknr); 6#define BTRFS_SUPER_INFO_OFFSET (16 * 1024)
17struct btrfs_buffer *find_tree_block(struct btrfs_root *root, u64 blocknr); 7
8static inline struct btrfs_node *btrfs_buffer_node(struct buffer_head *bh)
9{
10 return (struct btrfs_node *)bh->b_data;
11}
12
13static inline struct btrfs_leaf *btrfs_buffer_leaf(struct buffer_head *bh)
14{
15 return (struct btrfs_leaf *)bh->b_data;
16}
17
18static inline struct btrfs_header *btrfs_buffer_header(struct buffer_head *bh)
19{
20 return &((struct btrfs_node *)bh->b_data)->header;
21}
22
23struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr);
24struct buffer_head *find_tree_block(struct btrfs_root *root, u64 blocknr);
18int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, 25int write_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
19 struct btrfs_buffer *buf); 26 struct buffer_head *buf);
20int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, 27int dirty_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
21 struct btrfs_buffer *buf); 28 struct buffer_head *buf);
22int clean_tree_block(struct btrfs_trans_handle *trans, 29int clean_tree_block(struct btrfs_trans_handle *trans,
23 struct btrfs_root *root, struct btrfs_buffer *buf); 30 struct btrfs_root *root, struct buffer_head *buf);
24int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct btrfs_root 31int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct btrfs_root
25 *root, struct btrfs_super_block *s); 32 *root, struct btrfs_super_block *s);
26struct btrfs_root *open_ctree(char *filename, struct btrfs_super_block *s); 33struct btrfs_root *open_ctree(struct super_block *sb,
27struct btrfs_root *open_ctree_fd(int fp, struct btrfs_super_block *super); 34 struct buffer_head *sb_buffer,
28int close_ctree(struct btrfs_root *root, struct btrfs_super_block *s); 35 struct btrfs_super_block *disk_super);
29void btrfs_block_release(struct btrfs_root *root, struct btrfs_buffer *buf); 36int close_ctree(struct btrfs_root *root);
37void btrfs_block_release(struct btrfs_root *root, struct buffer_head *buf);
30int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root *root, 38int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root *root,
31 struct btrfs_super_block *s); 39 struct btrfs_super_block *s);
32int mkfs(int fd, u64 num_blocks, u32 blocksize); 40int mkfs(int fd, u64 num_blocks, u32 blocksize);
33
34#define BTRFS_SUPER_INFO_OFFSET (16 * 1024)
35
36#endif 41#endif
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 53a7550b5c1e..e3af2c035687 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -10,9 +10,8 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
10 search_end, struct btrfs_key *ins); 10 search_end, struct btrfs_key *ins);
11static int finish_current_insert(struct btrfs_trans_handle *trans, struct 11static int finish_current_insert(struct btrfs_trans_handle *trans, struct
12 btrfs_root *extent_root); 12 btrfs_root *extent_root);
13static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root 13static int del_pending_extents(struct btrfs_trans_handle *trans, struct
14 *extent_root); 14 btrfs_root *extent_root);
15
16/* 15/*
17 * pending extents are blocks that we're trying to allocate in the extent 16 * pending extents are blocks that we're trying to allocate in the extent
18 * map while trying to grow the map because of other allocations. To avoid 17 * map while trying to grow the map because of other allocations. To avoid
@@ -21,6 +20,7 @@ static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root
21 * manner for deletes. 20 * manner for deletes.
22 */ 21 */
23#define CTREE_EXTENT_PENDING_DEL 0 22#define CTREE_EXTENT_PENDING_DEL 0
23#define CTREE_EXTENT_PINNED 1
24 24
25static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root 25static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
26 *root, u64 blocknr) 26 *root, u64 blocknr)
@@ -45,15 +45,14 @@ static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
45 if (ret != 0) 45 if (ret != 0)
46 BUG(); 46 BUG();
47 BUG_ON(ret != 0); 47 BUG_ON(ret != 0);
48 l = &path.nodes[0]->leaf; 48 l = btrfs_buffer_leaf(path.nodes[0]);
49 item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item); 49 item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item);
50 refs = btrfs_extent_refs(item); 50 refs = btrfs_extent_refs(item);
51 btrfs_set_extent_refs(item, refs + 1); 51 btrfs_set_extent_refs(item, refs + 1);
52 52
53 BUG_ON(list_empty(&path.nodes[0]->dirty));
54 btrfs_release_path(root->fs_info->extent_root, &path); 53 btrfs_release_path(root->fs_info->extent_root, &path);
55 finish_current_insert(trans, root->fs_info->extent_root); 54 finish_current_insert(trans, root->fs_info->extent_root);
56 run_pending(trans, root->fs_info->extent_root); 55 del_pending_extents(trans, root->fs_info->extent_root);
57 return 0; 56 return 0;
58} 57}
59 58
@@ -74,7 +73,7 @@ static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
74 0, 0); 73 0, 0);
75 if (ret != 0) 74 if (ret != 0)
76 BUG(); 75 BUG();
77 l = &path.nodes[0]->leaf; 76 l = btrfs_buffer_leaf(path.nodes[0]);
78 item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item); 77 item = btrfs_item_ptr(l, path.slots[0], struct btrfs_extent_item);
79 *refs = btrfs_extent_refs(item); 78 *refs = btrfs_extent_refs(item);
80 btrfs_release_path(root->fs_info->extent_root, &path); 79 btrfs_release_path(root->fs_info->extent_root, &path);
@@ -82,18 +81,20 @@ static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root
82} 81}
83 82
84int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, 83int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
85 struct btrfs_buffer *buf) 84 struct buffer_head *buf)
86{ 85{
87 u64 blocknr; 86 u64 blocknr;
87 struct btrfs_node *buf_node;
88 int i; 88 int i;
89 89
90 if (!root->ref_cows) 90 if (!root->ref_cows)
91 return 0; 91 return 0;
92 if (btrfs_is_leaf(&buf->node)) 92 buf_node = btrfs_buffer_node(buf);
93 if (btrfs_is_leaf(buf_node))
93 return 0; 94 return 0;
94 95
95 for (i = 0; i < btrfs_header_nritems(&buf->node.header); i++) { 96 for (i = 0; i < btrfs_header_nritems(&buf_node->header); i++) {
96 blocknr = btrfs_node_blockptr(&buf->node, i); 97 blocknr = btrfs_node_blockptr(buf_node, i);
97 inc_block_ref(trans, root, blocknr); 98 inc_block_ref(trans, root, blocknr);
98 } 99 }
99 return 0; 100 return 0;
@@ -108,9 +109,10 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct
108 int i; 109 int i;
109 110
110 while(1) { 111 while(1) {
111 ret = radix_tree_gang_lookup(&root->fs_info->pinned_radix, 112 ret = radix_tree_gang_lookup_tag(&root->fs_info->pinned_radix,
112 (void **)gang, 0, 113 (void **)gang, 0,
113 ARRAY_SIZE(gang)); 114 ARRAY_SIZE(gang),
115 CTREE_EXTENT_PINNED);
114 if (!ret) 116 if (!ret)
115 break; 117 break;
116 if (!first) 118 if (!first)
@@ -137,7 +139,7 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
137 139
138 btrfs_set_extent_refs(&extent_item, 1); 140 btrfs_set_extent_refs(&extent_item, 1);
139 btrfs_set_extent_owner(&extent_item, 141 btrfs_set_extent_owner(&extent_item,
140 btrfs_header_parentid(&extent_root->node->node.header)); 142 btrfs_header_parentid(btrfs_buffer_header(extent_root->node)));
141 ins.offset = 1; 143 ins.offset = 1;
142 ins.flags = 0; 144 ins.flags = 0;
143 btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY); 145 btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY);
@@ -156,11 +158,24 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
156 return 0; 158 return 0;
157} 159}
158 160
161static int pin_down_block(struct btrfs_root *root, u64 blocknr, int tag)
162{
163 int err;
164 err = radix_tree_insert(&root->fs_info->pinned_radix,
165 blocknr, (void *)blocknr);
166 BUG_ON(err);
167 if (err)
168 return err;
169 radix_tree_tag_set(&root->fs_info->pinned_radix, blocknr,
170 tag);
171 return 0;
172}
173
159/* 174/*
160 * remove an extent from the root, returns 0 on success 175 * remove an extent from the root, returns 0 on success
161 */ 176 */
162static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root 177static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
163 *root, u64 blocknr, u64 num_blocks, int pin) 178 *root, u64 blocknr, u64 num_blocks)
164{ 179{
165 struct btrfs_path path; 180 struct btrfs_path path;
166 struct btrfs_key key; 181 struct btrfs_key key;
@@ -171,7 +186,6 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
171 struct btrfs_key ins; 186 struct btrfs_key ins;
172 u32 refs; 187 u32 refs;
173 188
174 BUG_ON(pin && num_blocks != 1);
175 key.objectid = blocknr; 189 key.objectid = blocknr;
176 key.flags = 0; 190 key.flags = 0;
177 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 191 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
@@ -186,26 +200,18 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
186 printk("failed to find %Lu\n", key.objectid); 200 printk("failed to find %Lu\n", key.objectid);
187 BUG(); 201 BUG();
188 } 202 }
189 ei = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0], 203 ei = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0],
190 struct btrfs_extent_item); 204 struct btrfs_extent_item);
191 BUG_ON(ei->refs == 0); 205 BUG_ON(ei->refs == 0);
192 refs = btrfs_extent_refs(ei) - 1; 206 refs = btrfs_extent_refs(ei) - 1;
193 btrfs_set_extent_refs(ei, refs); 207 btrfs_set_extent_refs(ei, refs);
194 if (refs == 0) { 208 if (refs == 0) {
195 u64 super_blocks_used; 209 u64 super_blocks_used;
196 if (pin) {
197 int err;
198 radix_tree_preload(GFP_KERNEL);
199 err = radix_tree_insert(&info->pinned_radix,
200 blocknr, (void *)blocknr);
201 BUG_ON(err);
202 radix_tree_preload_end();
203 }
204 super_blocks_used = btrfs_super_blocks_used(info->disk_super); 210 super_blocks_used = btrfs_super_blocks_used(info->disk_super);
205 btrfs_set_super_blocks_used(info->disk_super, 211 btrfs_set_super_blocks_used(info->disk_super,
206 super_blocks_used - num_blocks); 212 super_blocks_used - num_blocks);
207 ret = btrfs_del_item(trans, extent_root, &path); 213 ret = btrfs_del_item(trans, extent_root, &path);
208 if (!pin && extent_root->fs_info->last_insert.objectid > 214 if (extent_root->fs_info->last_insert.objectid >
209 blocknr) 215 blocknr)
210 extent_root->fs_info->last_insert.objectid = blocknr; 216 extent_root->fs_info->last_insert.objectid = blocknr;
211 if (ret) 217 if (ret)
@@ -224,39 +230,32 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
224 btrfs_root *extent_root) 230 btrfs_root *extent_root)
225{ 231{
226 int ret; 232 int ret;
227 struct btrfs_buffer *gang[4]; 233 int wret;
234 int err = 0;
235 unsigned long gang[4];
228 int i; 236 int i;
237 struct radix_tree_root *radix = &extent_root->fs_info->pinned_radix;
229 238
230 while(1) { 239 while(1) {
231 ret = radix_tree_gang_lookup_tag( 240 ret = radix_tree_gang_lookup_tag(
232 &extent_root->fs_info->cache_radix, 241 &extent_root->fs_info->pinned_radix,
233 (void **)gang, 0, 242 (void **)gang, 0,
234 ARRAY_SIZE(gang), 243 ARRAY_SIZE(gang),
235 CTREE_EXTENT_PENDING_DEL); 244 CTREE_EXTENT_PENDING_DEL);
236 if (!ret) 245 if (!ret)
237 break; 246 break;
238 for (i = 0; i < ret; i++) { 247 for (i = 0; i < ret; i++) {
239 ret = __free_extent(trans, extent_root, 248 radix_tree_tag_set(radix, gang[i], CTREE_EXTENT_PINNED);
240 gang[i]->blocknr, 1, 1); 249 radix_tree_tag_clear(radix, gang[i],
241 radix_tree_tag_clear(&extent_root->fs_info->cache_radix,
242 gang[i]->blocknr,
243 CTREE_EXTENT_PENDING_DEL); 250 CTREE_EXTENT_PENDING_DEL);
244 btrfs_block_release(extent_root, gang[i]); 251 wret = __free_extent(trans, extent_root, gang[i], 1);
252 if (wret)
253 err = wret;
245 } 254 }
246 } 255 }
247 return 0; 256 return err;
248} 257}
249 258
250static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root
251 *extent_root)
252{
253 while(radix_tree_tagged(&extent_root->fs_info->cache_radix,
254 CTREE_EXTENT_PENDING_DEL))
255 del_pending_extents(trans, extent_root);
256 return 0;
257}
258
259
260/* 259/*
261 * remove an extent from the root, returns 0 on success 260 * remove an extent from the root, returns 0 on success
262 */ 261 */
@@ -264,18 +263,21 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
264 *root, u64 blocknr, u64 num_blocks, int pin) 263 *root, u64 blocknr, u64 num_blocks, int pin)
265{ 264{
266 struct btrfs_root *extent_root = root->fs_info->extent_root; 265 struct btrfs_root *extent_root = root->fs_info->extent_root;
267 struct btrfs_buffer *t; 266 struct buffer_head *t;
268 int pending_ret; 267 int pending_ret;
269 int ret; 268 int ret;
270 269
271 if (root == extent_root) { 270 if (root == extent_root) {
272 t = find_tree_block(root, blocknr); 271 t = find_tree_block(root, blocknr);
273 radix_tree_tag_set(&root->fs_info->cache_radix, blocknr, 272 pin_down_block(root, blocknr, CTREE_EXTENT_PENDING_DEL);
274 CTREE_EXTENT_PENDING_DEL);
275 return 0; 273 return 0;
276 } 274 }
277 ret = __free_extent(trans, root, blocknr, num_blocks, pin); 275 if (pin) {
278 pending_ret = run_pending(trans, root->fs_info->extent_root); 276 ret = pin_down_block(root, blocknr, CTREE_EXTENT_PINNED);
277 BUG_ON(ret);
278 }
279 ret = __free_extent(trans, root, blocknr, num_blocks);
280 pending_ret = del_pending_extents(trans, root->fs_info->extent_root);
279 return ret ? ret : pending_ret; 281 return ret ? ret : pending_ret;
280} 282}
281 283
@@ -296,14 +298,16 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
296 int ret; 298 int ret;
297 u64 hole_size = 0; 299 u64 hole_size = 0;
298 int slot = 0; 300 int slot = 0;
299 u64 last_block; 301 u64 last_block = 0;
300 u64 test_block; 302 u64 test_block;
301 int start_found; 303 int start_found;
302 struct btrfs_leaf *l; 304 struct btrfs_leaf *l;
303 struct btrfs_root * root = orig_root->fs_info->extent_root; 305 struct btrfs_root * root = orig_root->fs_info->extent_root;
304 int total_needed = num_blocks; 306 int total_needed = num_blocks;
307 int level;
305 308
306 total_needed += (btrfs_header_level(&root->node->node.header) + 1) * 3; 309 level = btrfs_header_level(btrfs_buffer_header(root->node));
310 total_needed += (level + 1) * 3;
307 if (root->fs_info->last_insert.objectid > search_start) 311 if (root->fs_info->last_insert.objectid > search_start)
308 search_start = root->fs_info->last_insert.objectid; 312 search_start = root->fs_info->last_insert.objectid;
309 313
@@ -323,7 +327,7 @@ check_failed:
323 path.slots[0]--; 327 path.slots[0]--;
324 328
325 while (1) { 329 while (1) {
326 l = &path.nodes[0]->leaf; 330 l = btrfs_buffer_leaf(path.nodes[0]);
327 slot = path.slots[0]; 331 slot = path.slots[0];
328 if (slot >= btrfs_header_nritems(&l->header)) { 332 if (slot >= btrfs_header_nritems(&l->header)) {
329 ret = btrfs_next_leaf(root, &path); 333 ret = btrfs_next_leaf(root, &path);
@@ -429,7 +433,7 @@ static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root
429 sizeof(extent_item)); 433 sizeof(extent_item));
430 434
431 finish_current_insert(trans, extent_root); 435 finish_current_insert(trans, extent_root);
432 pending_ret = run_pending(trans, extent_root); 436 pending_ret = del_pending_extents(trans, extent_root);
433 if (ret) 437 if (ret)
434 return ret; 438 return ret;
435 if (pending_ret) 439 if (pending_ret)
@@ -441,16 +445,15 @@ static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root
441 * helper function to allocate a block for a given tree 445 * helper function to allocate a block for a given tree
442 * returns the tree buffer or NULL. 446 * returns the tree buffer or NULL.
443 */ 447 */
444struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, 448struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
445 struct btrfs_root *root) 449 struct btrfs_root *root)
446{ 450{
447 struct btrfs_key ins; 451 struct btrfs_key ins;
448 int ret; 452 int ret;
449 struct btrfs_buffer *buf; 453 struct buffer_head *buf;
450 454
451 ret = alloc_extent(trans, root, 1, 0, (unsigned long)-1, 455 ret = alloc_extent(trans, root, 1, 0, (unsigned long)-1,
452 btrfs_header_parentid(&root->node->node.header), 456 btrfs_header_parentid(btrfs_buffer_header(root->node)), &ins);
453 &ins);
454 if (ret) { 457 if (ret) {
455 BUG(); 458 BUG();
456 return NULL; 459 return NULL;
@@ -467,13 +470,13 @@ struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
467static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root 470static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
468 *root, struct btrfs_path *path, int *level) 471 *root, struct btrfs_path *path, int *level)
469{ 472{
470 struct btrfs_buffer *next; 473 struct buffer_head *next;
471 struct btrfs_buffer *cur; 474 struct buffer_head *cur;
472 u64 blocknr; 475 u64 blocknr;
473 int ret; 476 int ret;
474 u32 refs; 477 u32 refs;
475 478
476 ret = lookup_block_ref(trans, root, path->nodes[*level]->blocknr, 479 ret = lookup_block_ref(trans, root, path->nodes[*level]->b_blocknr,
477 &refs); 480 &refs);
478 BUG_ON(ret); 481 BUG_ON(ret);
479 if (refs > 1) 482 if (refs > 1)
@@ -484,9 +487,10 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
484 while(*level > 0) { 487 while(*level > 0) {
485 cur = path->nodes[*level]; 488 cur = path->nodes[*level];
486 if (path->slots[*level] >= 489 if (path->slots[*level] >=
487 btrfs_header_nritems(&cur->node.header)) 490 btrfs_header_nritems(btrfs_buffer_header(cur)))
488 break; 491 break;
489 blocknr = btrfs_node_blockptr(&cur->node, path->slots[*level]); 492 blocknr = btrfs_node_blockptr(btrfs_buffer_node(cur),
493 path->slots[*level]);
490 ret = lookup_block_ref(trans, root, blocknr, &refs); 494 ret = lookup_block_ref(trans, root, blocknr, &refs);
491 if (refs != 1 || *level == 1) { 495 if (refs != 1 || *level == 1) {
492 path->slots[*level]++; 496 path->slots[*level]++;
@@ -499,12 +503,12 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
499 if (path->nodes[*level-1]) 503 if (path->nodes[*level-1])
500 btrfs_block_release(root, path->nodes[*level-1]); 504 btrfs_block_release(root, path->nodes[*level-1]);
501 path->nodes[*level-1] = next; 505 path->nodes[*level-1] = next;
502 *level = btrfs_header_level(&next->node.header); 506 *level = btrfs_header_level(btrfs_buffer_header(next));
503 path->slots[*level] = 0; 507 path->slots[*level] = 0;
504 } 508 }
505out: 509out:
506 ret = btrfs_free_extent(trans, root, path->nodes[*level]->blocknr, 1, 510 ret = btrfs_free_extent(trans, root, path->nodes[*level]->b_blocknr,
507 1); 511 1, 1);
508 btrfs_block_release(root, path->nodes[*level]); 512 btrfs_block_release(root, path->nodes[*level]);
509 path->nodes[*level] = NULL; 513 path->nodes[*level] = NULL;
510 *level += 1; 514 *level += 1;
@@ -525,14 +529,14 @@ static int walk_up_tree(struct btrfs_trans_handle *trans, struct btrfs_root
525 int ret; 529 int ret;
526 for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) { 530 for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) {
527 slot = path->slots[i]; 531 slot = path->slots[i];
528 if (slot < 532 if (slot < btrfs_header_nritems(
529 btrfs_header_nritems(&path->nodes[i]->node.header)- 1) { 533 btrfs_buffer_header(path->nodes[i])) - 1) {
530 path->slots[i]++; 534 path->slots[i]++;
531 *level = i; 535 *level = i;
532 return 0; 536 return 0;
533 } else { 537 } else {
534 ret = btrfs_free_extent(trans, root, 538 ret = btrfs_free_extent(trans, root,
535 path->nodes[*level]->blocknr, 539 path->nodes[*level]->b_blocknr,
536 1, 1); 540 1, 1);
537 btrfs_block_release(root, path->nodes[*level]); 541 btrfs_block_release(root, path->nodes[*level]);
538 path->nodes[*level] = NULL; 542 path->nodes[*level] = NULL;
@@ -549,7 +553,7 @@ static int walk_up_tree(struct btrfs_trans_handle *trans, struct btrfs_root
549 * decremented. 553 * decremented.
550 */ 554 */
551int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root 555int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
552 *root, struct btrfs_buffer *snap) 556 *root, struct buffer_head *snap)
553{ 557{
554 int ret = 0; 558 int ret = 0;
555 int wret; 559 int wret;
@@ -560,7 +564,7 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
560 564
561 btrfs_init_path(&path); 565 btrfs_init_path(&path);
562 566
563 level = btrfs_header_level(&snap->node.header); 567 level = btrfs_header_level(btrfs_buffer_header(snap));
564 orig_level = level; 568 orig_level = level;
565 path.nodes[level] = snap; 569 path.nodes[level] = snap;
566 path.slots[level] = 0; 570 path.slots[level] = 0;
diff --git a/fs/btrfs/hash.c b/fs/btrfs/hash.c
index 6c2a71a46c7d..22519b8e0cf2 100644
--- a/fs/btrfs/hash.c
+++ b/fs/btrfs/hash.c
@@ -10,6 +10,7 @@
10 * License. 10 * License.
11 */ 11 */
12 12
13#include <linux/types.h>
13#define DELTA 0x9E3779B9 14#define DELTA 0x9E3779B9
14 15
15static void TEA_transform(__u32 buf[2], __u32 const in[]) 16static void TEA_transform(__u32 buf[2], __u32 const in[])
@@ -63,6 +64,14 @@ int btrfs_name_hash(const char *name, int len, u64 *hash_result)
63 const char *p; 64 const char *p;
64 __u32 in[8], buf[2]; 65 __u32 in[8], buf[2];
65 66
67 if (len == 1 && *name == '.') {
68 *hash_result = 1;
69 return 0;
70 } else if (len == 2 && name[0] == '.' && name[1] == '.') {
71 *hash_result = 2;
72 return 0;
73 }
74
66 /* Initialize the default seed for the hash checksum functions */ 75 /* Initialize the default seed for the hash checksum functions */
67 buf[0] = 0x67452301; 76 buf[0] = 0x67452301;
68 buf[1] = 0xefcdab89; 77 buf[1] = 0xefcdab89;
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index c7fda3bf7b21..c45aec258bd5 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -15,7 +15,7 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
15 int ret; 15 int ret;
16 u64 hole_size = 0; 16 u64 hole_size = 0;
17 int slot = 0; 17 int slot = 0;
18 u64 last_ino; 18 u64 last_ino = 0;
19 int start_found; 19 int start_found;
20 struct btrfs_leaf *l; 20 struct btrfs_leaf *l;
21 struct btrfs_root *root = fs_root->fs_info->inode_root; 21 struct btrfs_root *root = fs_root->fs_info->inode_root;
@@ -40,7 +40,7 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
40 path.slots[0]--; 40 path.slots[0]--;
41 41
42 while (1) { 42 while (1) {
43 l = &path.nodes[0]->leaf; 43 l = btrfs_buffer_leaf(path.nodes[0]);
44 slot = path.slots[0]; 44 slot = path.slots[0];
45 if (slot >= btrfs_header_nritems(&l->header)) { 45 if (slot >= btrfs_header_nritems(&l->header)) {
46 ret = btrfs_next_leaf(root, &path); 46 ret = btrfs_next_leaf(root, &path);
@@ -105,8 +105,8 @@ int btrfs_insert_inode_map(struct btrfs_trans_handle *trans,
105 if (ret) 105 if (ret)
106 goto out; 106 goto out;
107 107
108 inode_item = btrfs_item_ptr(&path.nodes[0]->leaf, path.slots[0], 108 inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]),
109 struct btrfs_inode_map_item); 109 path.slots[0], struct btrfs_inode_map_item);
110 btrfs_cpu_key_to_disk(&inode_item->key, location); 110 btrfs_cpu_key_to_disk(&inode_item->key, location);
111out: 111out:
112 btrfs_release_path(inode_root, &path); 112 btrfs_release_path(inode_root, &path);
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c
index aa2d3fac8804..c8ee938c1251 100644
--- a/fs/btrfs/print-tree.c
+++ b/fs/btrfs/print-tree.c
@@ -17,7 +17,6 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
17 printk("leaf %Lu total ptrs %d free space %d\n", 17 printk("leaf %Lu total ptrs %d free space %d\n",
18 btrfs_header_blocknr(&l->header), nr, 18 btrfs_header_blocknr(&l->header), nr,
19 btrfs_leaf_free_space(root, l)); 19 btrfs_leaf_free_space(root, l));
20 fflush(stdout);
21 for (i = 0 ; i < nr ; i++) { 20 for (i = 0 ; i < nr ; i++) {
22 item = l->items + i; 21 item = l->items + i;
23 type = btrfs_disk_key_type(&item->key); 22 type = btrfs_disk_key_type(&item->key);
@@ -67,10 +66,10 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l)
67 btrfs_leaf_data(l) + btrfs_item_offset(item)); 66 btrfs_leaf_data(l) + btrfs_item_offset(item));
68 break; 67 break;
69 }; 68 };
70 fflush(stdout);
71 } 69 }
72} 70}
73void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t) 71
72void btrfs_print_tree(struct btrfs_root *root, struct buffer_head *t)
74{ 73{
75 int i; 74 int i;
76 u32 nr; 75 u32 nr;
@@ -78,16 +77,16 @@ void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t)
78 77
79 if (!t) 78 if (!t)
80 return; 79 return;
81 c = &t->node; 80 c = btrfs_buffer_node(t);
82 nr = btrfs_header_nritems(&c->header); 81 nr = btrfs_header_nritems(&c->header);
83 if (btrfs_is_leaf(c)) { 82 if (btrfs_is_leaf(c)) {
84 btrfs_print_leaf(root, (struct btrfs_leaf *)c); 83 btrfs_print_leaf(root, (struct btrfs_leaf *)c);
85 return; 84 return;
86 } 85 }
87 printk("node %Lu level %d total ptrs %d free spc %u\n", t->blocknr, 86 printk("node %Lu level %d total ptrs %d free spc %u\n",
88 btrfs_header_level(&c->header), nr, 87 btrfs_header_blocknr(&c->header),
89 (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr); 88 btrfs_header_level(&c->header), nr,
90 fflush(stdout); 89 (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr);
91 for (i = 0; i < nr; i++) { 90 for (i = 0; i < nr; i++) {
92 printk("\tkey %d (%Lu %u %Lu) block %Lu\n", 91 printk("\tkey %d (%Lu %u %Lu) block %Lu\n",
93 i, 92 i,
@@ -95,12 +94,11 @@ void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t)
95 c->ptrs[i].key.flags, 94 c->ptrs[i].key.flags,
96 c->ptrs[i].key.offset, 95 c->ptrs[i].key.offset,
97 btrfs_node_blockptr(c, i)); 96 btrfs_node_blockptr(c, i));
98 fflush(stdout);
99 } 97 }
100 for (i = 0; i < nr; i++) { 98 for (i = 0; i < nr; i++) {
101 struct btrfs_buffer *next_buf = read_tree_block(root, 99 struct buffer_head *next_buf = read_tree_block(root,
102 btrfs_node_blockptr(c, i)); 100 btrfs_node_blockptr(c, i));
103 struct btrfs_node *next = &next_buf->node; 101 struct btrfs_node *next = btrfs_buffer_node(next_buf);
104 if (btrfs_is_leaf(next) && 102 if (btrfs_is_leaf(next) &&
105 btrfs_header_level(&c->header) != 1) 103 btrfs_header_level(&c->header) != 1)
106 BUG(); 104 BUG();
diff --git a/fs/btrfs/print-tree.h b/fs/btrfs/print-tree.h
index 0882ca904eca..396041a05cfa 100644
--- a/fs/btrfs/print-tree.h
+++ b/fs/btrfs/print-tree.h
@@ -1,5 +1,5 @@
1#ifndef __PRINT_TREE_ 1#ifndef __PRINT_TREE_
2#define __PRINT_TREE_ 2#define __PRINT_TREE_
3void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l); 3void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l);
4void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t); 4void btrfs_print_tree(struct btrfs_root *root, struct buffer_head *t);
5#endif 5#endif
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 52c83be4b307..a4554c007ef7 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -21,7 +21,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
21 if (ret < 0) 21 if (ret < 0)
22 goto out; 22 goto out;
23 BUG_ON(ret == 0); 23 BUG_ON(ret == 0);
24 l = &path.nodes[0]->leaf; 24 l = btrfs_buffer_leaf(path.nodes[0]);
25 BUG_ON(path.slots[0] == 0); 25 BUG_ON(path.slots[0] == 0);
26 slot = path.slots[0] - 1; 26 slot = path.slots[0] - 1;
27 if (btrfs_disk_key_objectid(&l->items[slot].key) != objectid) { 27 if (btrfs_disk_key_objectid(&l->items[slot].key) != objectid) {
@@ -51,7 +51,7 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
51 if (ret < 0) 51 if (ret < 0)
52 goto out; 52 goto out;
53 BUG_ON(ret != 0); 53 BUG_ON(ret != 0);
54 l = &path.nodes[0]->leaf; 54 l = btrfs_buffer_leaf(path.nodes[0]);
55 slot = path.slots[0]; 55 slot = path.slots[0];
56 memcpy(btrfs_item_ptr(l, slot, struct btrfs_root_item), item, 56 memcpy(btrfs_item_ptr(l, slot, struct btrfs_root_item), item,
57 sizeof(*item)); 57 sizeof(*item));
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 4ae76044aeab..ccc056aad692 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1,4 +1,5 @@
1#include <linux/module.h> 1#include <linux/module.h>
2#include <linux/buffer_head.h>
2#include <linux/fs.h> 3#include <linux/fs.h>
3#include <linux/pagemap.h> 4#include <linux/pagemap.h>
4#include <linux/highmem.h> 5#include <linux/highmem.h>
@@ -8,13 +9,18 @@
8#include <linux/smp_lock.h> 9#include <linux/smp_lock.h>
9#include <linux/backing-dev.h> 10#include <linux/backing-dev.h>
10#include "ctree.h" 11#include "ctree.h"
12#include "disk-io.h"
11 13
12#define BTRFS_SUPER_MAGIC 0x9123682E 14#define BTRFS_SUPER_MAGIC 0x9123682E
15
16static struct inode_operations btrfs_dir_inode_operations;
17static struct super_operations btrfs_super_ops;
18static struct file_operations btrfs_dir_file_operations;
19
13#if 0 20#if 0
14/* some random number */ 21/* some random number */
15 22
16static struct super_operations ramfs_ops; 23static struct super_operations ramfs_ops;
17static struct inode_operations ramfs_dir_inode_operations;
18 24
19static struct backing_dev_info ramfs_backing_dev_info = { 25static struct backing_dev_info ramfs_backing_dev_info = {
20 .ra_pages = 0, /* No readahead */ 26 .ra_pages = 0, /* No readahead */
@@ -129,46 +135,243 @@ static struct inode_operations ramfs_dir_inode_operations = {
129}; 135};
130#endif 136#endif
131 137
132struct inode *btrfs_get_inode(struct super_block *sb, int mode, dev_t dev) 138static void btrfs_read_locked_inode(struct inode *inode)
133{ 139{
134 struct inode * inode = new_inode(sb); 140 struct btrfs_path path;
141 struct btrfs_inode_item *inode_item;
142 struct btrfs_root *root = btrfs_sb(inode->i_sb);
143 int ret;
144printk("read locked inode %lu\n", inode->i_ino);
145 btrfs_init_path(&path);
146 ret = btrfs_lookup_inode(NULL, root, &path, inode->i_ino, 0);
147 if (ret) {
148 make_bad_inode(inode);
149 return;
150 }
151 inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]),
152 path.slots[0],
153 struct btrfs_inode_item);
135 154
136 if (inode) { 155printk("found locked inode %lu\n", inode->i_ino);
137 inode->i_mode = mode; 156 inode->i_mode = btrfs_inode_mode(inode_item);
138 inode->i_uid = current->fsuid; 157 inode->i_nlink = btrfs_inode_nlink(inode_item);
139 inode->i_gid = current->fsgid; 158 inode->i_uid = btrfs_inode_uid(inode_item);
140 inode->i_blocks = 0; 159 inode->i_gid = btrfs_inode_gid(inode_item);
141 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 160 inode->i_size = btrfs_inode_size(inode_item);
161 inode->i_atime.tv_sec = btrfs_timespec_sec(&inode_item->atime);
162 inode->i_atime.tv_nsec = btrfs_timespec_nsec(&inode_item->atime);
163 inode->i_mtime.tv_sec = btrfs_timespec_sec(&inode_item->mtime);
164 inode->i_mtime.tv_nsec = btrfs_timespec_nsec(&inode_item->mtime);
165 inode->i_ctime.tv_sec = btrfs_timespec_sec(&inode_item->ctime);
166 inode->i_ctime.tv_nsec = btrfs_timespec_nsec(&inode_item->ctime);
167 inode->i_blocks = btrfs_inode_nblocks(inode_item);
168 inode->i_generation = btrfs_inode_generation(inode_item);
169printk("about to release\n");
170 btrfs_release_path(root, &path);
171 switch (inode->i_mode & S_IFMT) {
172#if 0
173 default:
174 init_special_inode(inode, inode->i_mode,
175 btrfs_inode_rdev(inode_item));
176 break;
177#endif
178 case S_IFREG:
179printk("inode %lu now a file\n", inode->i_ino);
180 break;
181 case S_IFDIR:
182printk("inode %lu now a directory\n", inode->i_ino);
183 inode->i_op = &btrfs_dir_inode_operations;
184 inode->i_fop = &btrfs_dir_file_operations;
185 break;
186 case S_IFLNK:
187printk("inode %lu now a link\n", inode->i_ino);
188 // inode->i_op = &page_symlink_inode_operations;
189 break;
142 } 190 }
143 return inode; 191printk("returning!\n");
192 return;
144} 193}
145 194
146static struct super_operations btrfs_ops = { 195static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
147 .statfs = simple_statfs, 196 ino_t *ino)
148 .drop_inode = generic_delete_inode, 197{
149}; 198 const char *name = dentry->d_name.name;
199 int namelen = dentry->d_name.len;
200 struct btrfs_dir_item *di;
201 struct btrfs_path path;
202 struct btrfs_root *root = btrfs_sb(dir->i_sb);
203 int ret;
204
205 btrfs_init_path(&path);
206 ret = btrfs_lookup_dir_item(NULL, root, &path, dir->i_ino, name,
207 namelen, 0);
208 if (ret) {
209 *ino = 0;
210 goto out;
211 }
212 di = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0],
213 struct btrfs_dir_item);
214 *ino = btrfs_dir_objectid(di);
215out:
216 btrfs_release_path(root, &path);
217 return ret;
218}
219
220static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
221 struct nameidata *nd)
222{
223 struct inode * inode;
224 ino_t ino;
225 int ret;
226
227 if (dentry->d_name.len > BTRFS_NAME_LEN)
228 return ERR_PTR(-ENAMETOOLONG);
229
230 ret = btrfs_inode_by_name(dir, dentry, &ino);
231 if (ret < 0)
232 return ERR_PTR(ret);
233 inode = NULL;
234 if (ino) {
235printk("lookup on %.*s returns %lu\n", dentry->d_name.len, dentry->d_name.name, ino);
236 inode = iget(dir->i_sb, ino);
237 if (!inode)
238 return ERR_PTR(-EACCES);
239 }
240 return d_splice_alias(inode, dentry);
241}
242
243static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
244{
245 struct inode *inode = filp->f_path.dentry->d_inode;
246 struct btrfs_root *root = btrfs_sb(inode->i_sb);
247 struct btrfs_item *item;
248 struct btrfs_dir_item *di;
249 struct btrfs_key key;
250 struct btrfs_path path;
251 int ret;
252 u32 nritems;
253 struct btrfs_leaf *leaf;
254 int slot;
255 int advance;
256 unsigned char d_type = DT_UNKNOWN;
257 int over;
258
259 key.objectid = inode->i_ino;
260printk("readdir on dir %Lu pos %Lu\n", key.objectid, filp->f_pos);
261 key.flags = 0;
262 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
263 key.offset = filp->f_pos;
264 btrfs_init_path(&path);
265 ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
266 if (ret < 0) {
267 goto err;
268 }
269printk("first ret %d\n", ret);
270 advance = filp->f_pos > 0 && ret != 0;
271 while(1) {
272 leaf = btrfs_buffer_leaf(path.nodes[0]);
273 nritems = btrfs_header_nritems(&leaf->header);
274 slot = path.slots[0];
275printk("leaf %Lu nritems %lu slot %d\n", path.nodes[0]->b_blocknr, nritems, slot);
276 if (advance) {
277printk("advancing!\n");
278 if (slot == nritems -1) {
279 ret = btrfs_next_leaf(root, &path);
280 if (ret)
281 break;
282 leaf = btrfs_buffer_leaf(path.nodes[0]);
283 nritems = btrfs_header_nritems(&leaf->header);
284 slot = path.slots[0];
285printk("2leaf %Lu nritems %lu slot %d\n", path.nodes[0]->b_blocknr, nritems, slot);
286 } else {
287 slot++;
288 path.slots[0]++;
289 }
290 }
291 advance = 1;
292 item = leaf->items + slot;
293printk("item key %Lu %u %Lu\n", btrfs_disk_key_objectid(&item->key),
294 btrfs_disk_key_flags(&item->key), btrfs_disk_key_offset(&item->key));
295 if (btrfs_disk_key_objectid(&item->key) != key.objectid)
296 break;
297 if (btrfs_disk_key_type(&item->key) != BTRFS_DIR_ITEM_KEY)
298 continue;
299 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
300printk("filldir name %.*s, objectid %Lu\n", btrfs_dir_name_len(di),
301 (const char *)(di + 1), btrfs_dir_objectid(di));
302 over = filldir(dirent, (const char *)(di + 1),
303 btrfs_dir_name_len(di),
304 btrfs_disk_key_offset(&item->key),
305 btrfs_dir_objectid(di), d_type);
306 if (over)
307 break;
308 filp->f_pos = btrfs_disk_key_offset(&item->key) + 1;
309 }
310printk("filldir all done\n");
311 ret = 0;
312err:
313 btrfs_release_path(root, &path);
314 return ret;
315}
316
317static void btrfs_put_super (struct super_block * sb)
318{
319 struct btrfs_root *root = btrfs_sb(sb);
320 int ret;
321
322 ret = close_ctree(root);
323 if (ret) {
324 printk("close ctree returns %d\n", ret);
325 }
326 sb->s_fs_info = NULL;
327}
150 328
151static int btrfs_fill_super(struct super_block * sb, void * data, int silent) 329static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
152{ 330{
153 struct inode * inode; 331 struct inode * inode;
154 struct dentry * root; 332 struct dentry * root_dentry;
333 struct btrfs_super_block *disk_super;
334 struct buffer_head *bh;
335 struct btrfs_root *root;
155 336
156 sb->s_maxbytes = MAX_LFS_FILESIZE; 337 sb->s_maxbytes = MAX_LFS_FILESIZE;
157 sb->s_blocksize = PAGE_CACHE_SIZE; 338 sb->s_blocksize = PAGE_CACHE_SIZE;
158 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 339 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
159 sb->s_magic = BTRFS_SUPER_MAGIC; 340 sb->s_magic = BTRFS_SUPER_MAGIC;
160 sb->s_op = &btrfs_ops; 341 sb->s_op = &btrfs_super_ops;
161 sb->s_time_gran = 1; 342 sb->s_time_gran = 1;
162 inode = btrfs_get_inode(sb, S_IFDIR | 0755, 0); 343
344 bh = sb_bread(sb, BTRFS_SUPER_INFO_OFFSET / sb->s_blocksize);
345 if (!bh) {
346 printk("btrfs: unable to read on disk super\n");
347 return -EIO;
348 }
349 disk_super = (struct btrfs_super_block *)bh->b_data;
350 root = open_ctree(sb, bh, disk_super);
351 sb->s_fs_info = root;
352 if (!root) {
353 printk("btrfs: open_ctree failed\n");
354 return -EIO;
355 }
356 printk("read in super total blocks %Lu root %Lu\n",
357 btrfs_super_total_blocks(disk_super),
358 btrfs_super_root_dir(disk_super));
359
360 inode = iget_locked(sb, btrfs_super_root_dir(disk_super));
163 if (!inode) 361 if (!inode)
164 return -ENOMEM; 362 return -ENOMEM;
363 if (inode->i_state & I_NEW) {
364 btrfs_read_locked_inode(inode);
365 unlock_new_inode(inode);
366 }
165 367
166 root = d_alloc_root(inode); 368 root_dentry = d_alloc_root(inode);
167 if (!root) { 369 if (!root_dentry) {
168 iput(inode); 370 iput(inode);
169 return -ENOMEM; 371 return -ENOMEM;
170 } 372 }
171 sb->s_root = root; 373 sb->s_root = root_dentry;
374
172 return 0; 375 return 0;
173} 376}
174 377
@@ -187,6 +390,24 @@ static struct file_system_type btrfs_fs_type = {
187 .fs_flags = FS_REQUIRES_DEV, 390 .fs_flags = FS_REQUIRES_DEV,
188}; 391};
189 392
393static struct super_operations btrfs_super_ops = {
394 .statfs = simple_statfs,
395 .drop_inode = generic_delete_inode,
396 .put_super = btrfs_put_super,
397 .read_inode = btrfs_read_locked_inode,
398};
399
400static struct inode_operations btrfs_dir_inode_operations = {
401 .lookup = btrfs_lookup,
402};
403
404static struct file_operations btrfs_dir_file_operations = {
405 .llseek = generic_file_llseek,
406 .read = generic_read_dir,
407 .readdir = btrfs_readdir,
408};
409
410
190static int __init init_btrfs_fs(void) 411static int __init init_btrfs_fs(void)
191{ 412{
192 printk("btrfs loaded!\n"); 413 printk("btrfs loaded!\n");
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index 3adb6e69fe43..9ab27b7491c5 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -10,7 +10,7 @@ struct btrfs_trans_handle {
10static inline struct btrfs_trans_handle * 10static inline struct btrfs_trans_handle *
11btrfs_start_transaction(struct btrfs_root *root, int num_blocks) 11btrfs_start_transaction(struct btrfs_root *root, int num_blocks)
12{ 12{
13 struct btrfs_trans_handle *h = malloc(sizeof(*h)); 13 struct btrfs_trans_handle *h = kmalloc(sizeof(*h), GFP_NOFS);
14 h->transid = root->root_key.offset; 14 h->transid = root->root_key.offset;
15 h->blocks_reserved = num_blocks; 15 h->blocks_reserved = num_blocks;
16 h->blocks_used = 0; 16 h->blocks_used = 0;
@@ -21,7 +21,7 @@ static inline void btrfs_free_transaction(struct btrfs_root *root,
21 struct btrfs_trans_handle *handle) 21 struct btrfs_trans_handle *handle)
22{ 22{
23 memset(handle, 0, sizeof(*handle)); 23 memset(handle, 0, sizeof(*handle));
24 free(handle); 24 kfree(handle);
25} 25}
26 26
27#endif 27#endif