diff options
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]); |