diff options
author | Zheng Yan <zheng.yan@oracle.com> | 2008-09-23 13:14:14 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:07 -0400 |
commit | 31840ae1a6b433ca0e6a8d341756ff478bbf959e (patch) | |
tree | 9343db596aec175e9640aa2800b80f01496d7047 /fs/btrfs/extent-tree.c | |
parent | 1c2308f8e7d8491467e0095af2b01500f1b70819 (diff) |
Btrfs: Full back reference support
This patch makes the back reference system to explicit record the
location of parent node for all types of extents. The location of
parent node is placed into the offset field of backref key. Every
time a tree block is balanced, the back references for the affected
lower level extents are updated.
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 | 1143 |
1 files changed, 695 insertions, 448 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 558fbe407368..5258923d621f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -29,6 +29,21 @@ | |||
29 | #include "locking.h" | 29 | #include "locking.h" |
30 | #include "ref-cache.h" | 30 | #include "ref-cache.h" |
31 | 31 | ||
32 | #define PENDING_EXTENT_INSERT 0 | ||
33 | #define PENDING_EXTENT_DELETE 1 | ||
34 | #define PENDING_BACKREF_UPDATE 2 | ||
35 | |||
36 | struct pending_extent_op { | ||
37 | int type; | ||
38 | u64 bytenr; | ||
39 | u64 num_bytes; | ||
40 | u64 parent; | ||
41 | u64 orig_parent; | ||
42 | u64 generation; | ||
43 | u64 orig_generation; | ||
44 | int level; | ||
45 | }; | ||
46 | |||
32 | static int finish_current_insert(struct btrfs_trans_handle *trans, struct | 47 | static int finish_current_insert(struct btrfs_trans_handle *trans, struct |
33 | btrfs_root *extent_root); | 48 | btrfs_root *extent_root); |
34 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct | 49 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct |
@@ -487,48 +502,15 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root, | |||
487 | return ret; | 502 | return ret; |
488 | } | 503 | } |
489 | 504 | ||
490 | static u64 hash_extent_ref(u64 root_objectid, u64 ref_generation, | ||
491 | u64 owner, u64 owner_offset) | ||
492 | { | ||
493 | u32 high_crc = ~(u32)0; | ||
494 | u32 low_crc = ~(u32)0; | ||
495 | __le64 lenum; | ||
496 | lenum = cpu_to_le64(root_objectid); | ||
497 | high_crc = btrfs_crc32c(high_crc, &lenum, sizeof(lenum)); | ||
498 | lenum = cpu_to_le64(ref_generation); | ||
499 | low_crc = btrfs_crc32c(low_crc, &lenum, sizeof(lenum)); | ||
500 | if (owner >= BTRFS_FIRST_FREE_OBJECTID) { | ||
501 | lenum = cpu_to_le64(owner); | ||
502 | low_crc = btrfs_crc32c(low_crc, &lenum, sizeof(lenum)); | ||
503 | lenum = cpu_to_le64(owner_offset); | ||
504 | low_crc = btrfs_crc32c(low_crc, &lenum, sizeof(lenum)); | ||
505 | } | ||
506 | return ((u64)high_crc << 32) | (u64)low_crc; | ||
507 | } | ||
508 | |||
509 | static int match_extent_ref(struct extent_buffer *leaf, | ||
510 | struct btrfs_extent_ref *disk_ref, | ||
511 | struct btrfs_extent_ref *cpu_ref) | ||
512 | { | ||
513 | int ret; | ||
514 | int len; | ||
515 | |||
516 | if (cpu_ref->objectid) | ||
517 | len = sizeof(*cpu_ref); | ||
518 | else | ||
519 | len = 2 * sizeof(u64); | ||
520 | ret = memcmp_extent_buffer(leaf, cpu_ref, (unsigned long)disk_ref, | ||
521 | len); | ||
522 | return ret == 0; | ||
523 | } | ||
524 | |||
525 | /* simple helper to search for an existing extent at a given offset */ | 505 | /* simple helper to search for an existing extent at a given offset */ |
526 | int btrfs_lookup_extent(struct btrfs_root *root, struct btrfs_path *path, | 506 | int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len) |
527 | u64 start, u64 len) | ||
528 | { | 507 | { |
529 | int ret; | 508 | int ret; |
530 | struct btrfs_key key; | 509 | struct btrfs_key key; |
510 | struct btrfs_path *path; | ||
531 | 511 | ||
512 | path = btrfs_alloc_path(); | ||
513 | BUG_ON(!path); | ||
532 | maybe_lock_mutex(root); | 514 | maybe_lock_mutex(root); |
533 | key.objectid = start; | 515 | key.objectid = start; |
534 | key.offset = len; | 516 | key.offset = len; |
@@ -536,72 +518,7 @@ int btrfs_lookup_extent(struct btrfs_root *root, struct btrfs_path *path, | |||
536 | ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path, | 518 | ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path, |
537 | 0, 0); | 519 | 0, 0); |
538 | maybe_unlock_mutex(root); | 520 | maybe_unlock_mutex(root); |
539 | return ret; | 521 | btrfs_free_path(path); |
540 | } | ||
541 | |||
542 | static int noinline lookup_extent_backref(struct btrfs_trans_handle *trans, | ||
543 | struct btrfs_root *root, | ||
544 | struct btrfs_path *path, u64 bytenr, | ||
545 | u64 root_objectid, | ||
546 | u64 ref_generation, u64 owner, | ||
547 | u64 owner_offset, int del) | ||
548 | { | ||
549 | u64 hash; | ||
550 | struct btrfs_key key; | ||
551 | struct btrfs_key found_key; | ||
552 | struct btrfs_extent_ref ref; | ||
553 | struct extent_buffer *leaf; | ||
554 | struct btrfs_extent_ref *disk_ref; | ||
555 | int ret; | ||
556 | int ret2; | ||
557 | |||
558 | btrfs_set_stack_ref_root(&ref, root_objectid); | ||
559 | btrfs_set_stack_ref_generation(&ref, ref_generation); | ||
560 | btrfs_set_stack_ref_objectid(&ref, owner); | ||
561 | btrfs_set_stack_ref_offset(&ref, owner_offset); | ||
562 | |||
563 | hash = hash_extent_ref(root_objectid, ref_generation, owner, | ||
564 | owner_offset); | ||
565 | key.offset = hash; | ||
566 | key.objectid = bytenr; | ||
567 | key.type = BTRFS_EXTENT_REF_KEY; | ||
568 | |||
569 | while (1) { | ||
570 | ret = btrfs_search_slot(trans, root, &key, path, | ||
571 | del ? -1 : 0, del); | ||
572 | if (ret < 0) | ||
573 | goto out; | ||
574 | leaf = path->nodes[0]; | ||
575 | if (ret != 0) { | ||
576 | u32 nritems = btrfs_header_nritems(leaf); | ||
577 | if (path->slots[0] >= nritems) { | ||
578 | ret2 = btrfs_next_leaf(root, path); | ||
579 | if (ret2) | ||
580 | goto out; | ||
581 | leaf = path->nodes[0]; | ||
582 | } | ||
583 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | ||
584 | if (found_key.objectid != bytenr || | ||
585 | found_key.type != BTRFS_EXTENT_REF_KEY) | ||
586 | goto out; | ||
587 | key.offset = found_key.offset; | ||
588 | if (del) { | ||
589 | btrfs_release_path(root, path); | ||
590 | continue; | ||
591 | } | ||
592 | } | ||
593 | disk_ref = btrfs_item_ptr(path->nodes[0], | ||
594 | path->slots[0], | ||
595 | struct btrfs_extent_ref); | ||
596 | if (match_extent_ref(path->nodes[0], disk_ref, &ref)) { | ||
597 | ret = 0; | ||
598 | goto out; | ||
599 | } | ||
600 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | ||
601 | key.offset = found_key.offset + 1; | ||
602 | btrfs_release_path(root, path); | ||
603 | } | ||
604 | out: | ||
605 | return ret; | 522 | return ret; |
606 | } | 523 | } |
607 | 524 | ||
@@ -622,7 +539,7 @@ out: | |||
622 | * File extents can be referenced by: | 539 | * File extents can be referenced by: |
623 | * | 540 | * |
624 | * - multiple snapshots, subvolumes, or different generations in one subvol | 541 | * - multiple snapshots, subvolumes, or different generations in one subvol |
625 | * - different files inside a single subvolume (in theory, not implemented yet) | 542 | * - different files inside a single subvolume |
626 | * - different offsets inside a file (bookend extents in file.c) | 543 | * - different offsets inside a file (bookend extents in file.c) |
627 | * | 544 | * |
628 | * The extent ref structure has fields for: | 545 | * The extent ref structure has fields for: |
@@ -631,119 +548,284 @@ out: | |||
631 | * - Generation number of the tree holding the reference | 548 | * - Generation number of the tree holding the reference |
632 | * - objectid of the file holding the reference | 549 | * - objectid of the file holding the reference |
633 | * - offset in the file corresponding to the key holding the reference | 550 | * - offset in the file corresponding to the key holding the reference |
551 | * - number of references holding by parent node (alway 1 for tree blocks) | ||
552 | * | ||
553 | * Btree leaf may hold multiple references to a file extent. In most cases, | ||
554 | * these references are from same file and the corresponding offsets inside | ||
555 | * the file are close together. So inode objectid and offset in file are | ||
556 | * just hints, they provide hints about where in the btree the references | ||
557 | * can be found and when we can stop searching. | ||
634 | * | 558 | * |
635 | * When a file extent is allocated the fields are filled in: | 559 | * When a file extent is allocated the fields are filled in: |
636 | * (root_key.objectid, trans->transid, inode objectid, offset in file) | 560 | * (root_key.objectid, trans->transid, inode objectid, offset in file, 1) |
637 | * | 561 | * |
638 | * When a leaf is cow'd new references are added for every file extent found | 562 | * When a leaf is cow'd new references are added for every file extent found |
639 | * in the leaf. It looks the same as the create case, but trans->transid | 563 | * in the leaf. It looks similar to the create case, but trans->transid will |
640 | * will be different when the block is cow'd. | 564 | * be different when the block is cow'd. |
641 | * | 565 | * |
642 | * (root_key.objectid, trans->transid, inode objectid, offset in file) | 566 | * (root_key.objectid, trans->transid, inode objectid, offset in file, |
567 | * number of references in the leaf) | ||
643 | * | 568 | * |
644 | * When a file extent is removed either during snapshot deletion or file | 569 | * Because inode objectid and offset in file are just hints, they are not |
645 | * truncation, the corresponding back reference is found | 570 | * used when backrefs are deleted. When a file extent is removed either |
646 | * by searching for: | 571 | * during snapshot deletion or file truncation, we find the corresponding |
572 | * back back reference and check the following fields. | ||
647 | * | 573 | * |
648 | * (btrfs_header_owner(leaf), btrfs_header_generation(leaf), | 574 | * (btrfs_header_owner(leaf), btrfs_header_generation(leaf)) |
649 | * inode objectid, offset in file) | ||
650 | * | 575 | * |
651 | * Btree extents can be referenced by: | 576 | * Btree extents can be referenced by: |
652 | * | 577 | * |
653 | * - Different subvolumes | 578 | * - Different subvolumes |
654 | * - Different generations of the same subvolume | 579 | * - Different generations of the same subvolume |
655 | * | 580 | * |
656 | * Storing sufficient information for a full reverse mapping of a btree | ||
657 | * block would require storing the lowest key of the block in the backref, | ||
658 | * and it would require updating that lowest key either before write out or | ||
659 | * every time it changed. Instead, the objectid of the lowest key is stored | ||
660 | * along with the level of the tree block. This provides a hint | ||
661 | * about where in the btree the block can be found. Searches through the | ||
662 | * btree only need to look for a pointer to that block, so they stop one | ||
663 | * level higher than the level recorded in the backref. | ||
664 | * | ||
665 | * Some btrees do not do reference counting on their extents. These | ||
666 | * include the extent tree and the tree of tree roots. Backrefs for these | ||
667 | * trees always have a generation of zero. | ||
668 | * | ||
669 | * When a tree block is created, back references are inserted: | 581 | * When a tree block is created, back references are inserted: |
670 | * | 582 | * |
671 | * (root->root_key.objectid, trans->transid or zero, level, lowest_key_objectid) | 583 | * (root->root_key.objectid, trans->transid, level, 0, 1) |
672 | * | 584 | * |
673 | * When a tree block is cow'd in a reference counted root, | 585 | * When a tree block is cow'd, new back references are added for all the |
674 | * new back references are added for all the blocks it points to. | 586 | * blocks it points to. If the tree block isn't in reference counted root, |
675 | * These are of the form (trans->transid will have increased since creation): | 587 | * the old back references are removed. These new back references are of |
588 | * the form (trans->transid will have increased since creation): | ||
676 | * | 589 | * |
677 | * (root->root_key.objectid, trans->transid, level, lowest_key_objectid) | 590 | * (root->root_key.objectid, trans->transid, level, 0, 1) |
678 | * | 591 | * |
679 | * Because the lowest_key_objectid and the level are just hints | 592 | * When a backref is in deleting, the following fields are checked: |
680 | * they are not used when backrefs are deleted. When a backref is deleted: | ||
681 | * | 593 | * |
682 | * if backref was for a tree root: | 594 | * if backref was for a tree root: |
683 | * root_objectid = root->root_key.objectid | 595 | * (btrfs_header_owner(itself), btrfs_header_generation(itself)) |
684 | * else | 596 | * else |
685 | * root_objectid = btrfs_header_owner(parent) | 597 | * (btrfs_header_owner(parent), btrfs_header_generation(parent)) |
686 | * | 598 | * |
687 | * (root_objectid, btrfs_header_generation(parent) or zero, 0, 0) | 599 | * Back Reference Key composing: |
688 | * | 600 | * |
689 | * Back Reference Key hashing: | 601 | * The key objectid corresponds to the first byte in the extent, the key |
690 | * | 602 | * type is set to BTRFS_EXTENT_REF_KEY, and the key offset is the first |
691 | * Back references have four fields, each 64 bits long. Unfortunately, | 603 | * byte of parent extent. If a extent is tree root, the key offset is set |
692 | * This is hashed into a single 64 bit number and placed into the key offset. | 604 | * to the key objectid. |
693 | * The key objectid corresponds to the first byte in the extent, and the | ||
694 | * key type is set to BTRFS_EXTENT_REF_KEY | ||
695 | */ | 605 | */ |
696 | int btrfs_insert_extent_backref(struct btrfs_trans_handle *trans, | 606 | |
697 | struct btrfs_root *root, | 607 | static int noinline lookup_extent_backref(struct btrfs_trans_handle *trans, |
698 | struct btrfs_path *path, u64 bytenr, | 608 | struct btrfs_root *root, |
699 | u64 root_objectid, u64 ref_generation, | 609 | struct btrfs_path *path, u64 bytenr, |
700 | u64 owner, u64 owner_offset) | 610 | u64 parent, u64 ref_root, |
611 | u64 ref_generation, int del) | ||
701 | { | 612 | { |
702 | u64 hash; | ||
703 | struct btrfs_key key; | 613 | struct btrfs_key key; |
704 | struct btrfs_extent_ref ref; | 614 | struct btrfs_extent_ref *ref; |
705 | struct btrfs_extent_ref *disk_ref; | 615 | struct extent_buffer *leaf; |
706 | int ret; | 616 | int ret; |
707 | 617 | ||
708 | btrfs_set_stack_ref_root(&ref, root_objectid); | 618 | key.objectid = bytenr; |
709 | btrfs_set_stack_ref_generation(&ref, ref_generation); | 619 | key.type = BTRFS_EXTENT_REF_KEY; |
710 | btrfs_set_stack_ref_objectid(&ref, owner); | 620 | key.offset = parent; |
711 | btrfs_set_stack_ref_offset(&ref, owner_offset); | 621 | |
622 | ret = btrfs_search_slot(trans, root, &key, path, del ? -1 : 0, 1); | ||
623 | if (ret < 0) | ||
624 | goto out; | ||
625 | if (ret > 0) { | ||
626 | ret = -ENOENT; | ||
627 | goto out; | ||
628 | } | ||
629 | |||
630 | leaf = path->nodes[0]; | ||
631 | ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_ref); | ||
632 | if (btrfs_ref_root(leaf, ref) != ref_root || | ||
633 | btrfs_ref_generation(leaf, ref) != ref_generation) { | ||
634 | ret = -EIO; | ||
635 | WARN_ON(1); | ||
636 | goto out; | ||
637 | } | ||
638 | ret = 0; | ||
639 | out: | ||
640 | return ret; | ||
641 | } | ||
642 | |||
643 | static int noinline insert_extent_backref(struct btrfs_trans_handle *trans, | ||
644 | struct btrfs_root *root, | ||
645 | struct btrfs_path *path, | ||
646 | u64 bytenr, u64 parent, | ||
647 | u64 ref_root, u64 ref_generation, | ||
648 | u64 owner_objectid, u64 owner_offset) | ||
649 | { | ||
650 | struct btrfs_key key; | ||
651 | struct extent_buffer *leaf; | ||
652 | struct btrfs_extent_ref *ref; | ||
653 | u32 num_refs; | ||
654 | int ret; | ||
712 | 655 | ||
713 | hash = hash_extent_ref(root_objectid, ref_generation, owner, | ||
714 | owner_offset); | ||
715 | key.offset = hash; | ||
716 | key.objectid = bytenr; | 656 | key.objectid = bytenr; |
717 | key.type = BTRFS_EXTENT_REF_KEY; | 657 | key.type = BTRFS_EXTENT_REF_KEY; |
658 | key.offset = parent; | ||
718 | 659 | ||
719 | ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(ref)); | 660 | ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(*ref)); |
720 | while (ret == -EEXIST) { | 661 | if (ret == 0) { |
721 | disk_ref = btrfs_item_ptr(path->nodes[0], path->slots[0], | 662 | leaf = path->nodes[0]; |
722 | struct btrfs_extent_ref); | 663 | ref = btrfs_item_ptr(leaf, path->slots[0], |
723 | if (match_extent_ref(path->nodes[0], disk_ref, &ref)) | 664 | struct btrfs_extent_ref); |
665 | btrfs_set_ref_root(leaf, ref, ref_root); | ||
666 | btrfs_set_ref_generation(leaf, ref, ref_generation); | ||
667 | btrfs_set_ref_objectid(leaf, ref, owner_objectid); | ||
668 | btrfs_set_ref_offset(leaf, ref, owner_offset); | ||
669 | btrfs_set_ref_num_refs(leaf, ref, 1); | ||
670 | } else if (ret == -EEXIST) { | ||
671 | u64 existing_owner; | ||
672 | BUG_ON(owner_objectid < BTRFS_FIRST_FREE_OBJECTID); | ||
673 | leaf = path->nodes[0]; | ||
674 | ref = btrfs_item_ptr(leaf, path->slots[0], | ||
675 | struct btrfs_extent_ref); | ||
676 | if (btrfs_ref_root(leaf, ref) != ref_root || | ||
677 | btrfs_ref_generation(leaf, ref) != ref_generation) { | ||
678 | ret = -EIO; | ||
679 | WARN_ON(1); | ||
724 | goto out; | 680 | goto out; |
725 | key.offset++; | 681 | } |
726 | btrfs_release_path(root, path); | 682 | |
727 | ret = btrfs_insert_empty_item(trans, root, path, &key, | 683 | num_refs = btrfs_ref_num_refs(leaf, ref); |
728 | sizeof(ref)); | 684 | BUG_ON(num_refs == 0); |
729 | } | 685 | btrfs_set_ref_num_refs(leaf, ref, num_refs + 1); |
730 | if (ret) | 686 | |
687 | existing_owner = btrfs_ref_objectid(leaf, ref); | ||
688 | if (existing_owner == owner_objectid && | ||
689 | btrfs_ref_offset(leaf, ref) > owner_offset) { | ||
690 | btrfs_set_ref_offset(leaf, ref, owner_offset); | ||
691 | } else if (existing_owner != owner_objectid && | ||
692 | existing_owner != BTRFS_MULTIPLE_OBJECTIDS) { | ||
693 | btrfs_set_ref_objectid(leaf, ref, | ||
694 | BTRFS_MULTIPLE_OBJECTIDS); | ||
695 | btrfs_set_ref_offset(leaf, ref, 0); | ||
696 | } | ||
697 | ret = 0; | ||
698 | } else { | ||
731 | goto out; | 699 | goto out; |
732 | disk_ref = btrfs_item_ptr(path->nodes[0], path->slots[0], | 700 | } |
733 | struct btrfs_extent_ref); | ||
734 | write_extent_buffer(path->nodes[0], &ref, (unsigned long)disk_ref, | ||
735 | sizeof(ref)); | ||
736 | btrfs_mark_buffer_dirty(path->nodes[0]); | 701 | btrfs_mark_buffer_dirty(path->nodes[0]); |
737 | out: | 702 | out: |
738 | btrfs_release_path(root, path); | 703 | btrfs_release_path(root, path); |
739 | return ret; | 704 | return ret; |
740 | } | 705 | } |
741 | 706 | ||
707 | static int noinline remove_extent_backref(struct btrfs_trans_handle *trans, | ||
708 | struct btrfs_root *root, | ||
709 | struct btrfs_path *path) | ||
710 | { | ||
711 | struct extent_buffer *leaf; | ||
712 | struct btrfs_extent_ref *ref; | ||
713 | u32 num_refs; | ||
714 | int ret = 0; | ||
715 | |||
716 | leaf = path->nodes[0]; | ||
717 | ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_ref); | ||
718 | num_refs = btrfs_ref_num_refs(leaf, ref); | ||
719 | BUG_ON(num_refs == 0); | ||
720 | num_refs -= 1; | ||
721 | if (num_refs == 0) { | ||
722 | ret = btrfs_del_item(trans, root, path); | ||
723 | } else { | ||
724 | btrfs_set_ref_num_refs(leaf, ref, num_refs); | ||
725 | btrfs_mark_buffer_dirty(leaf); | ||
726 | } | ||
727 | btrfs_release_path(root, path); | ||
728 | return ret; | ||
729 | } | ||
730 | |||
731 | static int __btrfs_update_extent_ref(struct btrfs_trans_handle *trans, | ||
732 | struct btrfs_root *root, u64 bytenr, | ||
733 | u64 orig_parent, u64 parent, | ||
734 | u64 orig_root, u64 ref_root, | ||
735 | u64 orig_generation, u64 ref_generation, | ||
736 | u64 owner_objectid, u64 owner_offset) | ||
737 | { | ||
738 | int ret; | ||
739 | struct btrfs_root *extent_root = root->fs_info->extent_root; | ||
740 | struct btrfs_path *path; | ||
741 | |||
742 | if (root == root->fs_info->extent_root) { | ||
743 | struct pending_extent_op *extent_op; | ||
744 | u64 num_bytes; | ||
745 | |||
746 | BUG_ON(owner_objectid >= BTRFS_MAX_LEVEL); | ||
747 | num_bytes = btrfs_level_size(root, (int)owner_objectid); | ||
748 | if (test_range_bit(&root->fs_info->extent_ins, bytenr, | ||
749 | bytenr + num_bytes - 1, EXTENT_LOCKED, 0)) { | ||
750 | u64 priv; | ||
751 | ret = get_state_private(&root->fs_info->extent_ins, | ||
752 | bytenr, &priv); | ||
753 | BUG_ON(ret); | ||
754 | extent_op = (struct pending_extent_op *) | ||
755 | (unsigned long)priv; | ||
756 | BUG_ON(extent_op->parent != orig_parent); | ||
757 | BUG_ON(extent_op->generation != orig_generation); | ||
758 | extent_op->parent = parent; | ||
759 | extent_op->generation = ref_generation; | ||
760 | } else { | ||
761 | extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); | ||
762 | BUG_ON(!extent_op); | ||
763 | |||
764 | extent_op->type = PENDING_BACKREF_UPDATE; | ||
765 | extent_op->bytenr = bytenr; | ||
766 | extent_op->num_bytes = num_bytes; | ||
767 | extent_op->parent = parent; | ||
768 | extent_op->orig_parent = orig_parent; | ||
769 | extent_op->generation = ref_generation; | ||
770 | extent_op->orig_generation = orig_generation; | ||
771 | extent_op->level = (int)owner_objectid; | ||
772 | |||
773 | set_extent_bits(&root->fs_info->extent_ins, | ||
774 | bytenr, bytenr + num_bytes - 1, | ||
775 | EXTENT_LOCKED, GFP_NOFS); | ||
776 | set_state_private(&root->fs_info->extent_ins, | ||
777 | bytenr, (unsigned long)extent_op); | ||
778 | } | ||
779 | return 0; | ||
780 | } | ||
781 | |||
782 | path = btrfs_alloc_path(); | ||
783 | if (!path) | ||
784 | return -ENOMEM; | ||
785 | ret = lookup_extent_backref(trans, extent_root, path, | ||
786 | bytenr, orig_parent, orig_root, | ||
787 | orig_generation, 1); | ||
788 | if (ret) | ||
789 | goto out; | ||
790 | ret = remove_extent_backref(trans, extent_root, path); | ||
791 | if (ret) | ||
792 | goto out; | ||
793 | ret = insert_extent_backref(trans, extent_root, path, bytenr, | ||
794 | parent, ref_root, ref_generation, | ||
795 | owner_objectid, owner_offset); | ||
796 | BUG_ON(ret); | ||
797 | finish_current_insert(trans, extent_root); | ||
798 | del_pending_extents(trans, extent_root); | ||
799 | out: | ||
800 | btrfs_free_path(path); | ||
801 | return ret; | ||
802 | } | ||
803 | |||
804 | int btrfs_update_extent_ref(struct btrfs_trans_handle *trans, | ||
805 | struct btrfs_root *root, u64 bytenr, | ||
806 | u64 orig_parent, u64 parent, | ||
807 | u64 ref_root, u64 ref_generation, | ||
808 | u64 owner_objectid, u64 owner_offset) | ||
809 | { | ||
810 | int ret; | ||
811 | if (ref_root == BTRFS_TREE_LOG_OBJECTID && | ||
812 | owner_objectid < BTRFS_FIRST_FREE_OBJECTID) | ||
813 | return 0; | ||
814 | maybe_lock_mutex(root); | ||
815 | ret = __btrfs_update_extent_ref(trans, root, bytenr, orig_parent, | ||
816 | parent, ref_root, ref_root, | ||
817 | ref_generation, ref_generation, | ||
818 | owner_objectid, owner_offset); | ||
819 | maybe_unlock_mutex(root); | ||
820 | return ret; | ||
821 | } | ||
822 | |||
742 | static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 823 | static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
743 | struct btrfs_root *root, | 824 | struct btrfs_root *root, u64 bytenr, |
744 | u64 bytenr, u64 num_bytes, | 825 | u64 orig_parent, u64 parent, |
745 | u64 root_objectid, u64 ref_generation, | 826 | u64 orig_root, u64 ref_root, |
746 | u64 owner, u64 owner_offset) | 827 | u64 orig_generation, u64 ref_generation, |
828 | u64 owner_objectid, u64 owner_offset) | ||
747 | { | 829 | { |
748 | struct btrfs_path *path; | 830 | struct btrfs_path *path; |
749 | int ret; | 831 | int ret; |
@@ -752,24 +834,28 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
752 | struct btrfs_extent_item *item; | 834 | struct btrfs_extent_item *item; |
753 | u32 refs; | 835 | u32 refs; |
754 | 836 | ||
755 | WARN_ON(num_bytes < root->sectorsize); | ||
756 | path = btrfs_alloc_path(); | 837 | path = btrfs_alloc_path(); |
757 | if (!path) | 838 | if (!path) |
758 | return -ENOMEM; | 839 | return -ENOMEM; |
759 | 840 | ||
760 | path->reada = 1; | 841 | path->reada = 1; |
761 | key.objectid = bytenr; | 842 | key.objectid = bytenr; |
762 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 843 | key.type = BTRFS_EXTENT_ITEM_KEY; |
763 | key.offset = num_bytes; | 844 | key.offset = (u64)-1; |
845 | |||
764 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, | 846 | ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, path, |
765 | 0, 1); | 847 | 0, 1); |
766 | if (ret < 0) | 848 | if (ret < 0) |
767 | return ret; | 849 | return ret; |
768 | if (ret != 0) { | 850 | BUG_ON(ret == 0 || path->slots[0] == 0); |
769 | BUG(); | 851 | |
770 | } | 852 | path->slots[0]--; |
771 | BUG_ON(ret != 0); | ||
772 | l = path->nodes[0]; | 853 | l = path->nodes[0]; |
854 | |||
855 | btrfs_item_key_to_cpu(l, &key, path->slots[0]); | ||
856 | BUG_ON(key.objectid != bytenr); | ||
857 | BUG_ON(key.type != BTRFS_EXTENT_ITEM_KEY); | ||
858 | |||
773 | item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); | 859 | item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); |
774 | refs = btrfs_extent_refs(l, item); | 860 | refs = btrfs_extent_refs(l, item); |
775 | btrfs_set_extent_refs(l, item, refs + 1); | 861 | btrfs_set_extent_refs(l, item, refs + 1); |
@@ -778,9 +864,10 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
778 | btrfs_release_path(root->fs_info->extent_root, path); | 864 | btrfs_release_path(root->fs_info->extent_root, path); |
779 | 865 | ||
780 | path->reada = 1; | 866 | path->reada = 1; |
781 | ret = btrfs_insert_extent_backref(trans, root->fs_info->extent_root, | 867 | ret = insert_extent_backref(trans, root->fs_info->extent_root, |
782 | path, bytenr, root_objectid, | 868 | path, bytenr, parent, |
783 | ref_generation, owner, owner_offset); | 869 | ref_root, ref_generation, |
870 | owner_objectid, owner_offset); | ||
784 | BUG_ON(ret); | 871 | BUG_ON(ret); |
785 | finish_current_insert(trans, root->fs_info->extent_root); | 872 | finish_current_insert(trans, root->fs_info->extent_root); |
786 | del_pending_extents(trans, root->fs_info->extent_root); | 873 | del_pending_extents(trans, root->fs_info->extent_root); |
@@ -790,18 +877,20 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
790 | } | 877 | } |
791 | 878 | ||
792 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 879 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
793 | struct btrfs_root *root, | 880 | struct btrfs_root *root, |
794 | u64 bytenr, u64 num_bytes, | 881 | u64 bytenr, u64 num_bytes, u64 parent, |
795 | u64 root_objectid, u64 ref_generation, | 882 | u64 ref_root, u64 ref_generation, |
796 | u64 owner, u64 owner_offset) | 883 | u64 owner_objectid, u64 owner_offset) |
797 | { | 884 | { |
798 | int ret; | 885 | int ret; |
799 | 886 | if (ref_root == BTRFS_TREE_LOG_OBJECTID && | |
800 | mutex_lock(&root->fs_info->alloc_mutex); | 887 | owner_objectid < BTRFS_FIRST_FREE_OBJECTID) |
801 | ret = __btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, | 888 | return 0; |
802 | root_objectid, ref_generation, | 889 | maybe_lock_mutex(root); |
803 | owner, owner_offset); | 890 | ret = __btrfs_inc_extent_ref(trans, root, bytenr, 0, parent, |
804 | mutex_unlock(&root->fs_info->alloc_mutex); | 891 | 0, ref_root, 0, ref_generation, |
892 | owner_objectid, owner_offset); | ||
893 | maybe_unlock_mutex(root); | ||
805 | return ret; | 894 | return ret; |
806 | } | 895 | } |
807 | 896 | ||
@@ -813,9 +902,9 @@ int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | |||
813 | return 0; | 902 | return 0; |
814 | } | 903 | } |
815 | 904 | ||
816 | static int lookup_extent_ref(struct btrfs_trans_handle *trans, | 905 | int btrfs_lookup_extent_ref(struct btrfs_trans_handle *trans, |
817 | struct btrfs_root *root, u64 bytenr, | 906 | struct btrfs_root *root, u64 bytenr, |
818 | u64 num_bytes, u32 *refs) | 907 | u64 num_bytes, u32 *refs) |
819 | { | 908 | { |
820 | struct btrfs_path *path; | 909 | struct btrfs_path *path; |
821 | int ret; | 910 | int ret; |
@@ -846,7 +935,6 @@ out: | |||
846 | return 0; | 935 | return 0; |
847 | } | 936 | } |
848 | 937 | ||
849 | |||
850 | static int get_reference_status(struct btrfs_root *root, u64 bytenr, | 938 | static int get_reference_status(struct btrfs_root *root, u64 bytenr, |
851 | u64 parent_gen, u64 ref_objectid, | 939 | u64 parent_gen, u64 ref_objectid, |
852 | u64 *min_generation, u32 *ref_count) | 940 | u64 *min_generation, u32 *ref_count) |
@@ -863,7 +951,7 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr, | |||
863 | int ret; | 951 | int ret; |
864 | 952 | ||
865 | key.objectid = bytenr; | 953 | key.objectid = bytenr; |
866 | key.offset = 0; | 954 | key.offset = (u64)-1; |
867 | key.type = BTRFS_EXTENT_ITEM_KEY; | 955 | key.type = BTRFS_EXTENT_ITEM_KEY; |
868 | 956 | ||
869 | path = btrfs_alloc_path(); | 957 | path = btrfs_alloc_path(); |
@@ -872,7 +960,10 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr, | |||
872 | if (ret < 0) | 960 | if (ret < 0) |
873 | goto out; | 961 | goto out; |
874 | BUG_ON(ret == 0); | 962 | BUG_ON(ret == 0); |
963 | if (ret < 0 || path->slots[0] == 0) | ||
964 | goto out; | ||
875 | 965 | ||
966 | path->slots[0]--; | ||
876 | leaf = path->nodes[0]; | 967 | leaf = path->nodes[0]; |
877 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | 968 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
878 | 969 | ||
@@ -909,7 +1000,7 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr, | |||
909 | struct btrfs_extent_ref); | 1000 | struct btrfs_extent_ref); |
910 | ref_generation = btrfs_ref_generation(leaf, ref_item); | 1001 | ref_generation = btrfs_ref_generation(leaf, ref_item); |
911 | /* | 1002 | /* |
912 | * For (parent_gen > 0 && parent_gen > ref_gen): | 1003 | * For (parent_gen > 0 && parent_gen > ref_generation): |
913 | * | 1004 | * |
914 | * we reach here through the oldest root, therefore | 1005 | * we reach here through the oldest root, therefore |
915 | * all other reference from same snapshot should have | 1006 | * all other reference from same snapshot should have |
@@ -919,8 +1010,7 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr, | |||
919 | (parent_gen > 0 && parent_gen > ref_generation) || | 1010 | (parent_gen > 0 && parent_gen > ref_generation) || |
920 | (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID && | 1011 | (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID && |
921 | ref_objectid != btrfs_ref_objectid(leaf, ref_item))) { | 1012 | ref_objectid != btrfs_ref_objectid(leaf, ref_item))) { |
922 | if (ref_count) | 1013 | *ref_count = 2; |
923 | *ref_count = 2; | ||
924 | break; | 1014 | break; |
925 | } | 1015 | } |
926 | 1016 | ||
@@ -1020,80 +1110,29 @@ out: | |||
1020 | return ret; | 1110 | return ret; |
1021 | } | 1111 | } |
1022 | 1112 | ||
1023 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 1113 | int btrfs_cache_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
1024 | struct extent_buffer *buf, int cache_ref) | 1114 | struct extent_buffer *buf, u32 nr_extents) |
1025 | { | 1115 | { |
1026 | u64 bytenr; | ||
1027 | u32 nritems; | 1116 | u32 nritems; |
1028 | struct btrfs_key key; | 1117 | struct btrfs_key key; |
1029 | struct btrfs_file_extent_item *fi; | 1118 | struct btrfs_file_extent_item *fi; |
1030 | int i; | 1119 | int i; |
1031 | int level; | 1120 | int level; |
1032 | int ret; | 1121 | int ret = 0; |
1033 | int faili; | ||
1034 | int nr_file_extents = 0; | ||
1035 | 1122 | ||
1036 | if (!root->ref_cows) | 1123 | if (!root->ref_cows) |
1037 | return 0; | 1124 | return 0; |
1038 | 1125 | ||
1039 | level = btrfs_header_level(buf); | 1126 | level = btrfs_header_level(buf); |
1040 | nritems = btrfs_header_nritems(buf); | 1127 | nritems = btrfs_header_nritems(buf); |
1041 | for (i = 0; i < nritems; i++) { | ||
1042 | cond_resched(); | ||
1043 | if (level == 0) { | ||
1044 | u64 disk_bytenr; | ||
1045 | btrfs_item_key_to_cpu(buf, &key, i); | ||
1046 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | ||
1047 | continue; | ||
1048 | fi = btrfs_item_ptr(buf, i, | ||
1049 | struct btrfs_file_extent_item); | ||
1050 | if (btrfs_file_extent_type(buf, fi) == | ||
1051 | BTRFS_FILE_EXTENT_INLINE) | ||
1052 | continue; | ||
1053 | disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); | ||
1054 | if (disk_bytenr == 0) | ||
1055 | continue; | ||
1056 | |||
1057 | if (buf != root->commit_root) | ||
1058 | nr_file_extents++; | ||
1059 | |||
1060 | mutex_lock(&root->fs_info->alloc_mutex); | ||
1061 | ret = __btrfs_inc_extent_ref(trans, root, disk_bytenr, | ||
1062 | btrfs_file_extent_disk_num_bytes(buf, fi), | ||
1063 | root->root_key.objectid, trans->transid, | ||
1064 | key.objectid, key.offset); | ||
1065 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
1066 | if (ret) { | ||
1067 | faili = i; | ||
1068 | WARN_ON(1); | ||
1069 | goto fail; | ||
1070 | } | ||
1071 | } else { | ||
1072 | bytenr = btrfs_node_blockptr(buf, i); | ||
1073 | btrfs_node_key_to_cpu(buf, &key, i); | ||
1074 | 1128 | ||
1075 | mutex_lock(&root->fs_info->alloc_mutex); | 1129 | if (level == 0) { |
1076 | ret = __btrfs_inc_extent_ref(trans, root, bytenr, | ||
1077 | btrfs_level_size(root, level - 1), | ||
1078 | root->root_key.objectid, | ||
1079 | trans->transid, | ||
1080 | level - 1, key.objectid); | ||
1081 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
1082 | if (ret) { | ||
1083 | faili = i; | ||
1084 | WARN_ON(1); | ||
1085 | goto fail; | ||
1086 | } | ||
1087 | } | ||
1088 | } | ||
1089 | /* cache orignal leaf block's references */ | ||
1090 | if (level == 0 && cache_ref && buf != root->commit_root) { | ||
1091 | struct btrfs_leaf_ref *ref; | 1130 | struct btrfs_leaf_ref *ref; |
1092 | struct btrfs_extent_info *info; | 1131 | struct btrfs_extent_info *info; |
1093 | 1132 | ||
1094 | ref = btrfs_alloc_leaf_ref(root, nr_file_extents); | 1133 | ref = btrfs_alloc_leaf_ref(root, nr_extents); |
1095 | if (!ref) { | 1134 | if (!ref) { |
1096 | WARN_ON(1); | 1135 | ret = -ENOMEM; |
1097 | goto out; | 1136 | goto out; |
1098 | } | 1137 | } |
1099 | 1138 | ||
@@ -1101,10 +1140,10 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1101 | ref->bytenr = buf->start; | 1140 | ref->bytenr = buf->start; |
1102 | ref->owner = btrfs_header_owner(buf); | 1141 | ref->owner = btrfs_header_owner(buf); |
1103 | ref->generation = btrfs_header_generation(buf); | 1142 | ref->generation = btrfs_header_generation(buf); |
1104 | ref->nritems = nr_file_extents; | 1143 | ref->nritems = nr_extents; |
1105 | info = ref->extents; | 1144 | info = ref->extents; |
1106 | 1145 | ||
1107 | for (i = 0; nr_file_extents > 0 && i < nritems; i++) { | 1146 | for (i = 0; nr_extents > 0 && i < nritems; i++) { |
1108 | u64 disk_bytenr; | 1147 | u64 disk_bytenr; |
1109 | btrfs_item_key_to_cpu(buf, &key, i); | 1148 | btrfs_item_key_to_cpu(buf, &key, i); |
1110 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 1149 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
@@ -1132,13 +1171,52 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1132 | btrfs_free_leaf_ref(root, ref); | 1171 | btrfs_free_leaf_ref(root, ref); |
1133 | } | 1172 | } |
1134 | out: | 1173 | out: |
1135 | return 0; | 1174 | return ret; |
1136 | fail: | 1175 | } |
1137 | WARN_ON(1); | 1176 | |
1138 | #if 0 | 1177 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
1139 | for (i =0; i < faili; i++) { | 1178 | struct extent_buffer *orig_buf, struct extent_buffer *buf, |
1179 | u32 *nr_extents) | ||
1180 | { | ||
1181 | u64 bytenr; | ||
1182 | u64 ref_root; | ||
1183 | u64 orig_root; | ||
1184 | u64 ref_generation; | ||
1185 | u64 orig_generation; | ||
1186 | u32 nritems; | ||
1187 | u32 nr_file_extents = 0; | ||
1188 | struct btrfs_key key; | ||
1189 | struct btrfs_file_extent_item *fi; | ||
1190 | int i; | ||
1191 | int level; | ||
1192 | int ret = 0; | ||
1193 | int faili = 0; | ||
1194 | int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, | ||
1195 | u64, u64, u64, u64, u64, u64, u64, u64, u64); | ||
1196 | |||
1197 | ref_root = btrfs_header_owner(buf); | ||
1198 | ref_generation = btrfs_header_generation(buf); | ||
1199 | orig_root = btrfs_header_owner(orig_buf); | ||
1200 | orig_generation = btrfs_header_generation(orig_buf); | ||
1201 | |||
1202 | nritems = btrfs_header_nritems(buf); | ||
1203 | level = btrfs_header_level(buf); | ||
1204 | |||
1205 | if (root->ref_cows) { | ||
1206 | process_func = __btrfs_inc_extent_ref; | ||
1207 | } else { | ||
1208 | if (level == 0 && | ||
1209 | root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) | ||
1210 | goto out; | ||
1211 | if (level != 0 && | ||
1212 | root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) | ||
1213 | goto out; | ||
1214 | process_func = __btrfs_update_extent_ref; | ||
1215 | } | ||
1216 | |||
1217 | for (i = 0; i < nritems; i++) { | ||
1218 | cond_resched(); | ||
1140 | if (level == 0) { | 1219 | if (level == 0) { |
1141 | u64 disk_bytenr; | ||
1142 | btrfs_item_key_to_cpu(buf, &key, i); | 1220 | btrfs_item_key_to_cpu(buf, &key, i); |
1143 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | 1221 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) |
1144 | continue; | 1222 | continue; |
@@ -1147,24 +1225,131 @@ fail: | |||
1147 | if (btrfs_file_extent_type(buf, fi) == | 1225 | if (btrfs_file_extent_type(buf, fi) == |
1148 | BTRFS_FILE_EXTENT_INLINE) | 1226 | BTRFS_FILE_EXTENT_INLINE) |
1149 | continue; | 1227 | continue; |
1150 | disk_bytenr = btrfs_file_extent_disk_bytenr(buf, fi); | 1228 | bytenr = btrfs_file_extent_disk_bytenr(buf, fi); |
1151 | if (disk_bytenr == 0) | 1229 | if (bytenr == 0) |
1152 | continue; | 1230 | continue; |
1153 | err = btrfs_free_extent(trans, root, disk_bytenr, | 1231 | |
1154 | btrfs_file_extent_disk_num_bytes(buf, | 1232 | nr_file_extents++; |
1155 | fi), 0); | 1233 | |
1156 | BUG_ON(err); | 1234 | maybe_lock_mutex(root); |
1235 | ret = process_func(trans, root, bytenr, | ||
1236 | orig_buf->start, buf->start, | ||
1237 | orig_root, ref_root, | ||
1238 | orig_generation, ref_generation, | ||
1239 | key.objectid, key.offset); | ||
1240 | maybe_unlock_mutex(root); | ||
1241 | |||
1242 | if (ret) { | ||
1243 | faili = i; | ||
1244 | WARN_ON(1); | ||
1245 | goto fail; | ||
1246 | } | ||
1157 | } else { | 1247 | } else { |
1158 | bytenr = btrfs_node_blockptr(buf, i); | 1248 | bytenr = btrfs_node_blockptr(buf, i); |
1159 | err = btrfs_free_extent(trans, root, bytenr, | 1249 | maybe_lock_mutex(root); |
1160 | btrfs_level_size(root, level - 1), 0); | 1250 | ret = process_func(trans, root, bytenr, |
1161 | BUG_ON(err); | 1251 | orig_buf->start, buf->start, |
1252 | orig_root, ref_root, | ||
1253 | orig_generation, ref_generation, | ||
1254 | level - 1, 0); | ||
1255 | maybe_unlock_mutex(root); | ||
1256 | if (ret) { | ||
1257 | faili = i; | ||
1258 | WARN_ON(1); | ||
1259 | goto fail; | ||
1260 | } | ||
1162 | } | 1261 | } |
1163 | } | 1262 | } |
1164 | #endif | 1263 | out: |
1264 | if (nr_extents) { | ||
1265 | if (level == 0) | ||
1266 | *nr_extents = nr_file_extents; | ||
1267 | else | ||
1268 | *nr_extents = nritems; | ||
1269 | } | ||
1270 | return 0; | ||
1271 | fail: | ||
1272 | WARN_ON(1); | ||
1165 | return ret; | 1273 | return ret; |
1166 | } | 1274 | } |
1167 | 1275 | ||
1276 | int btrfs_update_ref(struct btrfs_trans_handle *trans, | ||
1277 | struct btrfs_root *root, struct extent_buffer *orig_buf, | ||
1278 | struct extent_buffer *buf, int start_slot, int nr) | ||
1279 | |||
1280 | { | ||
1281 | u64 bytenr; | ||
1282 | u64 ref_root; | ||
1283 | u64 orig_root; | ||
1284 | u64 ref_generation; | ||
1285 | u64 orig_generation; | ||
1286 | struct btrfs_key key; | ||
1287 | struct btrfs_file_extent_item *fi; | ||
1288 | int i; | ||
1289 | int ret; | ||
1290 | int slot; | ||
1291 | int level; | ||
1292 | |||
1293 | BUG_ON(start_slot < 0); | ||
1294 | BUG_ON(start_slot + nr > btrfs_header_nritems(buf)); | ||
1295 | |||
1296 | ref_root = btrfs_header_owner(buf); | ||
1297 | ref_generation = btrfs_header_generation(buf); | ||
1298 | orig_root = btrfs_header_owner(orig_buf); | ||
1299 | orig_generation = btrfs_header_generation(orig_buf); | ||
1300 | level = btrfs_header_level(buf); | ||
1301 | |||
1302 | if (!root->ref_cows) { | ||
1303 | if (level == 0 && | ||
1304 | root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) | ||
1305 | return 0; | ||
1306 | if (level != 0 && | ||
1307 | root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) | ||
1308 | return 0; | ||
1309 | } | ||
1310 | |||
1311 | for (i = 0, slot = start_slot; i < nr; i++, slot++) { | ||
1312 | cond_resched(); | ||
1313 | if (level == 0) { | ||
1314 | btrfs_item_key_to_cpu(buf, &key, slot); | ||
1315 | if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) | ||
1316 | continue; | ||
1317 | fi = btrfs_item_ptr(buf, slot, | ||
1318 | struct btrfs_file_extent_item); | ||
1319 | if (btrfs_file_extent_type(buf, fi) == | ||
1320 | BTRFS_FILE_EXTENT_INLINE) | ||
1321 | continue; | ||
1322 | bytenr = btrfs_file_extent_disk_bytenr(buf, fi); | ||
1323 | if (bytenr == 0) | ||
1324 | continue; | ||
1325 | maybe_lock_mutex(root); | ||
1326 | ret = __btrfs_update_extent_ref(trans, root, bytenr, | ||
1327 | orig_buf->start, buf->start, | ||
1328 | orig_root, ref_root, | ||
1329 | orig_generation, ref_generation, | ||
1330 | key.objectid, key.offset); | ||
1331 | maybe_unlock_mutex(root); | ||
1332 | if (ret) | ||
1333 | goto fail; | ||
1334 | } else { | ||
1335 | bytenr = btrfs_node_blockptr(buf, slot); | ||
1336 | maybe_lock_mutex(root); | ||
1337 | ret = __btrfs_update_extent_ref(trans, root, bytenr, | ||
1338 | orig_buf->start, buf->start, | ||
1339 | orig_root, ref_root, | ||
1340 | orig_generation, ref_generation, | ||
1341 | level - 1, 0); | ||
1342 | maybe_unlock_mutex(root); | ||
1343 | if (ret) | ||
1344 | goto fail; | ||
1345 | } | ||
1346 | } | ||
1347 | return 0; | ||
1348 | fail: | ||
1349 | WARN_ON(1); | ||
1350 | return -1; | ||
1351 | } | ||
1352 | |||
1168 | static int write_one_cache_group(struct btrfs_trans_handle *trans, | 1353 | static int write_one_cache_group(struct btrfs_trans_handle *trans, |
1169 | struct btrfs_root *root, | 1354 | struct btrfs_root *root, |
1170 | struct btrfs_path *path, | 1355 | struct btrfs_path *path, |
@@ -1539,19 +1724,18 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
1539 | { | 1724 | { |
1540 | u64 start; | 1725 | u64 start; |
1541 | u64 end; | 1726 | u64 end; |
1727 | u64 priv; | ||
1542 | struct btrfs_fs_info *info = extent_root->fs_info; | 1728 | struct btrfs_fs_info *info = extent_root->fs_info; |
1543 | struct extent_buffer *eb; | ||
1544 | struct btrfs_path *path; | 1729 | struct btrfs_path *path; |
1545 | struct btrfs_key ins; | 1730 | struct btrfs_extent_ref *ref; |
1546 | struct btrfs_disk_key first; | 1731 | struct pending_extent_op *extent_op; |
1732 | struct btrfs_key key; | ||
1547 | struct btrfs_extent_item extent_item; | 1733 | struct btrfs_extent_item extent_item; |
1548 | int ret; | 1734 | int ret; |
1549 | int level; | ||
1550 | int err = 0; | 1735 | int err = 0; |
1551 | 1736 | ||
1552 | WARN_ON(!mutex_is_locked(&extent_root->fs_info->alloc_mutex)); | 1737 | WARN_ON(!mutex_is_locked(&extent_root->fs_info->alloc_mutex)); |
1553 | btrfs_set_stack_extent_refs(&extent_item, 1); | 1738 | btrfs_set_stack_extent_refs(&extent_item, 1); |
1554 | btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY); | ||
1555 | path = btrfs_alloc_path(); | 1739 | path = btrfs_alloc_path(); |
1556 | 1740 | ||
1557 | while(1) { | 1741 | while(1) { |
@@ -1560,37 +1744,54 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
1560 | if (ret) | 1744 | if (ret) |
1561 | break; | 1745 | break; |
1562 | 1746 | ||
1563 | ins.objectid = start; | 1747 | ret = get_state_private(&info->extent_ins, start, &priv); |
1564 | ins.offset = end + 1 - start; | 1748 | BUG_ON(ret); |
1565 | err = btrfs_insert_item(trans, extent_root, &ins, | 1749 | extent_op = (struct pending_extent_op *)(unsigned long)priv; |
1750 | |||
1751 | if (extent_op->type == PENDING_EXTENT_INSERT) { | ||
1752 | key.objectid = start; | ||
1753 | key.offset = end + 1 - start; | ||
1754 | key.type = BTRFS_EXTENT_ITEM_KEY; | ||
1755 | err = btrfs_insert_item(trans, extent_root, &key, | ||
1566 | &extent_item, sizeof(extent_item)); | 1756 | &extent_item, sizeof(extent_item)); |
1567 | clear_extent_bits(&info->extent_ins, start, end, EXTENT_LOCKED, | 1757 | BUG_ON(err); |
1568 | GFP_NOFS); | ||
1569 | 1758 | ||
1570 | eb = btrfs_find_create_tree_block(extent_root, ins.objectid, | 1759 | clear_extent_bits(&info->extent_ins, start, end, |
1571 | ins.offset); | 1760 | EXTENT_LOCKED, GFP_NOFS); |
1572 | 1761 | ||
1573 | if (!btrfs_buffer_uptodate(eb, trans->transid)) | 1762 | err = insert_extent_backref(trans, extent_root, path, |
1574 | btrfs_read_buffer(eb, trans->transid); | 1763 | start, extent_op->parent, |
1764 | extent_root->root_key.objectid, | ||
1765 | extent_op->generation, | ||
1766 | extent_op->level, 0); | ||
1767 | BUG_ON(err); | ||
1768 | } else if (extent_op->type == PENDING_BACKREF_UPDATE) { | ||
1769 | err = lookup_extent_backref(trans, extent_root, path, | ||
1770 | start, extent_op->orig_parent, | ||
1771 | extent_root->root_key.objectid, | ||
1772 | extent_op->orig_generation, 0); | ||
1773 | BUG_ON(err); | ||
1575 | 1774 | ||
1576 | btrfs_tree_lock(eb); | 1775 | clear_extent_bits(&info->extent_ins, start, end, |
1577 | level = btrfs_header_level(eb); | 1776 | EXTENT_LOCKED, GFP_NOFS); |
1578 | if (level == 0) { | 1777 | |
1579 | btrfs_item_key(eb, &first, 0); | 1778 | key.objectid = start; |
1779 | key.offset = extent_op->parent; | ||
1780 | key.type = BTRFS_EXTENT_REF_KEY; | ||
1781 | err = btrfs_set_item_key_safe(trans, extent_root, path, | ||
1782 | &key); | ||
1783 | BUG_ON(err); | ||
1784 | ref = btrfs_item_ptr(path->nodes[0], path->slots[0], | ||
1785 | struct btrfs_extent_ref); | ||
1786 | btrfs_set_ref_generation(path->nodes[0], ref, | ||
1787 | extent_op->generation); | ||
1788 | btrfs_mark_buffer_dirty(path->nodes[0]); | ||
1789 | btrfs_release_path(extent_root, path); | ||
1580 | } else { | 1790 | } else { |
1581 | btrfs_node_key(eb, &first, 0); | 1791 | BUG_ON(1); |
1582 | } | 1792 | } |
1583 | btrfs_tree_unlock(eb); | 1793 | kfree(extent_op); |
1584 | free_extent_buffer(eb); | 1794 | |
1585 | /* | ||
1586 | * the first key is just a hint, so the race we've created | ||
1587 | * against reading it is fine | ||
1588 | */ | ||
1589 | err = btrfs_insert_extent_backref(trans, extent_root, path, | ||
1590 | start, extent_root->root_key.objectid, | ||
1591 | 0, level, | ||
1592 | btrfs_disk_key_objectid(&first)); | ||
1593 | BUG_ON(err); | ||
1594 | if (need_resched()) { | 1795 | if (need_resched()) { |
1595 | mutex_unlock(&extent_root->fs_info->alloc_mutex); | 1796 | mutex_unlock(&extent_root->fs_info->alloc_mutex); |
1596 | cond_resched(); | 1797 | cond_resched(); |
@@ -1601,52 +1802,44 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
1601 | return 0; | 1802 | return 0; |
1602 | } | 1803 | } |
1603 | 1804 | ||
1604 | static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes, | 1805 | static int pin_down_bytes(struct btrfs_trans_handle *trans, |
1605 | int is_data, int pending) | 1806 | struct btrfs_root *root, |
1807 | u64 bytenr, u64 num_bytes, int is_data) | ||
1606 | { | 1808 | { |
1607 | int err = 0; | 1809 | int err = 0; |
1810 | struct extent_buffer *buf; | ||
1608 | 1811 | ||
1609 | WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex)); | 1812 | WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex)); |
1610 | if (!pending) { | 1813 | if (is_data) |
1611 | struct extent_buffer *buf; | 1814 | goto pinit; |
1612 | 1815 | ||
1613 | if (is_data) | 1816 | buf = btrfs_find_tree_block(root, bytenr, num_bytes); |
1614 | goto pinit; | 1817 | if (!buf) |
1615 | 1818 | goto pinit; | |
1616 | buf = btrfs_find_tree_block(root, bytenr, num_bytes); | 1819 | |
1617 | if (buf) { | 1820 | /* we can reuse a block if it hasn't been written |
1618 | /* we can reuse a block if it hasn't been written | 1821 | * and it is from this transaction. We can't |
1619 | * and it is from this transaction. We can't | 1822 | * reuse anything from the tree log root because |
1620 | * reuse anything from the tree log root because | 1823 | * it has tiny sub-transactions. |
1621 | * it has tiny sub-transactions. | 1824 | */ |
1622 | */ | 1825 | if (btrfs_buffer_uptodate(buf, 0) && |
1623 | if (btrfs_buffer_uptodate(buf, 0) && | 1826 | btrfs_try_tree_lock(buf)) { |
1624 | btrfs_try_tree_lock(buf)) { | 1827 | u64 header_owner = btrfs_header_owner(buf); |
1625 | u64 transid = | 1828 | u64 header_transid = btrfs_header_generation(buf); |
1626 | root->fs_info->running_transaction->transid; | 1829 | if (header_owner != BTRFS_TREE_LOG_OBJECTID && |
1627 | u64 header_transid = | 1830 | header_transid == trans->transid && |
1628 | btrfs_header_generation(buf); | 1831 | !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { |
1629 | if (btrfs_header_owner(buf) != | 1832 | clean_tree_block(NULL, root, buf); |
1630 | BTRFS_TREE_LOG_OBJECTID && | 1833 | btrfs_tree_unlock(buf); |
1631 | header_transid == transid && | ||
1632 | !btrfs_header_flag(buf, | ||
1633 | BTRFS_HEADER_FLAG_WRITTEN)) { | ||
1634 | clean_tree_block(NULL, root, buf); | ||
1635 | btrfs_tree_unlock(buf); | ||
1636 | free_extent_buffer(buf); | ||
1637 | return 1; | ||
1638 | } | ||
1639 | btrfs_tree_unlock(buf); | ||
1640 | } | ||
1641 | free_extent_buffer(buf); | 1834 | free_extent_buffer(buf); |
1835 | return 1; | ||
1642 | } | 1836 | } |
1643 | pinit: | 1837 | btrfs_tree_unlock(buf); |
1644 | btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); | ||
1645 | } else { | ||
1646 | set_extent_bits(&root->fs_info->pending_del, | ||
1647 | bytenr, bytenr + num_bytes - 1, | ||
1648 | EXTENT_LOCKED, GFP_NOFS); | ||
1649 | } | 1838 | } |
1839 | free_extent_buffer(buf); | ||
1840 | pinit: | ||
1841 | btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); | ||
1842 | |||
1650 | BUG_ON(err < 0); | 1843 | BUG_ON(err < 0); |
1651 | return 0; | 1844 | return 0; |
1652 | } | 1845 | } |
@@ -1654,11 +1847,12 @@ pinit: | |||
1654 | /* | 1847 | /* |
1655 | * remove an extent from the root, returns 0 on success | 1848 | * remove an extent from the root, returns 0 on success |
1656 | */ | 1849 | */ |
1657 | static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 1850 | static int __free_extent(struct btrfs_trans_handle *trans, |
1658 | *root, u64 bytenr, u64 num_bytes, | 1851 | struct btrfs_root *root, |
1852 | u64 bytenr, u64 num_bytes, u64 parent, | ||
1659 | u64 root_objectid, u64 ref_generation, | 1853 | u64 root_objectid, u64 ref_generation, |
1660 | u64 owner_objectid, u64 owner_offset, int pin, | 1854 | u64 owner_objectid, u64 owner_offset, |
1661 | int mark_free) | 1855 | int pin, int mark_free) |
1662 | { | 1856 | { |
1663 | struct btrfs_path *path; | 1857 | struct btrfs_path *path; |
1664 | struct btrfs_key key; | 1858 | struct btrfs_key key; |
@@ -1681,10 +1875,8 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1681 | return -ENOMEM; | 1875 | return -ENOMEM; |
1682 | 1876 | ||
1683 | path->reada = 1; | 1877 | path->reada = 1; |
1684 | ret = lookup_extent_backref(trans, extent_root, path, | 1878 | ret = lookup_extent_backref(trans, extent_root, path, bytenr, parent, |
1685 | bytenr, root_objectid, | 1879 | root_objectid, ref_generation, 1); |
1686 | ref_generation, | ||
1687 | owner_objectid, owner_offset, 1); | ||
1688 | if (ret == 0) { | 1880 | if (ret == 0) { |
1689 | struct btrfs_key found_key; | 1881 | struct btrfs_key found_key; |
1690 | extent_slot = path->slots[0]; | 1882 | extent_slot = path->slots[0]; |
@@ -1702,8 +1894,15 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1702 | if (path->slots[0] - extent_slot > 5) | 1894 | if (path->slots[0] - extent_slot > 5) |
1703 | break; | 1895 | break; |
1704 | } | 1896 | } |
1705 | if (!found_extent) | 1897 | if (!found_extent) { |
1706 | ret = btrfs_del_item(trans, extent_root, path); | 1898 | ret = remove_extent_backref(trans, extent_root, path); |
1899 | BUG_ON(ret); | ||
1900 | btrfs_release_path(extent_root, path); | ||
1901 | ret = btrfs_search_slot(trans, extent_root, | ||
1902 | &key, path, -1, 1); | ||
1903 | BUG_ON(ret); | ||
1904 | extent_slot = path->slots[0]; | ||
1905 | } | ||
1707 | } else { | 1906 | } else { |
1708 | btrfs_print_leaf(extent_root, path->nodes[0]); | 1907 | btrfs_print_leaf(extent_root, path->nodes[0]); |
1709 | WARN_ON(1); | 1908 | WARN_ON(1); |
@@ -1712,14 +1911,6 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1712 | root_objectid, ref_generation, owner_objectid, | 1911 | root_objectid, ref_generation, owner_objectid, |
1713 | owner_offset); | 1912 | owner_offset); |
1714 | } | 1913 | } |
1715 | if (!found_extent) { | ||
1716 | btrfs_release_path(extent_root, path); | ||
1717 | ret = btrfs_search_slot(trans, extent_root, &key, path, -1, 1); | ||
1718 | if (ret < 0) | ||
1719 | return ret; | ||
1720 | BUG_ON(ret); | ||
1721 | extent_slot = path->slots[0]; | ||
1722 | } | ||
1723 | 1914 | ||
1724 | leaf = path->nodes[0]; | 1915 | leaf = path->nodes[0]; |
1725 | ei = btrfs_item_ptr(leaf, extent_slot, | 1916 | ei = btrfs_item_ptr(leaf, extent_slot, |
@@ -1732,6 +1923,10 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1732 | btrfs_mark_buffer_dirty(leaf); | 1923 | btrfs_mark_buffer_dirty(leaf); |
1733 | 1924 | ||
1734 | if (refs == 0 && found_extent && path->slots[0] == extent_slot + 1) { | 1925 | if (refs == 0 && found_extent && path->slots[0] == extent_slot + 1) { |
1926 | struct btrfs_extent_ref *ref; | ||
1927 | ref = btrfs_item_ptr(leaf, path->slots[0], | ||
1928 | struct btrfs_extent_ref); | ||
1929 | BUG_ON(btrfs_ref_num_refs(leaf, ref) != 1); | ||
1735 | /* if the back ref and the extent are next to each other | 1930 | /* if the back ref and the extent are next to each other |
1736 | * they get deleted below in one shot | 1931 | * they get deleted below in one shot |
1737 | */ | 1932 | */ |
@@ -1739,15 +1934,13 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1739 | num_to_del = 2; | 1934 | num_to_del = 2; |
1740 | } else if (found_extent) { | 1935 | } else if (found_extent) { |
1741 | /* otherwise delete the extent back ref */ | 1936 | /* otherwise delete the extent back ref */ |
1742 | ret = btrfs_del_item(trans, extent_root, path); | 1937 | ret = remove_extent_backref(trans, extent_root, path); |
1743 | BUG_ON(ret); | 1938 | BUG_ON(ret); |
1744 | /* if refs are 0, we need to setup the path for deletion */ | 1939 | /* if refs are 0, we need to setup the path for deletion */ |
1745 | if (refs == 0) { | 1940 | if (refs == 0) { |
1746 | btrfs_release_path(extent_root, path); | 1941 | btrfs_release_path(extent_root, path); |
1747 | ret = btrfs_search_slot(trans, extent_root, &key, path, | 1942 | ret = btrfs_search_slot(trans, extent_root, &key, path, |
1748 | -1, 1); | 1943 | -1, 1); |
1749 | if (ret < 0) | ||
1750 | return ret; | ||
1751 | BUG_ON(ret); | 1944 | BUG_ON(ret); |
1752 | } | 1945 | } |
1753 | } | 1946 | } |
@@ -1761,8 +1954,8 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1761 | #endif | 1954 | #endif |
1762 | 1955 | ||
1763 | if (pin) { | 1956 | if (pin) { |
1764 | ret = pin_down_bytes(root, bytenr, num_bytes, | 1957 | ret = pin_down_bytes(trans, root, bytenr, num_bytes, |
1765 | owner_objectid >= BTRFS_FIRST_FREE_OBJECTID, 0); | 1958 | owner_objectid >= BTRFS_FIRST_FREE_OBJECTID); |
1766 | if (ret > 0) | 1959 | if (ret > 0) |
1767 | mark_free = 1; | 1960 | mark_free = 1; |
1768 | BUG_ON(ret < 0); | 1961 | BUG_ON(ret < 0); |
@@ -1781,9 +1974,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1781 | root_used - num_bytes); | 1974 | root_used - num_bytes); |
1782 | ret = btrfs_del_items(trans, extent_root, path, path->slots[0], | 1975 | ret = btrfs_del_items(trans, extent_root, path, path->slots[0], |
1783 | num_to_del); | 1976 | num_to_del); |
1784 | if (ret) { | 1977 | BUG_ON(ret); |
1785 | return ret; | ||
1786 | } | ||
1787 | ret = update_block_group(trans, root, bytenr, num_bytes, 0, | 1978 | ret = update_block_group(trans, root, bytenr, num_bytes, 0, |
1788 | mark_free); | 1979 | mark_free); |
1789 | BUG_ON(ret); | 1980 | BUG_ON(ret); |
@@ -1822,33 +2013,61 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct | |||
1822 | { | 2013 | { |
1823 | int ret; | 2014 | int ret; |
1824 | int err = 0; | 2015 | int err = 0; |
2016 | int mark_free = 0; | ||
1825 | u64 start; | 2017 | u64 start; |
1826 | u64 end; | 2018 | u64 end; |
2019 | u64 priv; | ||
1827 | struct extent_io_tree *pending_del; | 2020 | struct extent_io_tree *pending_del; |
1828 | struct extent_io_tree *pinned_extents; | 2021 | struct extent_io_tree *extent_ins; |
2022 | struct pending_extent_op *extent_op; | ||
1829 | 2023 | ||
1830 | WARN_ON(!mutex_is_locked(&extent_root->fs_info->alloc_mutex)); | 2024 | WARN_ON(!mutex_is_locked(&extent_root->fs_info->alloc_mutex)); |
2025 | extent_ins = &extent_root->fs_info->extent_ins; | ||
1831 | pending_del = &extent_root->fs_info->pending_del; | 2026 | pending_del = &extent_root->fs_info->pending_del; |
1832 | pinned_extents = &extent_root->fs_info->pinned_extents; | ||
1833 | 2027 | ||
1834 | while(1) { | 2028 | while(1) { |
1835 | ret = find_first_extent_bit(pending_del, 0, &start, &end, | 2029 | ret = find_first_extent_bit(pending_del, 0, &start, &end, |
1836 | EXTENT_LOCKED); | 2030 | EXTENT_LOCKED); |
1837 | if (ret) | 2031 | if (ret) |
1838 | break; | 2032 | break; |
2033 | |||
2034 | ret = get_state_private(pending_del, start, &priv); | ||
2035 | BUG_ON(ret); | ||
2036 | extent_op = (struct pending_extent_op *)(unsigned long)priv; | ||
2037 | |||
1839 | clear_extent_bits(pending_del, start, end, EXTENT_LOCKED, | 2038 | clear_extent_bits(pending_del, start, end, EXTENT_LOCKED, |
1840 | GFP_NOFS); | 2039 | GFP_NOFS); |
1841 | if (!test_range_bit(&extent_root->fs_info->extent_ins, | 2040 | |
1842 | start, end, EXTENT_LOCKED, 0)) { | 2041 | ret = pin_down_bytes(trans, extent_root, start, |
1843 | btrfs_update_pinned_extents(extent_root, start, | 2042 | end + 1 - start, 0); |
1844 | end + 1 - start, 1); | 2043 | mark_free = ret > 0; |
2044 | if (!test_range_bit(extent_ins, start, end, | ||
2045 | EXTENT_LOCKED, 0)) { | ||
2046 | free_extent: | ||
1845 | ret = __free_extent(trans, extent_root, | 2047 | ret = __free_extent(trans, extent_root, |
1846 | start, end + 1 - start, | 2048 | start, end + 1 - start, |
1847 | extent_root->root_key.objectid, | 2049 | extent_op->orig_parent, |
1848 | 0, 0, 0, 0, 0); | 2050 | extent_root->root_key.objectid, |
2051 | extent_op->orig_generation, | ||
2052 | extent_op->level, 0, 0, mark_free); | ||
2053 | kfree(extent_op); | ||
1849 | } else { | 2054 | } else { |
1850 | clear_extent_bits(&extent_root->fs_info->extent_ins, | 2055 | kfree(extent_op); |
1851 | start, end, EXTENT_LOCKED, GFP_NOFS); | 2056 | ret = get_state_private(extent_ins, start, &priv); |
2057 | BUG_ON(ret); | ||
2058 | extent_op = (struct pending_extent_op *) | ||
2059 | (unsigned long)priv; | ||
2060 | |||
2061 | clear_extent_bits(extent_ins, start, end, | ||
2062 | EXTENT_LOCKED, GFP_NOFS); | ||
2063 | |||
2064 | if (extent_op->type == PENDING_BACKREF_UPDATE) | ||
2065 | goto free_extent; | ||
2066 | |||
2067 | ret = update_block_group(trans, extent_root, start, | ||
2068 | end + 1 - start, 0, mark_free); | ||
2069 | BUG_ON(ret); | ||
2070 | kfree(extent_op); | ||
1852 | } | 2071 | } |
1853 | if (ret) | 2072 | if (ret) |
1854 | err = ret; | 2073 | err = ret; |
@@ -1866,21 +2085,36 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct | |||
1866 | * remove an extent from the root, returns 0 on success | 2085 | * remove an extent from the root, returns 0 on success |
1867 | */ | 2086 | */ |
1868 | static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | 2087 | static int __btrfs_free_extent(struct btrfs_trans_handle *trans, |
1869 | struct btrfs_root *root, u64 bytenr, | 2088 | struct btrfs_root *root, |
1870 | u64 num_bytes, u64 root_objectid, | 2089 | u64 bytenr, u64 num_bytes, u64 parent, |
1871 | u64 ref_generation, u64 owner_objectid, | 2090 | u64 root_objectid, u64 ref_generation, |
1872 | u64 owner_offset, int pin) | 2091 | u64 owner_objectid, u64 owner_offset, int pin) |
1873 | { | 2092 | { |
1874 | struct btrfs_root *extent_root = root->fs_info->extent_root; | 2093 | struct btrfs_root *extent_root = root->fs_info->extent_root; |
1875 | int pending_ret; | 2094 | int pending_ret; |
1876 | int ret; | 2095 | int ret; |
1877 | 2096 | ||
1878 | WARN_ON(num_bytes < root->sectorsize); | 2097 | WARN_ON(num_bytes < root->sectorsize); |
1879 | if (!root->ref_cows) | ||
1880 | ref_generation = 0; | ||
1881 | |||
1882 | if (root == extent_root) { | 2098 | if (root == extent_root) { |
1883 | pin_down_bytes(root, bytenr, num_bytes, 0, 1); | 2099 | struct pending_extent_op *extent_op; |
2100 | |||
2101 | extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); | ||
2102 | BUG_ON(!extent_op); | ||
2103 | |||
2104 | extent_op->type = PENDING_EXTENT_DELETE; | ||
2105 | extent_op->bytenr = bytenr; | ||
2106 | extent_op->num_bytes = num_bytes; | ||
2107 | extent_op->parent = parent; | ||
2108 | extent_op->orig_parent = parent; | ||
2109 | extent_op->generation = ref_generation; | ||
2110 | extent_op->orig_generation = ref_generation; | ||
2111 | extent_op->level = (int)owner_objectid; | ||
2112 | |||
2113 | set_extent_bits(&root->fs_info->pending_del, | ||
2114 | bytenr, bytenr + num_bytes - 1, | ||
2115 | EXTENT_LOCKED, GFP_NOFS); | ||
2116 | set_state_private(&root->fs_info->pending_del, | ||
2117 | bytenr, (unsigned long)extent_op); | ||
1884 | return 0; | 2118 | return 0; |
1885 | } | 2119 | } |
1886 | /* if metadata always pin */ | 2120 | /* if metadata always pin */ |
@@ -1901,9 +2135,9 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
1901 | if (ref_generation != trans->transid) | 2135 | if (ref_generation != trans->transid) |
1902 | pin = 1; | 2136 | pin = 1; |
1903 | 2137 | ||
1904 | ret = __free_extent(trans, root, bytenr, num_bytes, root_objectid, | 2138 | ret = __free_extent(trans, root, bytenr, num_bytes, parent, |
1905 | ref_generation, owner_objectid, owner_offset, | 2139 | root_objectid, ref_generation, owner_objectid, |
1906 | pin, pin == 0); | 2140 | owner_offset, pin, pin == 0); |
1907 | 2141 | ||
1908 | finish_current_insert(trans, root->fs_info->extent_root); | 2142 | finish_current_insert(trans, root->fs_info->extent_root); |
1909 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root); | 2143 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root); |
@@ -1911,15 +2145,15 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
1911 | } | 2145 | } |
1912 | 2146 | ||
1913 | int btrfs_free_extent(struct btrfs_trans_handle *trans, | 2147 | int btrfs_free_extent(struct btrfs_trans_handle *trans, |
1914 | struct btrfs_root *root, u64 bytenr, | 2148 | struct btrfs_root *root, |
1915 | u64 num_bytes, u64 root_objectid, | 2149 | u64 bytenr, u64 num_bytes, u64 parent, |
1916 | u64 ref_generation, u64 owner_objectid, | 2150 | u64 root_objectid, u64 ref_generation, |
1917 | u64 owner_offset, int pin) | 2151 | u64 owner_objectid, u64 owner_offset, int pin) |
1918 | { | 2152 | { |
1919 | int ret; | 2153 | int ret; |
1920 | 2154 | ||
1921 | maybe_lock_mutex(root); | 2155 | maybe_lock_mutex(root); |
1922 | ret = __btrfs_free_extent(trans, root, bytenr, num_bytes, | 2156 | ret = __btrfs_free_extent(trans, root, bytenr, num_bytes, parent, |
1923 | root_objectid, ref_generation, | 2157 | root_objectid, ref_generation, |
1924 | owner_objectid, owner_offset, pin); | 2158 | owner_objectid, owner_offset, pin); |
1925 | maybe_unlock_mutex(root); | 2159 | maybe_unlock_mutex(root); |
@@ -2271,7 +2505,7 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, | |||
2271 | } | 2505 | } |
2272 | 2506 | ||
2273 | static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | 2507 | static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, |
2274 | struct btrfs_root *root, | 2508 | struct btrfs_root *root, u64 parent, |
2275 | u64 root_objectid, u64 ref_generation, | 2509 | u64 root_objectid, u64 ref_generation, |
2276 | u64 owner, u64 owner_offset, | 2510 | u64 owner, u64 owner_offset, |
2277 | struct btrfs_key *ins) | 2511 | struct btrfs_key *ins) |
@@ -2289,6 +2523,9 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2289 | struct btrfs_path *path; | 2523 | struct btrfs_path *path; |
2290 | struct btrfs_key keys[2]; | 2524 | struct btrfs_key keys[2]; |
2291 | 2525 | ||
2526 | if (parent == 0) | ||
2527 | parent = ins->objectid; | ||
2528 | |||
2292 | /* block accounting for super block */ | 2529 | /* block accounting for super block */ |
2293 | spin_lock_irq(&info->delalloc_lock); | 2530 | spin_lock_irq(&info->delalloc_lock); |
2294 | super_used = btrfs_super_bytes_used(&info->super_copy); | 2531 | super_used = btrfs_super_bytes_used(&info->super_copy); |
@@ -2300,17 +2537,32 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2300 | btrfs_set_root_used(&root->root_item, root_used + num_bytes); | 2537 | btrfs_set_root_used(&root->root_item, root_used + num_bytes); |
2301 | 2538 | ||
2302 | if (root == extent_root) { | 2539 | if (root == extent_root) { |
2540 | struct pending_extent_op *extent_op; | ||
2541 | |||
2542 | extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); | ||
2543 | BUG_ON(!extent_op); | ||
2544 | |||
2545 | extent_op->type = PENDING_EXTENT_INSERT; | ||
2546 | extent_op->bytenr = ins->objectid; | ||
2547 | extent_op->num_bytes = ins->offset; | ||
2548 | extent_op->parent = parent; | ||
2549 | extent_op->orig_parent = 0; | ||
2550 | extent_op->generation = ref_generation; | ||
2551 | extent_op->orig_generation = 0; | ||
2552 | extent_op->level = (int)owner; | ||
2553 | |||
2303 | set_extent_bits(&root->fs_info->extent_ins, ins->objectid, | 2554 | set_extent_bits(&root->fs_info->extent_ins, ins->objectid, |
2304 | ins->objectid + ins->offset - 1, | 2555 | ins->objectid + ins->offset - 1, |
2305 | EXTENT_LOCKED, GFP_NOFS); | 2556 | EXTENT_LOCKED, GFP_NOFS); |
2557 | set_state_private(&root->fs_info->extent_ins, | ||
2558 | ins->objectid, (unsigned long)extent_op); | ||
2306 | goto update_block; | 2559 | goto update_block; |
2307 | } | 2560 | } |
2308 | 2561 | ||
2309 | memcpy(&keys[0], ins, sizeof(*ins)); | 2562 | memcpy(&keys[0], ins, sizeof(*ins)); |
2310 | keys[1].offset = hash_extent_ref(root_objectid, ref_generation, | ||
2311 | owner, owner_offset); | ||
2312 | keys[1].objectid = ins->objectid; | 2563 | keys[1].objectid = ins->objectid; |
2313 | keys[1].type = BTRFS_EXTENT_REF_KEY; | 2564 | keys[1].type = BTRFS_EXTENT_REF_KEY; |
2565 | keys[1].offset = parent; | ||
2314 | sizes[0] = sizeof(*extent_item); | 2566 | sizes[0] = sizeof(*extent_item); |
2315 | sizes[1] = sizeof(*ref); | 2567 | sizes[1] = sizeof(*ref); |
2316 | 2568 | ||
@@ -2331,6 +2583,7 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2331 | btrfs_set_ref_generation(path->nodes[0], ref, ref_generation); | 2583 | btrfs_set_ref_generation(path->nodes[0], ref, ref_generation); |
2332 | btrfs_set_ref_objectid(path->nodes[0], ref, owner); | 2584 | btrfs_set_ref_objectid(path->nodes[0], ref, owner); |
2333 | btrfs_set_ref_offset(path->nodes[0], ref, owner_offset); | 2585 | btrfs_set_ref_offset(path->nodes[0], ref, owner_offset); |
2586 | btrfs_set_ref_num_refs(path->nodes[0], ref, 1); | ||
2334 | 2587 | ||
2335 | btrfs_mark_buffer_dirty(path->nodes[0]); | 2588 | btrfs_mark_buffer_dirty(path->nodes[0]); |
2336 | 2589 | ||
@@ -2359,7 +2612,7 @@ out: | |||
2359 | } | 2612 | } |
2360 | 2613 | ||
2361 | int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | 2614 | int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, |
2362 | struct btrfs_root *root, | 2615 | struct btrfs_root *root, u64 parent, |
2363 | u64 root_objectid, u64 ref_generation, | 2616 | u64 root_objectid, u64 ref_generation, |
2364 | u64 owner, u64 owner_offset, | 2617 | u64 owner, u64 owner_offset, |
2365 | struct btrfs_key *ins) | 2618 | struct btrfs_key *ins) |
@@ -2369,9 +2622,9 @@ int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2369 | if (root_objectid == BTRFS_TREE_LOG_OBJECTID) | 2622 | if (root_objectid == BTRFS_TREE_LOG_OBJECTID) |
2370 | return 0; | 2623 | return 0; |
2371 | maybe_lock_mutex(root); | 2624 | maybe_lock_mutex(root); |
2372 | ret = __btrfs_alloc_reserved_extent(trans, root, root_objectid, | 2625 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, |
2373 | ref_generation, owner, | 2626 | root_objectid, ref_generation, |
2374 | owner_offset, ins); | 2627 | owner, owner_offset, ins); |
2375 | maybe_unlock_mutex(root); | 2628 | maybe_unlock_mutex(root); |
2376 | return ret; | 2629 | return ret; |
2377 | } | 2630 | } |
@@ -2382,7 +2635,7 @@ int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2382 | * space cache bits as well | 2635 | * space cache bits as well |
2383 | */ | 2636 | */ |
2384 | int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, | 2637 | int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, |
2385 | struct btrfs_root *root, | 2638 | struct btrfs_root *root, u64 parent, |
2386 | u64 root_objectid, u64 ref_generation, | 2639 | u64 root_objectid, u64 ref_generation, |
2387 | u64 owner, u64 owner_offset, | 2640 | u64 owner, u64 owner_offset, |
2388 | struct btrfs_key *ins) | 2641 | struct btrfs_key *ins) |
@@ -2396,10 +2649,9 @@ int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, | |||
2396 | 2649 | ||
2397 | ret = btrfs_remove_free_space(block_group, ins->objectid, ins->offset); | 2650 | ret = btrfs_remove_free_space(block_group, ins->objectid, ins->offset); |
2398 | BUG_ON(ret); | 2651 | BUG_ON(ret); |
2399 | 2652 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, | |
2400 | ret = __btrfs_alloc_reserved_extent(trans, root, root_objectid, | 2653 | root_objectid, ref_generation, |
2401 | ref_generation, owner, | 2654 | owner, owner_offset, ins); |
2402 | owner_offset, ins); | ||
2403 | maybe_unlock_mutex(root); | 2655 | maybe_unlock_mutex(root); |
2404 | return ret; | 2656 | return ret; |
2405 | } | 2657 | } |
@@ -2413,9 +2665,9 @@ int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, | |||
2413 | */ | 2665 | */ |
2414 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | 2666 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, |
2415 | struct btrfs_root *root, | 2667 | struct btrfs_root *root, |
2416 | u64 num_bytes, u64 min_alloc_size, | 2668 | u64 num_bytes, u64 parent, u64 min_alloc_size, |
2417 | u64 root_objectid, u64 ref_generation, | 2669 | u64 root_objectid, u64 ref_generation, |
2418 | u64 owner, u64 owner_offset, | 2670 | u64 owner_objectid, u64 owner_offset, |
2419 | u64 empty_size, u64 hint_byte, | 2671 | u64 empty_size, u64 hint_byte, |
2420 | u64 search_end, struct btrfs_key *ins, u64 data) | 2672 | u64 search_end, struct btrfs_key *ins, u64 data) |
2421 | { | 2673 | { |
@@ -2428,9 +2680,9 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
2428 | search_end, ins, data); | 2680 | search_end, ins, data); |
2429 | BUG_ON(ret); | 2681 | BUG_ON(ret); |
2430 | if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { | 2682 | if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { |
2431 | ret = __btrfs_alloc_reserved_extent(trans, root, root_objectid, | 2683 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, |
2432 | ref_generation, owner, | 2684 | root_objectid, ref_generation, |
2433 | owner_offset, ins); | 2685 | owner_objectid, owner_offset, ins); |
2434 | BUG_ON(ret); | 2686 | BUG_ON(ret); |
2435 | 2687 | ||
2436 | } | 2688 | } |
@@ -2468,10 +2720,9 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | |||
2468 | */ | 2720 | */ |
2469 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | 2721 | struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
2470 | struct btrfs_root *root, | 2722 | struct btrfs_root *root, |
2471 | u32 blocksize, | 2723 | u32 blocksize, u64 parent, |
2472 | u64 root_objectid, | 2724 | u64 root_objectid, |
2473 | u64 ref_generation, | 2725 | u64 ref_generation, |
2474 | u64 first_objectid, | ||
2475 | int level, | 2726 | int level, |
2476 | u64 hint, | 2727 | u64 hint, |
2477 | u64 empty_size) | 2728 | u64 empty_size) |
@@ -2480,10 +2731,9 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
2480 | int ret; | 2731 | int ret; |
2481 | struct extent_buffer *buf; | 2732 | struct extent_buffer *buf; |
2482 | 2733 | ||
2483 | ret = btrfs_alloc_extent(trans, root, blocksize, blocksize, | 2734 | ret = btrfs_alloc_extent(trans, root, blocksize, parent, blocksize, |
2484 | root_objectid, ref_generation, | 2735 | root_objectid, ref_generation, level, 0, |
2485 | level, first_objectid, empty_size, hint, | 2736 | empty_size, hint, (u64)-1, &ins, 0); |
2486 | (u64)-1, &ins, 0); | ||
2487 | if (ret) { | 2737 | if (ret) { |
2488 | BUG_ON(ret > 0); | 2738 | BUG_ON(ret > 0); |
2489 | return ERR_PTR(ret); | 2739 | return ERR_PTR(ret); |
@@ -2531,15 +2781,14 @@ int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
2531 | mutex_lock(&root->fs_info->alloc_mutex); | 2781 | mutex_lock(&root->fs_info->alloc_mutex); |
2532 | ret = __btrfs_free_extent(trans, root, disk_bytenr, | 2782 | ret = __btrfs_free_extent(trans, root, disk_bytenr, |
2533 | btrfs_file_extent_disk_num_bytes(leaf, fi), | 2783 | btrfs_file_extent_disk_num_bytes(leaf, fi), |
2534 | leaf_owner, leaf_generation, | 2784 | leaf->start, leaf_owner, leaf_generation, |
2535 | key.objectid, key.offset, 0); | 2785 | key.objectid, key.offset, 0); |
2536 | mutex_unlock(&root->fs_info->alloc_mutex); | 2786 | mutex_unlock(&root->fs_info->alloc_mutex); |
2787 | BUG_ON(ret); | ||
2537 | 2788 | ||
2538 | atomic_inc(&root->fs_info->throttle_gen); | 2789 | atomic_inc(&root->fs_info->throttle_gen); |
2539 | wake_up(&root->fs_info->transaction_throttle); | 2790 | wake_up(&root->fs_info->transaction_throttle); |
2540 | cond_resched(); | 2791 | cond_resched(); |
2541 | |||
2542 | BUG_ON(ret); | ||
2543 | } | 2792 | } |
2544 | return 0; | 2793 | return 0; |
2545 | } | 2794 | } |
@@ -2554,10 +2803,10 @@ static int noinline cache_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
2554 | 2803 | ||
2555 | for (i = 0; i < ref->nritems; i++) { | 2804 | for (i = 0; i < ref->nritems; i++) { |
2556 | mutex_lock(&root->fs_info->alloc_mutex); | 2805 | mutex_lock(&root->fs_info->alloc_mutex); |
2557 | ret = __btrfs_free_extent(trans, root, | 2806 | ret = __btrfs_free_extent(trans, root, info->bytenr, |
2558 | info->bytenr, info->num_bytes, | 2807 | info->num_bytes, ref->bytenr, |
2559 | ref->owner, ref->generation, | 2808 | ref->owner, ref->generation, |
2560 | info->objectid, info->offset, 0); | 2809 | info->objectid, info->offset, 0); |
2561 | mutex_unlock(&root->fs_info->alloc_mutex); | 2810 | mutex_unlock(&root->fs_info->alloc_mutex); |
2562 | 2811 | ||
2563 | atomic_inc(&root->fs_info->throttle_gen); | 2812 | atomic_inc(&root->fs_info->throttle_gen); |
@@ -2576,7 +2825,7 @@ int drop_snap_lookup_refcount(struct btrfs_root *root, u64 start, u64 len, | |||
2576 | { | 2825 | { |
2577 | int ret; | 2826 | int ret; |
2578 | 2827 | ||
2579 | ret = lookup_extent_ref(NULL, root, start, len, refs); | 2828 | ret = btrfs_lookup_extent_ref(NULL, root, start, len, refs); |
2580 | BUG_ON(ret); | 2829 | BUG_ON(ret); |
2581 | 2830 | ||
2582 | #if 0 // some debugging code in case we see problems here | 2831 | #if 0 // some debugging code in case we see problems here |
@@ -2672,8 +2921,8 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2672 | 2921 | ||
2673 | mutex_lock(&root->fs_info->alloc_mutex); | 2922 | mutex_lock(&root->fs_info->alloc_mutex); |
2674 | ret = __btrfs_free_extent(trans, root, bytenr, | 2923 | ret = __btrfs_free_extent(trans, root, bytenr, |
2675 | blocksize, root_owner, | 2924 | blocksize, parent->start, |
2676 | root_gen, 0, 0, 1); | 2925 | root_owner, root_gen, 0, 0, 1); |
2677 | BUG_ON(ret); | 2926 | BUG_ON(ret); |
2678 | mutex_unlock(&root->fs_info->alloc_mutex); | 2927 | mutex_unlock(&root->fs_info->alloc_mutex); |
2679 | 2928 | ||
@@ -2690,8 +2939,6 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2690 | * So, we don't need to check it again | 2939 | * So, we don't need to check it again |
2691 | */ | 2940 | */ |
2692 | if (*level == 1) { | 2941 | if (*level == 1) { |
2693 | struct btrfs_key key; | ||
2694 | btrfs_node_key_to_cpu(cur, &key, path->slots[*level]); | ||
2695 | ref = btrfs_lookup_leaf_ref(root, bytenr); | 2942 | ref = btrfs_lookup_leaf_ref(root, bytenr); |
2696 | if (ref) { | 2943 | if (ref) { |
2697 | ret = cache_drop_leaf_ref(trans, root, ref); | 2944 | ret = cache_drop_leaf_ref(trans, root, ref); |
@@ -2750,12 +2997,13 @@ out: | |||
2750 | 2997 | ||
2751 | mutex_lock(&root->fs_info->alloc_mutex); | 2998 | mutex_lock(&root->fs_info->alloc_mutex); |
2752 | ret = __btrfs_free_extent(trans, root, bytenr, blocksize, | 2999 | ret = __btrfs_free_extent(trans, root, bytenr, blocksize, |
2753 | root_owner, root_gen, 0, 0, 1); | 3000 | parent->start, root_owner, root_gen, |
3001 | 0, 0, 1); | ||
3002 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
2754 | free_extent_buffer(path->nodes[*level]); | 3003 | free_extent_buffer(path->nodes[*level]); |
2755 | path->nodes[*level] = NULL; | 3004 | path->nodes[*level] = NULL; |
2756 | *level += 1; | 3005 | *level += 1; |
2757 | BUG_ON(ret); | 3006 | BUG_ON(ret); |
2758 | mutex_unlock(&root->fs_info->alloc_mutex); | ||
2759 | 3007 | ||
2760 | cond_resched(); | 3008 | cond_resched(); |
2761 | return 0; | 3009 | return 0; |
@@ -2792,19 +3040,18 @@ static int noinline walk_up_tree(struct btrfs_trans_handle *trans, | |||
2792 | root_item->drop_level = i; | 3040 | root_item->drop_level = i; |
2793 | return 0; | 3041 | return 0; |
2794 | } else { | 3042 | } else { |
2795 | if (path->nodes[*level] == root->node) { | 3043 | struct extent_buffer *parent; |
2796 | root_owner = root->root_key.objectid; | 3044 | if (path->nodes[*level] == root->node) |
2797 | root_gen = | 3045 | parent = path->nodes[*level]; |
2798 | btrfs_header_generation(path->nodes[*level]); | 3046 | else |
2799 | } else { | 3047 | parent = path->nodes[*level + 1]; |
2800 | struct extent_buffer *node; | 3048 | |
2801 | node = path->nodes[*level + 1]; | 3049 | root_owner = btrfs_header_owner(parent); |
2802 | root_owner = btrfs_header_owner(node); | 3050 | root_gen = btrfs_header_generation(parent); |
2803 | root_gen = btrfs_header_generation(node); | ||
2804 | } | ||
2805 | ret = btrfs_free_extent(trans, root, | 3051 | ret = btrfs_free_extent(trans, root, |
2806 | path->nodes[*level]->start, | 3052 | path->nodes[*level]->start, |
2807 | path->nodes[*level]->len, | 3053 | path->nodes[*level]->len, |
3054 | parent->start, | ||
2808 | root_owner, root_gen, 0, 0, 1); | 3055 | root_owner, root_gen, 0, 0, 1); |
2809 | BUG_ON(ret); | 3056 | BUG_ON(ret); |
2810 | free_extent_buffer(path->nodes[*level]); | 3057 | free_extent_buffer(path->nodes[*level]); |