aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-10-15 16:14:19 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:56 -0400
commit5f39d397dfbe140a14edecd4e73c34ce23c4f9ee (patch)
tree280561e4b68d573590557dd27df656869eed8023 /fs/btrfs/extent-tree.c
parent50b78c24d594e6985f36a9a8d8e2fb74e1664e90 (diff)
Btrfs: Create extent_buffer interface for large blocksizes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c294
1 files changed, 150 insertions, 144 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index f261a8326cdf..089c41cbca74 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -33,7 +33,7 @@ static int cache_block_group(struct btrfs_root *root,
33 struct btrfs_path *path; 33 struct btrfs_path *path;
34 int ret; 34 int ret;
35 struct btrfs_key key; 35 struct btrfs_key key;
36 struct btrfs_leaf *leaf; 36 struct extent_buffer *leaf;
37 struct radix_tree_root *extent_radix; 37 struct radix_tree_root *extent_radix;
38 int slot; 38 int slot;
39 u64 i; 39 u64 i;
@@ -56,7 +56,6 @@ static int cache_block_group(struct btrfs_root *root,
56 path->reada = 2; 56 path->reada = 2;
57 first_free = block_group->key.objectid; 57 first_free = block_group->key.objectid;
58 key.objectid = block_group->key.objectid; 58 key.objectid = block_group->key.objectid;
59 key.flags = 0;
60 key.offset = 0; 59 key.offset = 0;
61 60
62 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 61 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
@@ -69,9 +68,9 @@ static int cache_block_group(struct btrfs_root *root,
69 path->slots[0]--; 68 path->slots[0]--;
70 69
71 while(1) { 70 while(1) {
72 leaf = btrfs_buffer_leaf(path->nodes[0]); 71 leaf = path->nodes[0];
73 slot = path->slots[0]; 72 slot = path->slots[0];
74 if (slot >= btrfs_header_nritems(&leaf->header)) { 73 if (slot >= btrfs_header_nritems(leaf)) {
75 ret = btrfs_next_leaf(root, path); 74 ret = btrfs_next_leaf(root, path);
76 if (ret < 0) 75 if (ret < 0)
77 goto err; 76 goto err;
@@ -82,7 +81,7 @@ static int cache_block_group(struct btrfs_root *root,
82 } 81 }
83 } 82 }
84 83
85 btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key); 84 btrfs_item_key_to_cpu(leaf, &key, slot);
86 if (key.objectid < block_group->key.objectid) { 85 if (key.objectid < block_group->key.objectid) {
87 if (key.objectid + key.offset > first_free) 86 if (key.objectid + key.offset > first_free)
88 first_free = key.objectid + key.offset; 87 first_free = key.objectid + key.offset;
@@ -116,8 +115,7 @@ next:
116 hole_size = block_group->key.objectid + 115 hole_size = block_group->key.objectid +
117 block_group->key.offset - last; 116 block_group->key.offset - last;
118 for (i = 0; i < hole_size; i++) { 117 for (i = 0; i < hole_size; i++) {
119 set_radix_bit(extent_radix, 118 set_radix_bit(extent_radix, last + i);
120 last + i);
121 } 119 }
122 } 120 }
123 block_group->cached = 1; 121 block_group->cached = 1;
@@ -366,7 +364,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
366 struct btrfs_path *path; 364 struct btrfs_path *path;
367 int ret; 365 int ret;
368 struct btrfs_key key; 366 struct btrfs_key key;
369 struct btrfs_leaf *l; 367 struct extent_buffer *l;
370 struct btrfs_extent_item *item; 368 struct btrfs_extent_item *item;
371 u32 refs; 369 u32 refs;
372 370
@@ -375,7 +373,6 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
375 return -ENOMEM; 373 return -ENOMEM;
376 374
377 key.objectid = blocknr; 375 key.objectid = blocknr;
378 key.flags = 0;
379 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 376 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
380 key.offset = num_blocks; 377 key.offset = num_blocks;
381 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, 378 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path,
@@ -386,10 +383,10 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
386 BUG(); 383 BUG();
387 } 384 }
388 BUG_ON(ret != 0); 385 BUG_ON(ret != 0);
389 l = btrfs_buffer_leaf(path->nodes[0]); 386 l = path->nodes[0];
390 item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); 387 item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item);
391 refs = btrfs_extent_refs(item); 388 refs = btrfs_extent_refs(l, item);
392 btrfs_set_extent_refs(item, refs + 1); 389 btrfs_set_extent_refs(l, item, refs + 1);
393 btrfs_mark_buffer_dirty(path->nodes[0]); 390 btrfs_mark_buffer_dirty(path->nodes[0]);
394 391
395 btrfs_release_path(root->fs_info->extent_root, path); 392 btrfs_release_path(root->fs_info->extent_root, path);
@@ -414,23 +411,25 @@ static int lookup_extent_ref(struct btrfs_trans_handle *trans,
414 struct btrfs_path *path; 411 struct btrfs_path *path;
415 int ret; 412 int ret;
416 struct btrfs_key key; 413 struct btrfs_key key;
417 struct btrfs_leaf *l; 414 struct extent_buffer *l;
418 struct btrfs_extent_item *item; 415 struct btrfs_extent_item *item;
419 416
420 path = btrfs_alloc_path(); 417 path = btrfs_alloc_path();
421 key.objectid = blocknr; 418 key.objectid = blocknr;
422 key.offset = num_blocks; 419 key.offset = num_blocks;
423 key.flags = 0;
424 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 420 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
425 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, 421 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path,
426 0, 0); 422 0, 0);
427 if (ret < 0) 423 if (ret < 0)
428 goto out; 424 goto out;
429 if (ret != 0) 425 if (ret != 0) {
426 btrfs_print_leaf(root, path->nodes[0]);
427 printk("failed to find block number %Lu\n", blocknr);
430 BUG(); 428 BUG();
431 l = btrfs_buffer_leaf(path->nodes[0]); 429 }
430 l = path->nodes[0];
432 item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); 431 item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item);
433 *refs = btrfs_extent_refs(item); 432 *refs = btrfs_extent_refs(l, item);
434out: 433out:
435 btrfs_free_path(path); 434 btrfs_free_path(path);
436 return 0; 435 return 0;
@@ -439,16 +438,16 @@ out:
439int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, 438int btrfs_inc_root_ref(struct btrfs_trans_handle *trans,
440 struct btrfs_root *root) 439 struct btrfs_root *root)
441{ 440{
442 return btrfs_inc_extent_ref(trans, root, bh_blocknr(root->node), 1); 441 return btrfs_inc_extent_ref(trans, root,
442 extent_buffer_blocknr(root->node), 1);
443} 443}
444 444
445int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, 445int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
446 struct buffer_head *buf) 446 struct extent_buffer *buf)
447{ 447{
448 u64 blocknr; 448 u64 blocknr;
449 struct btrfs_node *buf_node; 449 u32 nritems;
450 struct btrfs_leaf *buf_leaf; 450 struct btrfs_key key;
451 struct btrfs_disk_key *key;
452 struct btrfs_file_extent_item *fi; 451 struct btrfs_file_extent_item *fi;
453 int i; 452 int i;
454 int leaf; 453 int leaf;
@@ -458,31 +457,31 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
458 457
459 if (!root->ref_cows) 458 if (!root->ref_cows)
460 return 0; 459 return 0;
461 buf_node = btrfs_buffer_node(buf); 460
462 leaf = btrfs_is_leaf(buf_node); 461 leaf = btrfs_is_leaf(buf);
463 buf_leaf = btrfs_buffer_leaf(buf); 462 nritems = btrfs_header_nritems(buf);
464 for (i = 0; i < btrfs_header_nritems(&buf_node->header); i++) { 463 for (i = 0; i < nritems; i++) {
465 if (leaf) { 464 if (leaf) {
466 u64 disk_blocknr; 465 u64 disk_blocknr;
467 key = &buf_leaf->items[i].key; 466 btrfs_item_key_to_cpu(buf, &key, i);
468 if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY) 467 if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY)
469 continue; 468 continue;
470 fi = btrfs_item_ptr(buf_leaf, i, 469 fi = btrfs_item_ptr(buf, i,
471 struct btrfs_file_extent_item); 470 struct btrfs_file_extent_item);
472 if (btrfs_file_extent_type(fi) == 471 if (btrfs_file_extent_type(buf, fi) ==
473 BTRFS_FILE_EXTENT_INLINE) 472 BTRFS_FILE_EXTENT_INLINE)
474 continue; 473 continue;
475 disk_blocknr = btrfs_file_extent_disk_blocknr(fi); 474 disk_blocknr = btrfs_file_extent_disk_blocknr(buf, fi);
476 if (disk_blocknr == 0) 475 if (disk_blocknr == 0)
477 continue; 476 continue;
478 ret = btrfs_inc_extent_ref(trans, root, disk_blocknr, 477 ret = btrfs_inc_extent_ref(trans, root, disk_blocknr,
479 btrfs_file_extent_disk_num_blocks(fi)); 478 btrfs_file_extent_disk_num_blocks(buf, fi));
480 if (ret) { 479 if (ret) {
481 faili = i; 480 faili = i;
482 goto fail; 481 goto fail;
483 } 482 }
484 } else { 483 } else {
485 blocknr = btrfs_node_blockptr(buf_node, i); 484 blocknr = btrfs_node_blockptr(buf, i);
486 ret = btrfs_inc_extent_ref(trans, root, blocknr, 1); 485 ret = btrfs_inc_extent_ref(trans, root, blocknr, 1);
487 if (ret) { 486 if (ret) {
488 faili = i; 487 faili = i;
@@ -496,22 +495,23 @@ fail:
496 for (i =0; i < faili; i++) { 495 for (i =0; i < faili; i++) {
497 if (leaf) { 496 if (leaf) {
498 u64 disk_blocknr; 497 u64 disk_blocknr;
499 key = &buf_leaf->items[i].key; 498 btrfs_item_key_to_cpu(buf, &key, i);
500 if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY) 499 if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY)
501 continue; 500 continue;
502 fi = btrfs_item_ptr(buf_leaf, i, 501 fi = btrfs_item_ptr(buf, i,
503 struct btrfs_file_extent_item); 502 struct btrfs_file_extent_item);
504 if (btrfs_file_extent_type(fi) == 503 if (btrfs_file_extent_type(buf, fi) ==
505 BTRFS_FILE_EXTENT_INLINE) 504 BTRFS_FILE_EXTENT_INLINE)
506 continue; 505 continue;
507 disk_blocknr = btrfs_file_extent_disk_blocknr(fi); 506 disk_blocknr = btrfs_file_extent_disk_blocknr(buf, fi);
508 if (disk_blocknr == 0) 507 if (disk_blocknr == 0)
509 continue; 508 continue;
510 err = btrfs_free_extent(trans, root, disk_blocknr, 509 err = btrfs_free_extent(trans, root, disk_blocknr,
511 btrfs_file_extent_disk_num_blocks(fi), 0); 510 btrfs_file_extent_disk_num_blocks(buf,
511 fi), 0);
512 BUG_ON(err); 512 BUG_ON(err);
513 } else { 513 } else {
514 blocknr = btrfs_node_blockptr(buf_node, i); 514 blocknr = btrfs_node_blockptr(buf, i);
515 err = btrfs_free_extent(trans, root, blocknr, 1, 0); 515 err = btrfs_free_extent(trans, root, blocknr, 1, 0);
516 BUG_ON(err); 516 BUG_ON(err);
517 } 517 }
@@ -527,16 +527,18 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans,
527 int ret; 527 int ret;
528 int pending_ret; 528 int pending_ret;
529 struct btrfs_root *extent_root = root->fs_info->extent_root; 529 struct btrfs_root *extent_root = root->fs_info->extent_root;
530 struct btrfs_block_group_item *bi; 530 unsigned long bi;
531 struct extent_buffer *leaf;
531 532
532 ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); 533 ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1);
533 if (ret < 0) 534 if (ret < 0)
534 goto fail; 535 goto fail;
535 BUG_ON(ret); 536 BUG_ON(ret);
536 bi = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], 537
537 struct btrfs_block_group_item); 538 leaf = path->nodes[0];
538 memcpy(bi, &cache->item, sizeof(*bi)); 539 bi = btrfs_item_ptr_offset(leaf, path->slots[0]);
539 btrfs_mark_buffer_dirty(path->nodes[0]); 540 write_extent_buffer(leaf, &cache->item, bi, sizeof(cache->item));
541 btrfs_mark_buffer_dirty(leaf);
540 btrfs_release_path(extent_root, path); 542 btrfs_release_path(extent_root, path);
541fail: 543fail:
542 finish_current_insert(trans, extent_root); 544 finish_current_insert(trans, extent_root);
@@ -768,11 +770,11 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
768 unsigned long gang[8]; 770 unsigned long gang[8];
769 struct btrfs_fs_info *info = extent_root->fs_info; 771 struct btrfs_fs_info *info = extent_root->fs_info;
770 772
771 btrfs_set_extent_refs(&extent_item, 1); 773 btrfs_set_stack_extent_refs(&extent_item, 1);
772 ins.offset = 1; 774 ins.offset = 1;
773 ins.flags = 0;
774 btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY); 775 btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY);
775 btrfs_set_extent_owner(&extent_item, extent_root->root_key.objectid); 776 btrfs_set_stack_extent_owner(&extent_item,
777 extent_root->root_key.objectid);
776 778
777 while(1) { 779 while(1) {
778 ret = find_first_radix_bit(&info->extent_ins_radix, gang, 0, 780 ret = find_first_radix_bit(&info->extent_ins_radix, gang, 0,
@@ -795,23 +797,20 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
795static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) 797static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending)
796{ 798{
797 int err; 799 int err;
798 struct btrfs_header *header; 800 struct extent_buffer *buf;
799 struct buffer_head *bh;
800 801
801 if (!pending) { 802 if (!pending) {
802 bh = btrfs_find_tree_block(root, blocknr); 803 buf = btrfs_find_tree_block(root, blocknr);
803 if (bh) { 804 if (buf) {
804 if (buffer_uptodate(bh)) { 805 if (btrfs_buffer_uptodate(buf)) {
805 u64 transid = 806 u64 transid =
806 root->fs_info->running_transaction->transid; 807 root->fs_info->running_transaction->transid;
807 header = btrfs_buffer_header(bh); 808 if (btrfs_header_generation(buf) == transid) {
808 if (btrfs_header_generation(header) == 809 free_extent_buffer(buf);
809 transid) {
810 btrfs_block_release(root, bh);
811 return 0; 810 return 0;
812 } 811 }
813 } 812 }
814 btrfs_block_release(root, bh); 813 free_extent_buffer(buf);
815 } 814 }
816 err = set_radix_bit(&root->fs_info->pinned_radix, blocknr); 815 err = set_radix_bit(&root->fs_info->pinned_radix, blocknr);
817 if (!err) { 816 if (!err) {
@@ -839,12 +838,12 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
839 struct btrfs_key key; 838 struct btrfs_key key;
840 struct btrfs_fs_info *info = root->fs_info; 839 struct btrfs_fs_info *info = root->fs_info;
841 struct btrfs_root *extent_root = info->extent_root; 840 struct btrfs_root *extent_root = info->extent_root;
841 struct extent_buffer *leaf;
842 int ret; 842 int ret;
843 struct btrfs_extent_item *ei; 843 struct btrfs_extent_item *ei;
844 u32 refs; 844 u32 refs;
845 845
846 key.objectid = blocknr; 846 key.objectid = blocknr;
847 key.flags = 0;
848 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 847 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
849 key.offset = num_blocks; 848 key.offset = num_blocks;
850 849
@@ -856,12 +855,16 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
856 if (ret < 0) 855 if (ret < 0)
857 return ret; 856 return ret;
858 BUG_ON(ret); 857 BUG_ON(ret);
859 ei = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]), path->slots[0], 858
859 leaf = path->nodes[0];
860 ei = btrfs_item_ptr(leaf, path->slots[0],
860 struct btrfs_extent_item); 861 struct btrfs_extent_item);
861 BUG_ON(ei->refs == 0); 862 refs = btrfs_extent_refs(leaf, ei);
862 refs = btrfs_extent_refs(ei) - 1; 863 BUG_ON(refs == 0);
863 btrfs_set_extent_refs(ei, refs); 864 refs -= 1;
864 btrfs_mark_buffer_dirty(path->nodes[0]); 865 btrfs_set_extent_refs(leaf, ei, refs);
866 btrfs_mark_buffer_dirty(leaf);
867
865 if (refs == 0) { 868 if (refs == 0) {
866 u64 super_blocks_used, root_blocks_used; 869 u64 super_blocks_used, root_blocks_used;
867 870
@@ -876,8 +879,8 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
876 super_blocks_used - num_blocks); 879 super_blocks_used - num_blocks);
877 880
878 /* block accounting for root item */ 881 /* block accounting for root item */
879 root_blocks_used = btrfs_root_blocks_used(&root->root_item); 882 root_blocks_used = btrfs_root_used(&root->root_item);
880 btrfs_set_root_blocks_used(&root->root_item, 883 btrfs_set_root_used(&root->root_item,
881 root_blocks_used - num_blocks); 884 root_blocks_used - num_blocks);
882 885
883 ret = btrfs_del_item(trans, extent_root, path); 886 ret = btrfs_del_item(trans, extent_root, path);
@@ -984,7 +987,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
984 u64 test_block; 987 u64 test_block;
985 u64 orig_search_start = search_start; 988 u64 orig_search_start = search_start;
986 int start_found; 989 int start_found;
987 struct btrfs_leaf *l; 990 struct extent_buffer *l;
988 struct btrfs_root * root = orig_root->fs_info->extent_root; 991 struct btrfs_root * root = orig_root->fs_info->extent_root;
989 struct btrfs_fs_info *info = root->fs_info; 992 struct btrfs_fs_info *info = root->fs_info;
990 int total_needed = num_blocks; 993 int total_needed = num_blocks;
@@ -994,10 +997,10 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
994 int wrapped = 0; 997 int wrapped = 0;
995 998
996 WARN_ON(num_blocks < 1); 999 WARN_ON(num_blocks < 1);
997 ins->flags = 0;
998 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); 1000 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
999 1001
1000 level = btrfs_header_level(btrfs_buffer_header(root->node)); 1002 level = btrfs_header_level(root->node);
1003
1001 if (search_end == (u64)-1) 1004 if (search_end == (u64)-1)
1002 search_end = btrfs_super_total_blocks(&info->super_copy); 1005 search_end = btrfs_super_total_blocks(&info->super_copy);
1003 if (hint_block) { 1006 if (hint_block) {
@@ -1034,8 +1037,9 @@ check_failed:
1034 path->slots[0]--; 1037 path->slots[0]--;
1035 } 1038 }
1036 1039
1037 l = btrfs_buffer_leaf(path->nodes[0]); 1040 l = path->nodes[0];
1038 btrfs_disk_key_to_cpu(&key, &l->items[path->slots[0]].key); 1041 btrfs_item_key_to_cpu(l, &key, path->slots[0]);
1042
1039 /* 1043 /*
1040 * a rare case, go back one key if we hit a block group item 1044 * a rare case, go back one key if we hit a block group item
1041 * instead of an extent item 1045 * instead of an extent item
@@ -1055,9 +1059,9 @@ check_failed:
1055 } 1059 }
1056 1060
1057 while (1) { 1061 while (1) {
1058 l = btrfs_buffer_leaf(path->nodes[0]); 1062 l = path->nodes[0];
1059 slot = path->slots[0]; 1063 slot = path->slots[0];
1060 if (slot >= btrfs_header_nritems(&l->header)) { 1064 if (slot >= btrfs_header_nritems(l)) {
1061 ret = btrfs_next_leaf(root, path); 1065 ret = btrfs_next_leaf(root, path);
1062 if (ret == 0) 1066 if (ret == 0)
1063 continue; 1067 continue;
@@ -1075,7 +1079,7 @@ check_failed:
1075 goto check_pending; 1079 goto check_pending;
1076 } 1080 }
1077 1081
1078 btrfs_disk_key_to_cpu(&key, &l->items[slot].key); 1082 btrfs_item_key_to_cpu(l, &key, slot);
1079 if (key.objectid >= search_start && key.objectid > last_block && 1083 if (key.objectid >= search_start && key.objectid > last_block &&
1080 start_found) { 1084 start_found) {
1081 if (last_block < search_start) 1085 if (last_block < search_start)
@@ -1183,8 +1187,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1183 struct btrfs_root *extent_root = info->extent_root; 1187 struct btrfs_root *extent_root = info->extent_root;
1184 struct btrfs_extent_item extent_item; 1188 struct btrfs_extent_item extent_item;
1185 1189
1186 btrfs_set_extent_refs(&extent_item, 1); 1190 btrfs_set_stack_extent_refs(&extent_item, 1);
1187 btrfs_set_extent_owner(&extent_item, owner); 1191 btrfs_set_stack_extent_owner(&extent_item, owner);
1188 1192
1189 WARN_ON(num_blocks < 1); 1193 WARN_ON(num_blocks < 1);
1190 ret = find_free_extent(trans, root, num_blocks, empty_size, 1194 ret = find_free_extent(trans, root, num_blocks, empty_size,
@@ -1201,8 +1205,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1201 num_blocks); 1205 num_blocks);
1202 1206
1203 /* block accounting for root item */ 1207 /* block accounting for root item */
1204 root_blocks_used = btrfs_root_blocks_used(&root->root_item); 1208 root_blocks_used = btrfs_root_used(&root->root_item);
1205 btrfs_set_root_blocks_used(&root->root_item, root_blocks_used + 1209 btrfs_set_root_used(&root->root_item, root_blocks_used +
1206 num_blocks); 1210 num_blocks);
1207 1211
1208 if (root == extent_root) { 1212 if (root == extent_root) {
@@ -1241,13 +1245,13 @@ update_block:
1241 * helper function to allocate a block for a given tree 1245 * helper function to allocate a block for a given tree
1242 * returns the tree buffer or NULL. 1246 * returns the tree buffer or NULL.
1243 */ 1247 */
1244struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, 1248struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
1245 struct btrfs_root *root, u64 hint, 1249 struct btrfs_root *root, u64 hint,
1246 u64 empty_size) 1250 u64 empty_size)
1247{ 1251{
1248 struct btrfs_key ins; 1252 struct btrfs_key ins;
1249 int ret; 1253 int ret;
1250 struct buffer_head *buf; 1254 struct extent_buffer *buf;
1251 1255
1252 ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, 1256 ret = btrfs_alloc_extent(trans, root, root->root_key.objectid,
1253 1, empty_size, hint, (u64)-1, &ins, 0); 1257 1, empty_size, hint, (u64)-1, &ins, 0);
@@ -1260,53 +1264,57 @@ struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
1260 btrfs_free_extent(trans, root, ins.objectid, 1, 0); 1264 btrfs_free_extent(trans, root, ins.objectid, 1, 0);
1261 return ERR_PTR(-ENOMEM); 1265 return ERR_PTR(-ENOMEM);
1262 } 1266 }
1263 WARN_ON(buffer_dirty(buf)); 1267 btrfs_set_buffer_uptodate(buf);
1264 set_buffer_uptodate(buf); 1268 set_extent_dirty(&trans->transaction->dirty_pages, buf->start,
1269 buf->start + buf->len - 1, GFP_NOFS);
1270 /*
1265 set_buffer_checked(buf); 1271 set_buffer_checked(buf);
1266 set_buffer_defrag(buf); 1272 set_buffer_defrag(buf);
1267 set_radix_bit(&trans->transaction->dirty_pages, buf->b_page->index); 1273 */
1274 /* FIXME!!!!!!!!!!!!!!!!
1275 set_radix_bit(&trans->transaction->dirty_pages, buf->pages[0]->index);
1276 */
1268 trans->blocks_used++; 1277 trans->blocks_used++;
1269 return buf; 1278 return buf;
1270} 1279}
1271 1280
1272static int drop_leaf_ref(struct btrfs_trans_handle *trans, 1281static int drop_leaf_ref(struct btrfs_trans_handle *trans,
1273 struct btrfs_root *root, struct buffer_head *cur) 1282 struct btrfs_root *root, struct extent_buffer *leaf)
1274{ 1283{
1275 struct btrfs_disk_key *key; 1284 struct btrfs_key key;
1276 struct btrfs_leaf *leaf;
1277 struct btrfs_file_extent_item *fi; 1285 struct btrfs_file_extent_item *fi;
1278 int i; 1286 int i;
1279 int nritems; 1287 int nritems;
1280 int ret; 1288 int ret;
1281 1289
1282 BUG_ON(!btrfs_is_leaf(btrfs_buffer_node(cur))); 1290 BUG_ON(!btrfs_is_leaf(leaf));
1283 leaf = btrfs_buffer_leaf(cur); 1291 nritems = btrfs_header_nritems(leaf);
1284 nritems = btrfs_header_nritems(&leaf->header);
1285 for (i = 0; i < nritems; i++) { 1292 for (i = 0; i < nritems; i++) {
1286 u64 disk_blocknr; 1293 u64 disk_blocknr;
1287 key = &leaf->items[i].key; 1294
1288 if (btrfs_disk_key_type(key) != BTRFS_EXTENT_DATA_KEY) 1295 btrfs_item_key_to_cpu(leaf, &key, i);
1296 if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY)
1289 continue; 1297 continue;
1290 fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); 1298 fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item);
1291 if (btrfs_file_extent_type(fi) == BTRFS_FILE_EXTENT_INLINE) 1299 if (btrfs_file_extent_type(leaf, fi) ==
1300 BTRFS_FILE_EXTENT_INLINE)
1292 continue; 1301 continue;
1293 /* 1302 /*
1294 * FIXME make sure to insert a trans record that 1303 * FIXME make sure to insert a trans record that
1295 * repeats the snapshot del on crash 1304 * repeats the snapshot del on crash
1296 */ 1305 */
1297 disk_blocknr = btrfs_file_extent_disk_blocknr(fi); 1306 disk_blocknr = btrfs_file_extent_disk_blocknr(leaf, fi);
1298 if (disk_blocknr == 0) 1307 if (disk_blocknr == 0)
1299 continue; 1308 continue;
1300 ret = btrfs_free_extent(trans, root, disk_blocknr, 1309 ret = btrfs_free_extent(trans, root, disk_blocknr,
1301 btrfs_file_extent_disk_num_blocks(fi), 1310 btrfs_file_extent_disk_num_blocks(leaf, fi), 0);
1302 0);
1303 BUG_ON(ret); 1311 BUG_ON(ret);
1304 } 1312 }
1305 return 0; 1313 return 0;
1306} 1314}
1307 1315
1308static void reada_walk_down(struct btrfs_root *root, 1316static void reada_walk_down(struct btrfs_root *root,
1309 struct btrfs_node *node) 1317 struct extent_buffer *node)
1310{ 1318{
1311 int i; 1319 int i;
1312 u32 nritems; 1320 u32 nritems;
@@ -1314,7 +1322,7 @@ static void reada_walk_down(struct btrfs_root *root,
1314 int ret; 1322 int ret;
1315 u32 refs; 1323 u32 refs;
1316 1324
1317 nritems = btrfs_header_nritems(&node->header); 1325 nritems = btrfs_header_nritems(node);
1318 for (i = 0; i < nritems; i++) { 1326 for (i = 0; i < nritems; i++) {
1319 blocknr = btrfs_node_blockptr(node, i); 1327 blocknr = btrfs_node_blockptr(node, i);
1320 ret = lookup_extent_ref(NULL, root, blocknr, 1, &refs); 1328 ret = lookup_extent_ref(NULL, root, blocknr, 1, &refs);
@@ -1337,16 +1345,17 @@ static void reada_walk_down(struct btrfs_root *root,
1337static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root 1345static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
1338 *root, struct btrfs_path *path, int *level) 1346 *root, struct btrfs_path *path, int *level)
1339{ 1347{
1340 struct buffer_head *next; 1348 struct extent_buffer *next;
1341 struct buffer_head *cur; 1349 struct extent_buffer *cur;
1342 u64 blocknr; 1350 u64 blocknr;
1343 int ret; 1351 int ret;
1344 u32 refs; 1352 u32 refs;
1345 1353
1346 WARN_ON(*level < 0); 1354 WARN_ON(*level < 0);
1347 WARN_ON(*level >= BTRFS_MAX_LEVEL); 1355 WARN_ON(*level >= BTRFS_MAX_LEVEL);
1348 ret = lookup_extent_ref(trans, root, bh_blocknr(path->nodes[*level]), 1356 ret = lookup_extent_ref(trans, root,
1349 1, &refs); 1357 extent_buffer_blocknr(path->nodes[*level]),
1358 1, &refs);
1350 BUG_ON(ret); 1359 BUG_ON(ret);
1351 if (refs > 1) 1360 if (refs > 1)
1352 goto out; 1361 goto out;
@@ -1360,21 +1369,20 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
1360 cur = path->nodes[*level]; 1369 cur = path->nodes[*level];
1361 1370
1362 if (*level > 0 && path->slots[*level] == 0) 1371 if (*level > 0 && path->slots[*level] == 0)
1363 reada_walk_down(root, btrfs_buffer_node(cur)); 1372 reada_walk_down(root, cur);
1364 1373
1365 if (btrfs_header_level(btrfs_buffer_header(cur)) != *level) 1374 if (btrfs_header_level(cur) != *level)
1366 WARN_ON(1); 1375 WARN_ON(1);
1367 1376
1368 if (path->slots[*level] >= 1377 if (path->slots[*level] >=
1369 btrfs_header_nritems(btrfs_buffer_header(cur))) 1378 btrfs_header_nritems(cur))
1370 break; 1379 break;
1371 if (*level == 0) { 1380 if (*level == 0) {
1372 ret = drop_leaf_ref(trans, root, cur); 1381 ret = drop_leaf_ref(trans, root, cur);
1373 BUG_ON(ret); 1382 BUG_ON(ret);
1374 break; 1383 break;
1375 } 1384 }
1376 blocknr = btrfs_node_blockptr(btrfs_buffer_node(cur), 1385 blocknr = btrfs_node_blockptr(cur, path->slots[*level]);
1377 path->slots[*level]);
1378 ret = lookup_extent_ref(trans, root, blocknr, 1, &refs); 1386 ret = lookup_extent_ref(trans, root, blocknr, 1, &refs);
1379 BUG_ON(ret); 1387 BUG_ON(ret);
1380 if (refs != 1) { 1388 if (refs != 1) {
@@ -1384,8 +1392,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
1384 continue; 1392 continue;
1385 } 1393 }
1386 next = btrfs_find_tree_block(root, blocknr); 1394 next = btrfs_find_tree_block(root, blocknr);
1387 if (!next || !buffer_uptodate(next)) { 1395 if (!next || !btrfs_buffer_uptodate(next)) {
1388 brelse(next); 1396 free_extent_buffer(next);
1389 mutex_unlock(&root->fs_info->fs_mutex); 1397 mutex_unlock(&root->fs_info->fs_mutex);
1390 next = read_tree_block(root, blocknr); 1398 next = read_tree_block(root, blocknr);
1391 mutex_lock(&root->fs_info->fs_mutex); 1399 mutex_lock(&root->fs_info->fs_mutex);
@@ -1395,7 +1403,7 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
1395 BUG_ON(ret); 1403 BUG_ON(ret);
1396 if (refs != 1) { 1404 if (refs != 1) {
1397 path->slots[*level]++; 1405 path->slots[*level]++;
1398 brelse(next); 1406 free_extent_buffer(next);
1399 ret = btrfs_free_extent(trans, root, 1407 ret = btrfs_free_extent(trans, root,
1400 blocknr, 1, 1); 1408 blocknr, 1, 1);
1401 BUG_ON(ret); 1409 BUG_ON(ret);
@@ -1404,17 +1412,17 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root
1404 } 1412 }
1405 WARN_ON(*level <= 0); 1413 WARN_ON(*level <= 0);
1406 if (path->nodes[*level-1]) 1414 if (path->nodes[*level-1])
1407 btrfs_block_release(root, path->nodes[*level-1]); 1415 free_extent_buffer(path->nodes[*level-1]);
1408 path->nodes[*level-1] = next; 1416 path->nodes[*level-1] = next;
1409 *level = btrfs_header_level(btrfs_buffer_header(next)); 1417 *level = btrfs_header_level(next);
1410 path->slots[*level] = 0; 1418 path->slots[*level] = 0;
1411 } 1419 }
1412out: 1420out:
1413 WARN_ON(*level < 0); 1421 WARN_ON(*level < 0);
1414 WARN_ON(*level >= BTRFS_MAX_LEVEL); 1422 WARN_ON(*level >= BTRFS_MAX_LEVEL);
1415 ret = btrfs_free_extent(trans, root, 1423 ret = btrfs_free_extent(trans, root,
1416 bh_blocknr(path->nodes[*level]), 1, 1); 1424 extent_buffer_blocknr(path->nodes[*level]), 1, 1);
1417 btrfs_block_release(root, path->nodes[*level]); 1425 free_extent_buffer(path->nodes[*level]);
1418 path->nodes[*level] = NULL; 1426 path->nodes[*level] = NULL;
1419 *level += 1; 1427 *level += 1;
1420 BUG_ON(ret); 1428 BUG_ON(ret);
@@ -1436,24 +1444,24 @@ static int walk_up_tree(struct btrfs_trans_handle *trans, struct btrfs_root
1436 1444
1437 for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) { 1445 for(i = *level; i < BTRFS_MAX_LEVEL - 1 && path->nodes[i]; i++) {
1438 slot = path->slots[i]; 1446 slot = path->slots[i];
1439 if (slot < btrfs_header_nritems( 1447 if (slot < btrfs_header_nritems(path->nodes[i]) - 1) {
1440 btrfs_buffer_header(path->nodes[i])) - 1) { 1448 struct extent_buffer *node;
1441 struct btrfs_node *node; 1449 struct btrfs_disk_key disk_key;
1442 node = btrfs_buffer_node(path->nodes[i]); 1450 node = path->nodes[i];
1443 path->slots[i]++; 1451 path->slots[i]++;
1444 *level = i; 1452 *level = i;
1445 WARN_ON(*level == 0); 1453 WARN_ON(*level == 0);
1454 btrfs_node_key(node, &disk_key, path->slots[i]);
1446 memcpy(&root_item->drop_progress, 1455 memcpy(&root_item->drop_progress,
1447 &node->ptrs[path->slots[i]].key, 1456 &disk_key, sizeof(disk_key));
1448 sizeof(root_item->drop_progress));
1449 root_item->drop_level = i; 1457 root_item->drop_level = i;
1450 return 0; 1458 return 0;
1451 } else { 1459 } else {
1452 ret = btrfs_free_extent(trans, root, 1460 ret = btrfs_free_extent(trans, root,
1453 bh_blocknr(path->nodes[*level]), 1461 extent_buffer_blocknr(path->nodes[*level]),
1454 1, 1); 1462 1, 1);
1455 BUG_ON(ret); 1463 BUG_ON(ret);
1456 btrfs_block_release(root, path->nodes[*level]); 1464 free_extent_buffer(path->nodes[*level]);
1457 path->nodes[*level] = NULL; 1465 path->nodes[*level] = NULL;
1458 *level = i + 1; 1466 *level = i + 1;
1459 } 1467 }
@@ -1480,15 +1488,15 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
1480 path = btrfs_alloc_path(); 1488 path = btrfs_alloc_path();
1481 BUG_ON(!path); 1489 BUG_ON(!path);
1482 1490
1483 level = btrfs_header_level(btrfs_buffer_header(root->node)); 1491 level = btrfs_header_level(root->node);
1484 orig_level = level; 1492 orig_level = level;
1485 if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) { 1493 if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) {
1486 path->nodes[level] = root->node; 1494 path->nodes[level] = root->node;
1487 path->slots[level] = 0; 1495 path->slots[level] = 0;
1488 } else { 1496 } else {
1489 struct btrfs_key key; 1497 struct btrfs_key key;
1490 struct btrfs_disk_key *found_key; 1498 struct btrfs_disk_key found_key;
1491 struct btrfs_node *node; 1499 struct extent_buffer *node;
1492 1500
1493 btrfs_disk_key_to_cpu(&key, &root_item->drop_progress); 1501 btrfs_disk_key_to_cpu(&key, &root_item->drop_progress);
1494 level = root_item->drop_level; 1502 level = root_item->drop_level;
@@ -1498,10 +1506,10 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
1498 ret = wret; 1506 ret = wret;
1499 goto out; 1507 goto out;
1500 } 1508 }
1501 node = btrfs_buffer_node(path->nodes[level]); 1509 node = path->nodes[level];
1502 found_key = &node->ptrs[path->slots[level]].key; 1510 btrfs_node_key(node, &found_key, path->slots[level]);
1503 WARN_ON(memcmp(found_key, &root_item->drop_progress, 1511 WARN_ON(memcmp(&found_key, &root_item->drop_progress,
1504 sizeof(*found_key))); 1512 sizeof(found_key)));
1505 } 1513 }
1506 while(1) { 1514 while(1) {
1507 wret = walk_down_tree(trans, root, path, &level); 1515 wret = walk_down_tree(trans, root, path, &level);
@@ -1516,12 +1524,12 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
1516 if (wret < 0) 1524 if (wret < 0)
1517 ret = wret; 1525 ret = wret;
1518 ret = -EAGAIN; 1526 ret = -EAGAIN;
1519 get_bh(root->node); 1527 extent_buffer_get(root->node);
1520 break; 1528 break;
1521 } 1529 }
1522 for (i = 0; i <= orig_level; i++) { 1530 for (i = 0; i <= orig_level; i++) {
1523 if (path->nodes[i]) { 1531 if (path->nodes[i]) {
1524 btrfs_block_release(root, path->nodes[i]); 1532 free_extent_buffer(path->nodes[i]);
1525 path->nodes[i] = 0; 1533 path->nodes[i] = 0;
1526 } 1534 }
1527 } 1535 }
@@ -1581,13 +1589,12 @@ int btrfs_read_block_groups(struct btrfs_root *root)
1581 struct btrfs_path *path; 1589 struct btrfs_path *path;
1582 int ret; 1590 int ret;
1583 int err = 0; 1591 int err = 0;
1584 struct btrfs_block_group_item *bi;
1585 struct btrfs_block_group_cache *cache; 1592 struct btrfs_block_group_cache *cache;
1586 struct btrfs_fs_info *info = root->fs_info; 1593 struct btrfs_fs_info *info = root->fs_info;
1587 struct radix_tree_root *radix; 1594 struct radix_tree_root *radix;
1588 struct btrfs_key key; 1595 struct btrfs_key key;
1589 struct btrfs_key found_key; 1596 struct btrfs_key found_key;
1590 struct btrfs_leaf *leaf; 1597 struct extent_buffer *leaf;
1591 u64 group_size_blocks; 1598 u64 group_size_blocks;
1592 u64 used; 1599 u64 used;
1593 1600
@@ -1596,7 +1603,6 @@ int btrfs_read_block_groups(struct btrfs_root *root)
1596 root = info->extent_root; 1603 root = info->extent_root;
1597 key.objectid = 0; 1604 key.objectid = 0;
1598 key.offset = group_size_blocks; 1605 key.offset = group_size_blocks;
1599 key.flags = 0;
1600 btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY); 1606 btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY);
1601 1607
1602 path = btrfs_alloc_path(); 1608 path = btrfs_alloc_path();
@@ -1610,18 +1616,18 @@ int btrfs_read_block_groups(struct btrfs_root *root)
1610 err = ret; 1616 err = ret;
1611 break; 1617 break;
1612 } 1618 }
1613 leaf = btrfs_buffer_leaf(path->nodes[0]); 1619 leaf = path->nodes[0];
1614 btrfs_disk_key_to_cpu(&found_key, 1620 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
1615 &leaf->items[path->slots[0]].key);
1616 cache = kmalloc(sizeof(*cache), GFP_NOFS); 1621 cache = kmalloc(sizeof(*cache), GFP_NOFS);
1617 if (!cache) { 1622 if (!cache) {
1618 err = -1; 1623 err = -1;
1619 break; 1624 break;
1620 } 1625 }
1621 1626
1622 bi = btrfs_item_ptr(leaf, path->slots[0], 1627 read_extent_buffer(leaf, &cache->item,
1623 struct btrfs_block_group_item); 1628 btrfs_item_ptr_offset(leaf, path->slots[0]),
1624 if (bi->flags & BTRFS_BLOCK_GROUP_DATA) { 1629 sizeof(cache->item));
1630 if (cache->item.flags & BTRFS_BLOCK_GROUP_DATA) {
1625 radix = &info->block_group_data_radix; 1631 radix = &info->block_group_data_radix;
1626 cache->data = 1; 1632 cache->data = 1;
1627 } else { 1633 } else {
@@ -1629,7 +1635,6 @@ int btrfs_read_block_groups(struct btrfs_root *root)
1629 cache->data = 0; 1635 cache->data = 0;
1630 } 1636 }
1631 1637
1632 memcpy(&cache->item, bi, sizeof(*bi));
1633 memcpy(&cache->key, &found_key, sizeof(found_key)); 1638 memcpy(&cache->key, &found_key, sizeof(found_key));
1634 cache->last_alloc = cache->key.objectid; 1639 cache->last_alloc = cache->key.objectid;
1635 cache->first_free = cache->key.objectid; 1640 cache->first_free = cache->key.objectid;
@@ -1640,11 +1645,12 @@ int btrfs_read_block_groups(struct btrfs_root *root)
1640 1645
1641 key.objectid = found_key.objectid + found_key.offset; 1646 key.objectid = found_key.objectid + found_key.offset;
1642 btrfs_release_path(root, path); 1647 btrfs_release_path(root, path);
1648
1643 ret = radix_tree_insert(radix, found_key.objectid + 1649 ret = radix_tree_insert(radix, found_key.objectid +
1644 found_key.offset - 1, 1650 found_key.offset - 1,
1645 (void *)cache); 1651 (void *)cache);
1646 BUG_ON(ret); 1652 BUG_ON(ret);
1647 used = btrfs_block_group_used(bi); 1653 used = btrfs_block_group_used(&cache->item);
1648 if (used < div_factor(key.offset, 8)) { 1654 if (used < div_factor(key.offset, 8)) {
1649 radix_tree_tag_set(radix, found_key.objectid + 1655 radix_tree_tag_set(radix, found_key.objectid +
1650 found_key.offset - 1, 1656 found_key.offset - 1,