diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-10-15 16:14:19 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:56 -0400 |
commit | 5f39d397dfbe140a14edecd4e73c34ce23c4f9ee (patch) | |
tree | 280561e4b68d573590557dd27df656869eed8023 /fs/btrfs/extent-tree.c | |
parent | 50b78c24d594e6985f36a9a8d8e2fb74e1664e90 (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.c | 294 |
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); |
434 | out: | 433 | out: |
435 | btrfs_free_path(path); | 434 | btrfs_free_path(path); |
436 | return 0; | 435 | return 0; |
@@ -439,16 +438,16 @@ out: | |||
439 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, | 438 | int 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 | ||
445 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 445 | int 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); |
541 | fail: | 543 | fail: |
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 | |||
795 | static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) | 797 | static 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 | */ |
1244 | struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 1248 | struct 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 | ||
1272 | static int drop_leaf_ref(struct btrfs_trans_handle *trans, | 1281 | static 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 | ||
1308 | static void reada_walk_down(struct btrfs_root *root, | 1316 | static 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, | |||
1337 | static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | 1345 | static 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 | } |
1412 | out: | 1420 | out: |
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, |