diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-10-15 16:15:53 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:56 -0400 |
commit | db94535db75e67fab12ccbb7f5ee548e33fed891 (patch) | |
tree | 1ad7dfc82b003294a94ee87d7329b24b902b369f /fs/btrfs/extent-tree.c | |
parent | 1a5bc167f6707542b79a55452075525620ed43f5 (diff) |
Btrfs: Allow tree blocks larger than the page size
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 | 285 |
1 files changed, 147 insertions, 138 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 477466d167a4..1be8f9f04a13 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -129,7 +129,7 @@ err: | |||
129 | 129 | ||
130 | struct btrfs_block_group_cache *btrfs_lookup_block_group(struct | 130 | struct btrfs_block_group_cache *btrfs_lookup_block_group(struct |
131 | btrfs_fs_info *info, | 131 | btrfs_fs_info *info, |
132 | u64 blocknr) | 132 | u64 bytenr) |
133 | { | 133 | { |
134 | struct extent_map_tree *block_group_cache; | 134 | struct extent_map_tree *block_group_cache; |
135 | struct btrfs_block_group_cache *block_group = NULL; | 135 | struct btrfs_block_group_cache *block_group = NULL; |
@@ -140,7 +140,7 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct | |||
140 | 140 | ||
141 | block_group_cache = &info->block_group_cache; | 141 | block_group_cache = &info->block_group_cache; |
142 | ret = find_first_extent_bit(block_group_cache, | 142 | ret = find_first_extent_bit(block_group_cache, |
143 | blocknr, &start, &end, | 143 | bytenr, &start, &end, |
144 | BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA); | 144 | BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA); |
145 | if (ret) { | 145 | if (ret) { |
146 | return NULL; | 146 | return NULL; |
@@ -152,7 +152,7 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct | |||
152 | block_group = (struct btrfs_block_group_cache *)ptr; | 152 | block_group = (struct btrfs_block_group_cache *)ptr; |
153 | 153 | ||
154 | 154 | ||
155 | if (block_group->key.objectid <= blocknr && blocknr <= | 155 | if (block_group->key.objectid <= bytenr && bytenr <= |
156 | block_group->key.objectid + block_group->key.offset) | 156 | block_group->key.objectid + block_group->key.offset) |
157 | return block_group; | 157 | return block_group; |
158 | 158 | ||
@@ -315,7 +315,7 @@ found: | |||
315 | 315 | ||
316 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 316 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
317 | struct btrfs_root *root, | 317 | struct btrfs_root *root, |
318 | u64 blocknr, u64 num_blocks) | 318 | u64 bytenr, u64 num_bytes) |
319 | { | 319 | { |
320 | struct btrfs_path *path; | 320 | struct btrfs_path *path; |
321 | int ret; | 321 | int ret; |
@@ -324,13 +324,14 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
324 | struct btrfs_extent_item *item; | 324 | struct btrfs_extent_item *item; |
325 | u32 refs; | 325 | u32 refs; |
326 | 326 | ||
327 | WARN_ON(num_bytes < root->sectorsize); | ||
327 | path = btrfs_alloc_path(); | 328 | path = btrfs_alloc_path(); |
328 | if (!path) | 329 | if (!path) |
329 | return -ENOMEM; | 330 | return -ENOMEM; |
330 | 331 | ||
331 | key.objectid = blocknr; | 332 | key.objectid = bytenr; |
332 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 333 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
333 | key.offset = num_blocks; | 334 | key.offset = num_bytes; |
334 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, | 335 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, |
335 | 0, 1); | 336 | 0, 1); |
336 | if (ret < 0) | 337 | if (ret < 0) |
@@ -361,8 +362,8 @@ int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | |||
361 | } | 362 | } |
362 | 363 | ||
363 | static int lookup_extent_ref(struct btrfs_trans_handle *trans, | 364 | static int lookup_extent_ref(struct btrfs_trans_handle *trans, |
364 | struct btrfs_root *root, u64 blocknr, | 365 | struct btrfs_root *root, u64 bytenr, |
365 | u64 num_blocks, u32 *refs) | 366 | u64 num_bytes, u32 *refs) |
366 | { | 367 | { |
367 | struct btrfs_path *path; | 368 | struct btrfs_path *path; |
368 | int ret; | 369 | int ret; |
@@ -370,9 +371,10 @@ static int lookup_extent_ref(struct btrfs_trans_handle *trans, | |||
370 | struct extent_buffer *l; | 371 | struct extent_buffer *l; |
371 | struct btrfs_extent_item *item; | 372 | struct btrfs_extent_item *item; |
372 | 373 | ||
374 | WARN_ON(num_bytes < root->sectorsize); | ||
373 | path = btrfs_alloc_path(); | 375 | path = btrfs_alloc_path(); |
374 | key.objectid = blocknr; | 376 | key.objectid = bytenr; |
375 | key.offset = num_blocks; | 377 | key.offset = num_bytes; |
376 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 378 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
377 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, | 379 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, |
378 | 0, 0); | 380 | 0, 0); |
@@ -380,7 +382,7 @@ static int lookup_extent_ref(struct btrfs_trans_handle *trans, | |||
380 | goto out; | 382 | goto out; |
381 | if (ret != 0) { | 383 | if (ret != 0) { |
382 | btrfs_print_leaf(root, path->nodes[0]); | 384 | btrfs_print_leaf(root, path->nodes[0]); |
383 | printk("failed to find block number %Lu\n", blocknr); | 385 | printk("failed to find block number %Lu\n", bytenr); |
384 | BUG(); | 386 | BUG(); |
385 | } | 387 | } |
386 | l = path->nodes[0]; | 388 | l = path->nodes[0]; |
@@ -394,19 +396,19 @@ out: | |||
394 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, | 396 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, |
395 | struct btrfs_root *root) | 397 | struct btrfs_root *root) |
396 | { | 398 | { |
397 | return btrfs_inc_extent_ref(trans, root, | 399 | return btrfs_inc_extent_ref(trans, root, root->node->start, |
398 | extent_buffer_blocknr(root->node), 1); | 400 | root->node->len); |
399 | } | 401 | } |
400 | 402 | ||
401 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 403 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
402 | struct extent_buffer *buf) | 404 | struct extent_buffer *buf) |
403 | { | 405 | { |
404 | u64 blocknr; | 406 | u64 bytenr; |
405 | u32 nritems; | 407 | u32 nritems; |
406 | struct btrfs_key key; | 408 | struct btrfs_key key; |
407 | struct btrfs_file_extent_item *fi; | 409 | struct btrfs_file_extent_item *fi; |
408 | int i; | 410 | int i; |
409 | int leaf; | 411 | int level; |
410 | int ret; | 412 | int ret; |
411 | int faili; | 413 | int faili; |
412 | int err; | 414 | int err; |
@@ -414,11 +416,11 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
414 | if (!root->ref_cows) | 416 | if (!root->ref_cows) |
415 | return 0; | 417 | return 0; |
416 | 418 | ||
417 | leaf = btrfs_is_leaf(buf); | 419 | level = btrfs_header_level(buf); |
418 | nritems = btrfs_header_nritems(buf); | 420 | nritems = btrfs_header_nritems(buf); |
419 | for (i = 0; i < nritems; i++) { | 421 | for (i = 0; i < nritems; i++) { |
420 | if (leaf) { | 422 | if (level == 0) { |
421 | u64 disk_blocknr; | 423 | u64 disk_bytenr; |
422 | btrfs_item_key_to_cpu(buf, &key, i); | 424 | btrfs_item_key_to_cpu(buf, &key, i); |
423 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 425 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
424 | continue; | 426 | continue; |
@@ -427,18 +429,19 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
427 | if (btrfs_file_extent_type(buf, fi) == | 429 | if (btrfs_file_extent_type(buf, fi) == |
428 | BTRFS_FILE_EXTENT_INLINE) | 430 | BTRFS_FILE_EXTENT_INLINE) |
429 | continue; | 431 | continue; |
430 | disk_blocknr = btrfs_file_extent_disk_blocknr(buf, fi); | 432 | disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); |
431 | if (disk_blocknr == 0) | 433 | if (disk_bytenr == 0) |
432 | continue; | 434 | continue; |
433 | ret = btrfs_inc_extent_ref(trans, root, disk_blocknr, | 435 | ret = btrfs_inc_extent_ref(trans, root, disk_bytenr, |
434 | btrfs_file_extent_disk_num_blocks(buf, fi)); | 436 | btrfs_file_extent_disk_num_bytes(buf, fi)); |
435 | if (ret) { | 437 | if (ret) { |
436 | faili = i; | 438 | faili = i; |
437 | goto fail; | 439 | goto fail; |
438 | } | 440 | } |
439 | } else { | 441 | } else { |
440 | blocknr = btrfs_node_blockptr(buf, i); | 442 | bytenr = btrfs_node_blockptr(buf, i); |
441 | ret = btrfs_inc_extent_ref(trans, root, blocknr, 1); | 443 | ret = btrfs_inc_extent_ref(trans, root, bytenr, |
444 | btrfs_level_size(root, level - 1)); | ||
442 | if (ret) { | 445 | if (ret) { |
443 | faili = i; | 446 | faili = i; |
444 | goto fail; | 447 | goto fail; |
@@ -449,8 +452,8 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
449 | fail: | 452 | fail: |
450 | WARN_ON(1); | 453 | WARN_ON(1); |
451 | for (i =0; i < faili; i++) { | 454 | for (i =0; i < faili; i++) { |
452 | if (leaf) { | 455 | if (level == 0) { |
453 | u64 disk_blocknr; | 456 | u64 disk_bytenr; |
454 | btrfs_item_key_to_cpu(buf, &key, i); | 457 | btrfs_item_key_to_cpu(buf, &key, i); |
455 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 458 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
456 | continue; | 459 | continue; |
@@ -459,16 +462,17 @@ fail: | |||
459 | if (btrfs_file_extent_type(buf, fi) == | 462 | if (btrfs_file_extent_type(buf, fi) == |
460 | BTRFS_FILE_EXTENT_INLINE) | 463 | BTRFS_FILE_EXTENT_INLINE) |
461 | continue; | 464 | continue; |
462 | disk_blocknr = btrfs_file_extent_disk_blocknr(buf, fi); | 465 | disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); |
463 | if (disk_blocknr == 0) | 466 | if (disk_bytenr == 0) |
464 | continue; | 467 | continue; |
465 | err = btrfs_free_extent(trans, root, disk_blocknr, | 468 | err = btrfs_free_extent(trans, root, disk_bytenr, |
466 | btrfs_file_extent_disk_num_blocks(buf, | 469 | btrfs_file_extent_disk_num_bytes(buf, |
467 | fi), 0); | 470 | fi), 0); |
468 | BUG_ON(err); | 471 | BUG_ON(err); |
469 | } else { | 472 | } else { |
470 | blocknr = btrfs_node_blockptr(buf, i); | 473 | bytenr = btrfs_node_blockptr(buf, i); |
471 | err = btrfs_free_extent(trans, root, blocknr, 1, 0); | 474 | err = btrfs_free_extent(trans, root, bytenr, |
475 | btrfs_level_size(root, level - 1), 0); | ||
472 | BUG_ON(err); | 476 | BUG_ON(err); |
473 | } | 477 | } |
474 | } | 478 | } |
@@ -558,31 +562,31 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | |||
558 | 562 | ||
559 | static int update_block_group(struct btrfs_trans_handle *trans, | 563 | static int update_block_group(struct btrfs_trans_handle *trans, |
560 | struct btrfs_root *root, | 564 | struct btrfs_root *root, |
561 | u64 blocknr, u64 num, int alloc, int mark_free, | 565 | u64 bytenr, u64 num_bytes, int alloc, |
562 | int data) | 566 | int mark_free, int data) |
563 | { | 567 | { |
564 | struct btrfs_block_group_cache *cache; | 568 | struct btrfs_block_group_cache *cache; |
565 | struct btrfs_fs_info *info = root->fs_info; | 569 | struct btrfs_fs_info *info = root->fs_info; |
566 | u64 total = num; | 570 | u64 total = num_bytes; |
567 | u64 old_val; | 571 | u64 old_val; |
568 | u64 block_in_group; | 572 | u64 byte_in_group; |
569 | u64 start; | 573 | u64 start; |
570 | u64 end; | 574 | u64 end; |
571 | 575 | ||
572 | while(total) { | 576 | while(total) { |
573 | cache = btrfs_lookup_block_group(info, blocknr); | 577 | cache = btrfs_lookup_block_group(info, bytenr); |
574 | if (!cache) { | 578 | if (!cache) { |
575 | return -1; | 579 | return -1; |
576 | } | 580 | } |
577 | block_in_group = blocknr - cache->key.objectid; | 581 | byte_in_group = bytenr - cache->key.objectid; |
578 | WARN_ON(block_in_group > cache->key.offset); | 582 | WARN_ON(byte_in_group > cache->key.offset); |
579 | start = cache->key.objectid; | 583 | start = cache->key.objectid; |
580 | end = start + cache->key.offset - 1; | 584 | end = start + cache->key.offset - 1; |
581 | set_extent_bits(&info->block_group_cache, start, end, | 585 | set_extent_bits(&info->block_group_cache, start, end, |
582 | BLOCK_GROUP_DIRTY, GFP_NOFS); | 586 | BLOCK_GROUP_DIRTY, GFP_NOFS); |
583 | 587 | ||
584 | old_val = btrfs_block_group_used(&cache->item); | 588 | old_val = btrfs_block_group_used(&cache->item); |
585 | num = min(total, cache->key.offset - block_in_group); | 589 | num_bytes = min(total, cache->key.offset - byte_in_group); |
586 | if (alloc) { | 590 | if (alloc) { |
587 | if (cache->data != data && | 591 | if (cache->data != data && |
588 | old_val < (cache->key.offset >> 1)) { | 592 | old_val < (cache->key.offset >> 1)) { |
@@ -608,18 +612,18 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
608 | start, end, bit_to_set, | 612 | start, end, bit_to_set, |
609 | GFP_NOFS); | 613 | GFP_NOFS); |
610 | } | 614 | } |
611 | old_val += num; | 615 | old_val += num_bytes; |
612 | } else { | 616 | } else { |
613 | old_val -= num; | 617 | old_val -= num_bytes; |
614 | if (mark_free) { | 618 | if (mark_free) { |
615 | set_extent_dirty(&info->free_space_cache, | 619 | set_extent_dirty(&info->free_space_cache, |
616 | blocknr, blocknr + num - 1, | 620 | bytenr, bytenr + num_bytes - 1, |
617 | GFP_NOFS); | 621 | GFP_NOFS); |
618 | } | 622 | } |
619 | } | 623 | } |
620 | btrfs_set_block_group_used(&cache->item, old_val); | 624 | btrfs_set_block_group_used(&cache->item, old_val); |
621 | total -= num; | 625 | total -= num_bytes; |
622 | blocknr += num; | 626 | bytenr += num_bytes; |
623 | } | 627 | } |
624 | return 0; | 628 | return 0; |
625 | } | 629 | } |
@@ -701,13 +705,14 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct | |||
701 | return 0; | 705 | return 0; |
702 | } | 706 | } |
703 | 707 | ||
704 | static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) | 708 | static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes, |
709 | int pending) | ||
705 | { | 710 | { |
706 | int err = 0; | 711 | int err = 0; |
707 | struct extent_buffer *buf; | 712 | struct extent_buffer *buf; |
708 | 713 | ||
709 | if (!pending) { | 714 | if (!pending) { |
710 | buf = btrfs_find_tree_block(root, blocknr); | 715 | buf = btrfs_find_tree_block(root, bytenr, num_bytes); |
711 | if (buf) { | 716 | if (buf) { |
712 | if (btrfs_buffer_uptodate(buf)) { | 717 | if (btrfs_buffer_uptodate(buf)) { |
713 | u64 transid = | 718 | u64 transid = |
@@ -720,10 +725,11 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) | |||
720 | free_extent_buffer(buf); | 725 | free_extent_buffer(buf); |
721 | } | 726 | } |
722 | set_extent_dirty(&root->fs_info->pinned_extents, | 727 | set_extent_dirty(&root->fs_info->pinned_extents, |
723 | blocknr, blocknr, GFP_NOFS); | 728 | bytenr, bytenr + num_bytes - 1, GFP_NOFS); |
724 | } else { | 729 | } else { |
725 | set_extent_bits(&root->fs_info->pending_del, | 730 | set_extent_bits(&root->fs_info->pending_del, |
726 | blocknr, blocknr, EXTENT_LOCKED, GFP_NOFS); | 731 | bytenr, bytenr + num_bytes - 1, |
732 | EXTENT_LOCKED, GFP_NOFS); | ||
727 | } | 733 | } |
728 | BUG_ON(err < 0); | 734 | BUG_ON(err < 0); |
729 | return 0; | 735 | return 0; |
@@ -733,7 +739,7 @@ static int pin_down_block(struct btrfs_root *root, u64 blocknr, int pending) | |||
733 | * remove an extent from the root, returns 0 on success | 739 | * remove an extent from the root, returns 0 on success |
734 | */ | 740 | */ |
735 | static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 741 | static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
736 | *root, u64 blocknr, u64 num_blocks, int pin, | 742 | *root, u64 bytenr, u64 num_bytes, int pin, |
737 | int mark_free) | 743 | int mark_free) |
738 | { | 744 | { |
739 | struct btrfs_path *path; | 745 | struct btrfs_path *path; |
@@ -745,9 +751,9 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
745 | struct btrfs_extent_item *ei; | 751 | struct btrfs_extent_item *ei; |
746 | u32 refs; | 752 | u32 refs; |
747 | 753 | ||
748 | key.objectid = blocknr; | 754 | key.objectid = bytenr; |
749 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 755 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
750 | key.offset = num_blocks; | 756 | key.offset = num_bytes; |
751 | 757 | ||
752 | path = btrfs_alloc_path(); | 758 | path = btrfs_alloc_path(); |
753 | if (!path) | 759 | if (!path) |
@@ -768,28 +774,29 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
768 | btrfs_mark_buffer_dirty(leaf); | 774 | btrfs_mark_buffer_dirty(leaf); |
769 | 775 | ||
770 | if (refs == 0) { | 776 | if (refs == 0) { |
771 | u64 super_blocks_used, root_blocks_used; | 777 | u64 super_used; |
778 | u64 root_used; | ||
772 | 779 | ||
773 | if (pin) { | 780 | if (pin) { |
774 | ret = pin_down_block(root, blocknr, 0); | 781 | ret = pin_down_bytes(root, bytenr, num_bytes, 0); |
775 | BUG_ON(ret); | 782 | BUG_ON(ret); |
776 | } | 783 | } |
777 | 784 | ||
778 | /* block accounting for super block */ | 785 | /* block accounting for super block */ |
779 | super_blocks_used = btrfs_super_blocks_used(&info->super_copy); | 786 | super_used = btrfs_super_bytes_used(&info->super_copy); |
780 | btrfs_set_super_blocks_used(&info->super_copy, | 787 | btrfs_set_super_bytes_used(&info->super_copy, |
781 | super_blocks_used - num_blocks); | 788 | super_used - num_bytes); |
782 | 789 | ||
783 | /* block accounting for root item */ | 790 | /* block accounting for root item */ |
784 | root_blocks_used = btrfs_root_used(&root->root_item); | 791 | root_used = btrfs_root_used(&root->root_item); |
785 | btrfs_set_root_used(&root->root_item, | 792 | btrfs_set_root_used(&root->root_item, |
786 | root_blocks_used - num_blocks); | 793 | root_used - num_bytes); |
787 | 794 | ||
788 | ret = btrfs_del_item(trans, extent_root, path); | 795 | ret = btrfs_del_item(trans, extent_root, path); |
789 | if (ret) { | 796 | if (ret) { |
790 | return ret; | 797 | return ret; |
791 | } | 798 | } |
792 | ret = update_block_group(trans, root, blocknr, num_blocks, 0, | 799 | ret = update_block_group(trans, root, bytenr, num_bytes, 0, |
793 | mark_free, 0); | 800 | mark_free, 0); |
794 | BUG_ON(ret); | 801 | BUG_ON(ret); |
795 | } | 802 | } |
@@ -836,17 +843,18 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct | |||
836 | * remove an extent from the root, returns 0 on success | 843 | * remove an extent from the root, returns 0 on success |
837 | */ | 844 | */ |
838 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 845 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
839 | *root, u64 blocknr, u64 num_blocks, int pin) | 846 | *root, u64 bytenr, u64 num_bytes, int pin) |
840 | { | 847 | { |
841 | struct btrfs_root *extent_root = root->fs_info->extent_root; | 848 | struct btrfs_root *extent_root = root->fs_info->extent_root; |
842 | int pending_ret; | 849 | int pending_ret; |
843 | int ret; | 850 | int ret; |
844 | 851 | ||
852 | WARN_ON(num_bytes < root->sectorsize); | ||
845 | if (root == extent_root) { | 853 | if (root == extent_root) { |
846 | pin_down_block(root, blocknr, 1); | 854 | pin_down_bytes(root, bytenr, num_bytes, 1); |
847 | return 0; | 855 | return 0; |
848 | } | 856 | } |
849 | ret = __free_extent(trans, root, blocknr, num_blocks, pin, pin == 0); | 857 | ret = __free_extent(trans, root, bytenr, num_bytes, pin, pin == 0); |
850 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root); | 858 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root); |
851 | return ret ? ret : pending_ret; | 859 | return ret ? ret : pending_ret; |
852 | } | 860 | } |
@@ -860,8 +868,8 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
860 | * Any available blocks before search_start are skipped. | 868 | * Any available blocks before search_start are skipped. |
861 | */ | 869 | */ |
862 | static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 870 | static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
863 | *orig_root, u64 num_blocks, u64 empty_size, | 871 | *orig_root, u64 num_bytes, u64 empty_size, |
864 | u64 search_start, u64 search_end, u64 hint_block, | 872 | u64 search_start, u64 search_end, u64 hint_byte, |
865 | struct btrfs_key *ins, u64 exclude_start, | 873 | struct btrfs_key *ins, u64 exclude_start, |
866 | u64 exclude_nr, int data) | 874 | u64 exclude_nr, int data) |
867 | { | 875 | { |
@@ -870,30 +878,29 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
870 | int ret; | 878 | int ret; |
871 | u64 hole_size = 0; | 879 | u64 hole_size = 0; |
872 | int slot = 0; | 880 | int slot = 0; |
873 | u64 last_block = 0; | 881 | u64 last_byte = 0; |
874 | u64 orig_search_start = search_start; | 882 | u64 orig_search_start = search_start; |
875 | int start_found; | 883 | int start_found; |
876 | struct extent_buffer *l; | 884 | struct extent_buffer *l; |
877 | struct btrfs_root * root = orig_root->fs_info->extent_root; | 885 | struct btrfs_root * root = orig_root->fs_info->extent_root; |
878 | struct btrfs_fs_info *info = root->fs_info; | 886 | struct btrfs_fs_info *info = root->fs_info; |
879 | int total_needed = num_blocks; | 887 | u64 total_needed = num_bytes; |
880 | int level; | 888 | int level; |
881 | struct btrfs_block_group_cache *block_group; | 889 | struct btrfs_block_group_cache *block_group; |
882 | int full_scan = 0; | 890 | int full_scan = 0; |
883 | int wrapped = 0; | 891 | int wrapped = 0; |
884 | u64 cached_search_start = 0; | ||
885 | 892 | ||
886 | WARN_ON(num_blocks < 1); | 893 | WARN_ON(num_bytes < root->sectorsize); |
887 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); | 894 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); |
888 | 895 | ||
889 | level = btrfs_header_level(root->node); | 896 | level = btrfs_header_level(root->node); |
890 | 897 | ||
891 | if (search_end == (u64)-1) | 898 | if (search_end == (u64)-1) |
892 | search_end = btrfs_super_total_blocks(&info->super_copy); | 899 | search_end = btrfs_super_total_bytes(&info->super_copy); |
893 | if (hint_block) { | 900 | if (hint_byte) { |
894 | block_group = btrfs_lookup_block_group(info, hint_block); | 901 | block_group = btrfs_lookup_block_group(info, hint_byte); |
895 | block_group = btrfs_find_block_group(root, block_group, | 902 | block_group = btrfs_find_block_group(root, block_group, |
896 | hint_block, data, 1); | 903 | hint_byte, data, 1); |
897 | } else { | 904 | } else { |
898 | block_group = btrfs_find_block_group(root, | 905 | block_group = btrfs_find_block_group(root, |
899 | trans->block_group, 0, | 906 | trans->block_group, 0, |
@@ -906,7 +913,6 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
906 | check_failed: | 913 | check_failed: |
907 | search_start = find_search_start(root, &block_group, | 914 | search_start = find_search_start(root, &block_group, |
908 | search_start, total_needed, data); | 915 | search_start, total_needed, data); |
909 | cached_search_start = search_start; | ||
910 | 916 | ||
911 | btrfs_init_path(path); | 917 | btrfs_init_path(path); |
912 | ins->objectid = search_start; | 918 | ins->objectid = search_start; |
@@ -958,27 +964,27 @@ check_failed: | |||
958 | start_found = 1; | 964 | start_found = 1; |
959 | goto check_pending; | 965 | goto check_pending; |
960 | } | 966 | } |
961 | ins->objectid = last_block > search_start ? | 967 | ins->objectid = last_byte > search_start ? |
962 | last_block : search_start; | 968 | last_byte : search_start; |
963 | ins->offset = search_end - ins->objectid; | 969 | ins->offset = search_end - ins->objectid; |
964 | goto check_pending; | 970 | goto check_pending; |
965 | } | 971 | } |
966 | btrfs_item_key_to_cpu(l, &key, slot); | 972 | btrfs_item_key_to_cpu(l, &key, slot); |
967 | 973 | ||
968 | if (key.objectid >= search_start && key.objectid > last_block && | 974 | if (key.objectid >= search_start && key.objectid > last_byte && |
969 | start_found) { | 975 | start_found) { |
970 | if (last_block < search_start) | 976 | if (last_byte < search_start) |
971 | last_block = search_start; | 977 | last_byte = search_start; |
972 | hole_size = key.objectid - last_block; | 978 | hole_size = key.objectid - last_byte; |
973 | if (hole_size >= num_blocks) { | 979 | if (hole_size >= num_bytes) { |
974 | ins->objectid = last_block; | 980 | ins->objectid = last_byte; |
975 | ins->offset = hole_size; | 981 | ins->offset = hole_size; |
976 | goto check_pending; | 982 | goto check_pending; |
977 | } | 983 | } |
978 | } | 984 | } |
979 | if (btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY) { | 985 | if (btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY) { |
980 | if (!start_found) { | 986 | if (!start_found) { |
981 | last_block = key.objectid; | 987 | last_byte = key.objectid; |
982 | start_found = 1; | 988 | start_found = 1; |
983 | } | 989 | } |
984 | goto next; | 990 | goto next; |
@@ -986,9 +992,9 @@ check_failed: | |||
986 | 992 | ||
987 | 993 | ||
988 | start_found = 1; | 994 | start_found = 1; |
989 | last_block = key.objectid + key.offset; | 995 | last_byte = key.objectid + key.offset; |
990 | 996 | ||
991 | if (!full_scan && last_block >= block_group->key.objectid + | 997 | if (!full_scan && last_byte >= block_group->key.objectid + |
992 | block_group->key.offset) { | 998 | block_group->key.offset) { |
993 | btrfs_release_path(root, path); | 999 | btrfs_release_path(root, path); |
994 | search_start = block_group->key.objectid + | 1000 | search_start = block_group->key.objectid + |
@@ -1006,20 +1012,20 @@ check_pending: | |||
1006 | btrfs_release_path(root, path); | 1012 | btrfs_release_path(root, path); |
1007 | BUG_ON(ins->objectid < search_start); | 1013 | BUG_ON(ins->objectid < search_start); |
1008 | 1014 | ||
1009 | if (ins->objectid + num_blocks >= search_end) | 1015 | if (ins->objectid + num_bytes >= search_end) |
1010 | goto enospc; | 1016 | goto enospc; |
1011 | 1017 | ||
1012 | if (test_range_bit(&info->extent_ins, ins->objectid, | 1018 | if (test_range_bit(&info->extent_ins, ins->objectid, |
1013 | ins->objectid + num_blocks -1, EXTENT_LOCKED, 0)) { | 1019 | ins->objectid + num_bytes -1, EXTENT_LOCKED, 0)) { |
1014 | search_start = ins->objectid + num_blocks; | 1020 | search_start = ins->objectid + num_bytes; |
1015 | goto new_group; | 1021 | goto new_group; |
1016 | } | 1022 | } |
1017 | if (test_range_bit(&info->pinned_extents, ins->objectid, | 1023 | if (test_range_bit(&info->pinned_extents, ins->objectid, |
1018 | ins->objectid + num_blocks -1, EXTENT_DIRTY, 0)) { | 1024 | ins->objectid + num_bytes -1, EXTENT_DIRTY, 0)) { |
1019 | search_start = ins->objectid + num_blocks; | 1025 | search_start = ins->objectid + num_bytes; |
1020 | goto new_group; | 1026 | goto new_group; |
1021 | } | 1027 | } |
1022 | if (exclude_nr > 0 && (ins->objectid + num_blocks > exclude_start && | 1028 | if (exclude_nr > 0 && (ins->objectid + num_bytes > exclude_start && |
1023 | ins->objectid < exclude_start + exclude_nr)) { | 1029 | ins->objectid < exclude_start + exclude_nr)) { |
1024 | search_start = exclude_start + exclude_nr; | 1030 | search_start = exclude_start + exclude_nr; |
1025 | goto new_group; | 1031 | goto new_group; |
@@ -1029,12 +1035,12 @@ check_pending: | |||
1029 | if (block_group) | 1035 | if (block_group) |
1030 | trans->block_group = block_group; | 1036 | trans->block_group = block_group; |
1031 | } | 1037 | } |
1032 | ins->offset = num_blocks; | 1038 | ins->offset = num_bytes; |
1033 | btrfs_free_path(path); | 1039 | btrfs_free_path(path); |
1034 | return 0; | 1040 | return 0; |
1035 | 1041 | ||
1036 | new_group: | 1042 | new_group: |
1037 | if (search_start + num_blocks >= search_end) { | 1043 | if (search_start + num_bytes >= search_end) { |
1038 | enospc: | 1044 | enospc: |
1039 | search_start = orig_search_start; | 1045 | search_start = orig_search_start; |
1040 | if (full_scan) { | 1046 | if (full_scan) { |
@@ -1069,12 +1075,12 @@ error: | |||
1069 | */ | 1075 | */ |
1070 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | 1076 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, |
1071 | struct btrfs_root *root, u64 owner, | 1077 | struct btrfs_root *root, u64 owner, |
1072 | u64 num_blocks, u64 empty_size, u64 hint_block, | 1078 | u64 num_bytes, u64 empty_size, u64 hint_byte, |
1073 | u64 search_end, struct btrfs_key *ins, int data) | 1079 | u64 search_end, struct btrfs_key *ins, int data) |
1074 | { | 1080 | { |
1075 | int ret; | 1081 | int ret; |
1076 | int pending_ret; | 1082 | int pending_ret; |
1077 | u64 super_blocks_used, root_blocks_used; | 1083 | u64 super_used, root_used; |
1078 | u64 search_start = 0; | 1084 | u64 search_start = 0; |
1079 | struct btrfs_fs_info *info = root->fs_info; | 1085 | struct btrfs_fs_info *info = root->fs_info; |
1080 | struct btrfs_root *extent_root = info->extent_root; | 1086 | struct btrfs_root *extent_root = info->extent_root; |
@@ -1083,9 +1089,9 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
1083 | btrfs_set_stack_extent_refs(&extent_item, 1); | 1089 | btrfs_set_stack_extent_refs(&extent_item, 1); |
1084 | btrfs_set_stack_extent_owner(&extent_item, owner); | 1090 | btrfs_set_stack_extent_owner(&extent_item, owner); |
1085 | 1091 | ||
1086 | WARN_ON(num_blocks < 1); | 1092 | WARN_ON(num_bytes < root->sectorsize); |
1087 | ret = find_free_extent(trans, root, num_blocks, empty_size, | 1093 | ret = find_free_extent(trans, root, num_bytes, empty_size, |
1088 | search_start, search_end, hint_block, ins, | 1094 | search_start, search_end, hint_byte, ins, |
1089 | trans->alloc_exclude_start, | 1095 | trans->alloc_exclude_start, |
1090 | trans->alloc_exclude_nr, data); | 1096 | trans->alloc_exclude_nr, data); |
1091 | BUG_ON(ret); | 1097 | BUG_ON(ret); |
@@ -1093,21 +1099,18 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
1093 | return ret; | 1099 | return ret; |
1094 | 1100 | ||
1095 | /* block accounting for super block */ | 1101 | /* block accounting for super block */ |
1096 | super_blocks_used = btrfs_super_blocks_used(&info->super_copy); | 1102 | super_used = btrfs_super_bytes_used(&info->super_copy); |
1097 | btrfs_set_super_blocks_used(&info->super_copy, super_blocks_used + | 1103 | btrfs_set_super_bytes_used(&info->super_copy, super_used + num_bytes); |
1098 | num_blocks); | ||
1099 | 1104 | ||
1100 | /* block accounting for root item */ | 1105 | /* block accounting for root item */ |
1101 | root_blocks_used = btrfs_root_used(&root->root_item); | 1106 | root_used = btrfs_root_used(&root->root_item); |
1102 | btrfs_set_root_used(&root->root_item, root_blocks_used + | 1107 | btrfs_set_root_used(&root->root_item, root_used + num_bytes); |
1103 | num_blocks); | ||
1104 | 1108 | ||
1105 | clear_extent_dirty(&root->fs_info->free_space_cache, | 1109 | clear_extent_dirty(&root->fs_info->free_space_cache, |
1106 | ins->objectid, ins->objectid + ins->offset - 1, | 1110 | ins->objectid, ins->objectid + ins->offset - 1, |
1107 | GFP_NOFS); | 1111 | GFP_NOFS); |
1108 | 1112 | ||
1109 | if (root == extent_root) { | 1113 | if (root == extent_root) { |
1110 | BUG_ON(num_blocks != 1); | ||
1111 | set_extent_bits(&root->fs_info->extent_ins, ins->objectid, | 1114 | set_extent_bits(&root->fs_info->extent_ins, ins->objectid, |
1112 | ins->objectid + ins->offset - 1, | 1115 | ins->objectid + ins->offset - 1, |
1113 | EXTENT_LOCKED, GFP_NOFS); | 1116 | EXTENT_LOCKED, GFP_NOFS); |
@@ -1146,7 +1149,8 @@ update_block: | |||
1146 | * returns the tree buffer or NULL. | 1149 | * returns the tree buffer or NULL. |
1147 | */ | 1150 | */ |
1148 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 1151 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
1149 | struct btrfs_root *root, u64 hint, | 1152 | struct btrfs_root *root, |
1153 | u32 blocksize, u64 hint, | ||
1150 | u64 empty_size) | 1154 | u64 empty_size) |
1151 | { | 1155 | { |
1152 | struct btrfs_key ins; | 1156 | struct btrfs_key ins; |
@@ -1154,14 +1158,15 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
1154 | struct extent_buffer *buf; | 1158 | struct extent_buffer *buf; |
1155 | 1159 | ||
1156 | ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, | 1160 | ret = btrfs_alloc_extent(trans, root, root->root_key.objectid, |
1157 | 1, empty_size, hint, (u64)-1, &ins, 0); | 1161 | blocksize, empty_size, hint, |
1162 | (u64)-1, &ins, 0); | ||
1158 | if (ret) { | 1163 | if (ret) { |
1159 | BUG_ON(ret > 0); | 1164 | BUG_ON(ret > 0); |
1160 | return ERR_PTR(ret); | 1165 | return ERR_PTR(ret); |
1161 | } | 1166 | } |
1162 | buf = btrfs_find_create_tree_block(root, ins.objectid); | 1167 | buf = btrfs_find_create_tree_block(root, ins.objectid, blocksize); |
1163 | if (!buf) { | 1168 | if (!buf) { |
1164 | btrfs_free_extent(trans, root, ins.objectid, 1, 0); | 1169 | btrfs_free_extent(trans, root, ins.objectid, blocksize, 0); |
1165 | return ERR_PTR(-ENOMEM); | 1170 | return ERR_PTR(-ENOMEM); |
1166 | } | 1171 | } |
1167 | btrfs_set_buffer_uptodate(buf); | 1172 | btrfs_set_buffer_uptodate(buf); |
@@ -1191,7 +1196,7 @@ static int drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
1191 | BUG_ON(!btrfs_is_leaf(leaf)); | 1196 | BUG_ON(!btrfs_is_leaf(leaf)); |
1192 | nritems = btrfs_header_nritems(leaf); | 1197 | nritems = btrfs_header_nritems(leaf); |
1193 | for (i = 0; i < nritems; i++) { | 1198 | for (i = 0; i < nritems; i++) { |
1194 | u64 disk_blocknr; | 1199 | u64 disk_bytenr; |
1195 | 1200 | ||
1196 | btrfs_item_key_to_cpu(leaf, &key, i); | 1201 | btrfs_item_key_to_cpu(leaf, &key, i); |
1197 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 1202 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
@@ -1204,11 +1209,11 @@ static int drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
1204 | * FIXME make sure to insert a trans record that | 1209 | * FIXME make sure to insert a trans record that |
1205 | * repeats the snapshot del on crash | 1210 | * repeats the snapshot del on crash |
1206 | */ | 1211 | */ |
1207 | disk_blocknr = btrfs_file_extent_disk_blocknr(leaf, fi); | 1212 | disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); |
1208 | if (disk_blocknr == 0) | 1213 | if (disk_bytenr == 0) |
1209 | continue; | 1214 | continue; |
1210 | ret = btrfs_free_extent(trans, root, disk_blocknr, | 1215 | ret = btrfs_free_extent(trans, root, disk_bytenr, |
1211 | btrfs_file_extent_disk_num_blocks(leaf, fi), 0); | 1216 | btrfs_file_extent_disk_num_bytes(leaf, fi), 0); |
1212 | BUG_ON(ret); | 1217 | BUG_ON(ret); |
1213 | } | 1218 | } |
1214 | return 0; | 1219 | return 0; |
@@ -1219,19 +1224,23 @@ static void reada_walk_down(struct btrfs_root *root, | |||
1219 | { | 1224 | { |
1220 | int i; | 1225 | int i; |
1221 | u32 nritems; | 1226 | u32 nritems; |
1222 | u64 blocknr; | 1227 | u64 bytenr; |
1223 | int ret; | 1228 | int ret; |
1224 | u32 refs; | 1229 | u32 refs; |
1230 | int level; | ||
1231 | u32 blocksize; | ||
1225 | 1232 | ||
1226 | nritems = btrfs_header_nritems(node); | 1233 | nritems = btrfs_header_nritems(node); |
1234 | level = btrfs_header_level(node); | ||
1227 | for (i = 0; i < nritems; i++) { | 1235 | for (i = 0; i < nritems; i++) { |
1228 | blocknr = btrfs_node_blockptr(node, i); | 1236 | bytenr = btrfs_node_blockptr(node, i); |
1229 | ret = lookup_extent_ref(NULL, root, blocknr, 1, &refs); | 1237 | blocksize = btrfs_level_size(root, level - 1); |
1238 | ret = lookup_extent_ref(NULL, root, bytenr, blocksize, &refs); | ||
1230 | BUG_ON(ret); | 1239 | BUG_ON(ret); |
1231 | if (refs != 1) | 1240 | if (refs != 1) |
1232 | continue; | 1241 | continue; |
1233 | mutex_unlock(&root->fs_info->fs_mutex); | 1242 | mutex_unlock(&root->fs_info->fs_mutex); |
1234 | ret = readahead_tree_block(root, blocknr); | 1243 | ret = readahead_tree_block(root, bytenr, blocksize); |
1235 | cond_resched(); | 1244 | cond_resched(); |
1236 | mutex_lock(&root->fs_info->fs_mutex); | 1245 | mutex_lock(&root->fs_info->fs_mutex); |
1237 | if (ret) | 1246 | if (ret) |
@@ -1248,15 +1257,16 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1248 | { | 1257 | { |
1249 | struct extent_buffer *next; | 1258 | struct extent_buffer *next; |
1250 | struct extent_buffer *cur; | 1259 | struct extent_buffer *cur; |
1251 | u64 blocknr; | 1260 | u64 bytenr; |
1261 | u32 blocksize; | ||
1252 | int ret; | 1262 | int ret; |
1253 | u32 refs; | 1263 | u32 refs; |
1254 | 1264 | ||
1255 | WARN_ON(*level < 0); | 1265 | WARN_ON(*level < 0); |
1256 | WARN_ON(*level >= BTRFS_MAX_LEVEL); | 1266 | WARN_ON(*level >= BTRFS_MAX_LEVEL); |
1257 | ret = lookup_extent_ref(trans, root, | 1267 | ret = lookup_extent_ref(trans, root, |
1258 | extent_buffer_blocknr(path->nodes[*level]), | 1268 | path->nodes[*level]->start, |
1259 | 1, &refs); | 1269 | path->nodes[*level]->len, &refs); |
1260 | BUG_ON(ret); | 1270 | BUG_ON(ret); |
1261 | if (refs > 1) | 1271 | if (refs > 1) |
1262 | goto out; | 1272 | goto out; |
@@ -1283,30 +1293,33 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1283 | BUG_ON(ret); | 1293 | BUG_ON(ret); |
1284 | break; | 1294 | break; |
1285 | } | 1295 | } |
1286 | blocknr = btrfs_node_blockptr(cur, path->slots[*level]); | 1296 | bytenr = btrfs_node_blockptr(cur, path->slots[*level]); |
1287 | ret = lookup_extent_ref(trans, root, blocknr, 1, &refs); | 1297 | blocksize = btrfs_level_size(root, *level - 1); |
1298 | ret = lookup_extent_ref(trans, root, bytenr, blocksize, &refs); | ||
1288 | BUG_ON(ret); | 1299 | BUG_ON(ret); |
1289 | if (refs != 1) { | 1300 | if (refs != 1) { |
1290 | path->slots[*level]++; | 1301 | path->slots[*level]++; |
1291 | ret = btrfs_free_extent(trans, root, blocknr, 1, 1); | 1302 | ret = btrfs_free_extent(trans, root, bytenr, |
1303 | blocksize, 1); | ||
1292 | BUG_ON(ret); | 1304 | BUG_ON(ret); |
1293 | continue; | 1305 | continue; |
1294 | } | 1306 | } |
1295 | next = btrfs_find_tree_block(root, blocknr); | 1307 | next = btrfs_find_tree_block(root, bytenr, blocksize); |
1296 | if (!next || !btrfs_buffer_uptodate(next)) { | 1308 | if (!next || !btrfs_buffer_uptodate(next)) { |
1297 | free_extent_buffer(next); | 1309 | free_extent_buffer(next); |
1298 | mutex_unlock(&root->fs_info->fs_mutex); | 1310 | mutex_unlock(&root->fs_info->fs_mutex); |
1299 | next = read_tree_block(root, blocknr); | 1311 | next = read_tree_block(root, bytenr, blocksize); |
1300 | mutex_lock(&root->fs_info->fs_mutex); | 1312 | mutex_lock(&root->fs_info->fs_mutex); |
1301 | 1313 | ||
1302 | /* we dropped the lock, check one more time */ | 1314 | /* we dropped the lock, check one more time */ |
1303 | ret = lookup_extent_ref(trans, root, blocknr, 1, &refs); | 1315 | ret = lookup_extent_ref(trans, root, bytenr, |
1316 | blocksize, &refs); | ||
1304 | BUG_ON(ret); | 1317 | BUG_ON(ret); |
1305 | if (refs != 1) { | 1318 | if (refs != 1) { |
1306 | path->slots[*level]++; | 1319 | path->slots[*level]++; |
1307 | free_extent_buffer(next); | 1320 | free_extent_buffer(next); |
1308 | ret = btrfs_free_extent(trans, root, | 1321 | ret = btrfs_free_extent(trans, root, |
1309 | blocknr, 1, 1); | 1322 | bytenr, blocksize, 1); |
1310 | BUG_ON(ret); | 1323 | BUG_ON(ret); |
1311 | continue; | 1324 | continue; |
1312 | } | 1325 | } |
@@ -1321,8 +1334,8 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1321 | out: | 1334 | out: |
1322 | WARN_ON(*level < 0); | 1335 | WARN_ON(*level < 0); |
1323 | WARN_ON(*level >= BTRFS_MAX_LEVEL); | 1336 | WARN_ON(*level >= BTRFS_MAX_LEVEL); |
1324 | ret = btrfs_free_extent(trans, root, | 1337 | ret = btrfs_free_extent(trans, root, path->nodes[*level]->start, |
1325 | extent_buffer_blocknr(path->nodes[*level]), 1, 1); | 1338 | path->nodes[*level]->len, 1); |
1326 | free_extent_buffer(path->nodes[*level]); | 1339 | free_extent_buffer(path->nodes[*level]); |
1327 | path->nodes[*level] = NULL; | 1340 | path->nodes[*level] = NULL; |
1328 | *level += 1; | 1341 | *level += 1; |
@@ -1359,8 +1372,8 @@ static int walk_up_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1359 | return 0; | 1372 | return 0; |
1360 | } else { | 1373 | } else { |
1361 | ret = btrfs_free_extent(trans, root, | 1374 | ret = btrfs_free_extent(trans, root, |
1362 | extent_buffer_blocknr(path->nodes[*level]), | 1375 | path->nodes[*level]->start, |
1363 | 1, 1); | 1376 | path->nodes[*level]->len, 1); |
1364 | BUG_ON(ret); | 1377 | BUG_ON(ret); |
1365 | free_extent_buffer(path->nodes[*level]); | 1378 | free_extent_buffer(path->nodes[*level]); |
1366 | path->nodes[*level] = NULL; | 1379 | path->nodes[*level] = NULL; |
@@ -1476,16 +1489,12 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
1476 | struct btrfs_key key; | 1489 | struct btrfs_key key; |
1477 | struct btrfs_key found_key; | 1490 | struct btrfs_key found_key; |
1478 | struct extent_buffer *leaf; | 1491 | struct extent_buffer *leaf; |
1479 | u64 group_size_blocks; | ||
1480 | 1492 | ||
1481 | block_group_cache = &info->block_group_cache; | 1493 | block_group_cache = &info->block_group_cache; |
1482 | 1494 | ||
1483 | group_size_blocks = BTRFS_BLOCK_GROUP_SIZE >> | ||
1484 | info->sb->s_blocksize_bits; | ||
1485 | |||
1486 | root = info->extent_root; | 1495 | root = info->extent_root; |
1487 | key.objectid = 0; | 1496 | key.objectid = 0; |
1488 | key.offset = group_size_blocks; | 1497 | key.offset = BTRFS_BLOCK_GROUP_SIZE; |
1489 | btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY); | 1498 | btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY); |
1490 | 1499 | ||
1491 | path = btrfs_alloc_path(); | 1500 | path = btrfs_alloc_path(); |
@@ -1532,7 +1541,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
1532 | (u64)cache); | 1541 | (u64)cache); |
1533 | 1542 | ||
1534 | if (key.objectid >= | 1543 | if (key.objectid >= |
1535 | btrfs_super_total_blocks(&info->super_copy)) | 1544 | btrfs_super_total_bytes(&info->super_copy)) |
1536 | break; | 1545 | break; |
1537 | } | 1546 | } |
1538 | 1547 | ||