diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 185 |
1 files changed, 88 insertions, 97 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 69db54e09fb9..ab36769c356c 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -525,31 +525,28 @@ int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len) | |||
525 | * - Objectid of the subvolume root | 525 | * - Objectid of the subvolume root |
526 | * - Generation number of the tree holding the reference | 526 | * - Generation number of the tree holding the reference |
527 | * - objectid of the file holding the reference | 527 | * - objectid of the file holding the reference |
528 | * - offset in the file corresponding to the key holding the reference | ||
529 | * - number of references holding by parent node (alway 1 for tree blocks) | 528 | * - number of references holding by parent node (alway 1 for tree blocks) |
530 | * | 529 | * |
531 | * Btree leaf may hold multiple references to a file extent. In most cases, | 530 | * Btree leaf may hold multiple references to a file extent. In most cases, |
532 | * these references are from same file and the corresponding offsets inside | 531 | * these references are from same file and the corresponding offsets inside |
533 | * the file are close together. So inode objectid and offset in file are | 532 | * the file are close together. |
534 | * just hints, they provide hints about where in the btree the references | ||
535 | * can be found and when we can stop searching. | ||
536 | * | 533 | * |
537 | * When a file extent is allocated the fields are filled in: | 534 | * When a file extent is allocated the fields are filled in: |
538 | * (root_key.objectid, trans->transid, inode objectid, offset in file, 1) | 535 | * (root_key.objectid, trans->transid, inode objectid, 1) |
539 | * | 536 | * |
540 | * When a leaf is cow'd new references are added for every file extent found | 537 | * When a leaf is cow'd new references are added for every file extent found |
541 | * in the leaf. It looks similar to the create case, but trans->transid will | 538 | * in the leaf. It looks similar to the create case, but trans->transid will |
542 | * be different when the block is cow'd. | 539 | * be different when the block is cow'd. |
543 | * | 540 | * |
544 | * (root_key.objectid, trans->transid, inode objectid, offset in file, | 541 | * (root_key.objectid, trans->transid, inode objectid, |
545 | * number of references in the leaf) | 542 | * number of references in the leaf) |
546 | * | 543 | * |
547 | * Because inode objectid and offset in file are just hints, they are not | 544 | * When a file extent is removed either during snapshot deletion or |
548 | * used when backrefs are deleted. When a file extent is removed either | 545 | * file truncation, we find the corresponding back reference and check |
549 | * during snapshot deletion or file truncation, we find the corresponding | 546 | * the following fields: |
550 | * back back reference and check the following fields. | ||
551 | * | 547 | * |
552 | * (btrfs_header_owner(leaf), btrfs_header_generation(leaf)) | 548 | * (btrfs_header_owner(leaf), btrfs_header_generation(leaf), |
549 | * inode objectid) | ||
553 | * | 550 | * |
554 | * Btree extents can be referenced by: | 551 | * Btree extents can be referenced by: |
555 | * | 552 | * |
@@ -558,21 +555,21 @@ int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len) | |||
558 | * | 555 | * |
559 | * When a tree block is created, back references are inserted: | 556 | * When a tree block is created, back references are inserted: |
560 | * | 557 | * |
561 | * (root->root_key.objectid, trans->transid, level, 0, 1) | 558 | * (root->root_key.objectid, trans->transid, level, 1) |
562 | * | 559 | * |
563 | * When a tree block is cow'd, new back references are added for all the | 560 | * When a tree block is cow'd, new back references are added for all the |
564 | * blocks it points to. If the tree block isn't in reference counted root, | 561 | * blocks it points to. If the tree block isn't in reference counted root, |
565 | * the old back references are removed. These new back references are of | 562 | * the old back references are removed. These new back references are of |
566 | * the form (trans->transid will have increased since creation): | 563 | * the form (trans->transid will have increased since creation): |
567 | * | 564 | * |
568 | * (root->root_key.objectid, trans->transid, level, 0, 1) | 565 | * (root->root_key.objectid, trans->transid, level, 1) |
569 | * | 566 | * |
570 | * When a backref is in deleting, the following fields are checked: | 567 | * When a backref is in deleting, the following fields are checked: |
571 | * | 568 | * |
572 | * if backref was for a tree root: | 569 | * if backref was for a tree root: |
573 | * (btrfs_header_owner(itself), btrfs_header_generation(itself)) | 570 | * (btrfs_header_owner(itself), btrfs_header_generation(itself), level) |
574 | * else | 571 | * else |
575 | * (btrfs_header_owner(parent), btrfs_header_generation(parent)) | 572 | * (btrfs_header_owner(parent), btrfs_header_generation(parent), level) |
576 | * | 573 | * |
577 | * Back Reference Key composing: | 574 | * Back Reference Key composing: |
578 | * | 575 | * |
@@ -584,13 +581,15 @@ int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len) | |||
584 | 581 | ||
585 | static int noinline lookup_extent_backref(struct btrfs_trans_handle *trans, | 582 | static int noinline lookup_extent_backref(struct btrfs_trans_handle *trans, |
586 | struct btrfs_root *root, | 583 | struct btrfs_root *root, |
587 | struct btrfs_path *path, u64 bytenr, | 584 | struct btrfs_path *path, |
588 | u64 parent, u64 ref_root, | 585 | u64 bytenr, u64 parent, |
589 | u64 ref_generation, int del) | 586 | u64 ref_root, u64 ref_generation, |
587 | u64 owner_objectid, int del) | ||
590 | { | 588 | { |
591 | struct btrfs_key key; | 589 | struct btrfs_key key; |
592 | struct btrfs_extent_ref *ref; | 590 | struct btrfs_extent_ref *ref; |
593 | struct extent_buffer *leaf; | 591 | struct extent_buffer *leaf; |
592 | u64 ref_objectid; | ||
594 | int ret; | 593 | int ret; |
595 | 594 | ||
596 | key.objectid = bytenr; | 595 | key.objectid = bytenr; |
@@ -607,8 +606,11 @@ static int noinline lookup_extent_backref(struct btrfs_trans_handle *trans, | |||
607 | 606 | ||
608 | leaf = path->nodes[0]; | 607 | leaf = path->nodes[0]; |
609 | ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_ref); | 608 | ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_ref); |
609 | ref_objectid = btrfs_ref_objectid(leaf, ref); | ||
610 | if (btrfs_ref_root(leaf, ref) != ref_root || | 610 | if (btrfs_ref_root(leaf, ref) != ref_root || |
611 | btrfs_ref_generation(leaf, ref) != ref_generation) { | 611 | btrfs_ref_generation(leaf, ref) != ref_generation || |
612 | (ref_objectid != owner_objectid && | ||
613 | ref_objectid != BTRFS_MULTIPLE_OBJECTIDS)) { | ||
612 | ret = -EIO; | 614 | ret = -EIO; |
613 | WARN_ON(1); | 615 | WARN_ON(1); |
614 | goto out; | 616 | goto out; |
@@ -623,7 +625,7 @@ static int noinline insert_extent_backref(struct btrfs_trans_handle *trans, | |||
623 | struct btrfs_path *path, | 625 | struct btrfs_path *path, |
624 | u64 bytenr, u64 parent, | 626 | u64 bytenr, u64 parent, |
625 | u64 ref_root, u64 ref_generation, | 627 | u64 ref_root, u64 ref_generation, |
626 | u64 owner_objectid, u64 owner_offset) | 628 | u64 owner_objectid) |
627 | { | 629 | { |
628 | struct btrfs_key key; | 630 | struct btrfs_key key; |
629 | struct extent_buffer *leaf; | 631 | struct extent_buffer *leaf; |
@@ -643,7 +645,6 @@ static int noinline insert_extent_backref(struct btrfs_trans_handle *trans, | |||
643 | btrfs_set_ref_root(leaf, ref, ref_root); | 645 | btrfs_set_ref_root(leaf, ref, ref_root); |
644 | btrfs_set_ref_generation(leaf, ref, ref_generation); | 646 | btrfs_set_ref_generation(leaf, ref, ref_generation); |
645 | btrfs_set_ref_objectid(leaf, ref, owner_objectid); | 647 | btrfs_set_ref_objectid(leaf, ref, owner_objectid); |
646 | btrfs_set_ref_offset(leaf, ref, owner_offset); | ||
647 | btrfs_set_ref_num_refs(leaf, ref, 1); | 648 | btrfs_set_ref_num_refs(leaf, ref, 1); |
648 | } else if (ret == -EEXIST) { | 649 | } else if (ret == -EEXIST) { |
649 | u64 existing_owner; | 650 | u64 existing_owner; |
@@ -663,14 +664,10 @@ static int noinline insert_extent_backref(struct btrfs_trans_handle *trans, | |||
663 | btrfs_set_ref_num_refs(leaf, ref, num_refs + 1); | 664 | btrfs_set_ref_num_refs(leaf, ref, num_refs + 1); |
664 | 665 | ||
665 | existing_owner = btrfs_ref_objectid(leaf, ref); | 666 | existing_owner = btrfs_ref_objectid(leaf, ref); |
666 | if (existing_owner == owner_objectid && | 667 | if (existing_owner != owner_objectid && |
667 | btrfs_ref_offset(leaf, ref) > owner_offset) { | 668 | existing_owner != BTRFS_MULTIPLE_OBJECTIDS) { |
668 | btrfs_set_ref_offset(leaf, ref, owner_offset); | ||
669 | } else if (existing_owner != owner_objectid && | ||
670 | existing_owner != BTRFS_MULTIPLE_OBJECTIDS) { | ||
671 | btrfs_set_ref_objectid(leaf, ref, | 669 | btrfs_set_ref_objectid(leaf, ref, |
672 | BTRFS_MULTIPLE_OBJECTIDS); | 670 | BTRFS_MULTIPLE_OBJECTIDS); |
673 | btrfs_set_ref_offset(leaf, ref, 0); | ||
674 | } | 671 | } |
675 | ret = 0; | 672 | ret = 0; |
676 | } else { | 673 | } else { |
@@ -711,7 +708,7 @@ static int __btrfs_update_extent_ref(struct btrfs_trans_handle *trans, | |||
711 | u64 orig_parent, u64 parent, | 708 | u64 orig_parent, u64 parent, |
712 | u64 orig_root, u64 ref_root, | 709 | u64 orig_root, u64 ref_root, |
713 | u64 orig_generation, u64 ref_generation, | 710 | u64 orig_generation, u64 ref_generation, |
714 | u64 owner_objectid, u64 owner_offset) | 711 | u64 owner_objectid) |
715 | { | 712 | { |
716 | int ret; | 713 | int ret; |
717 | struct btrfs_root *extent_root = root->fs_info->extent_root; | 714 | struct btrfs_root *extent_root = root->fs_info->extent_root; |
@@ -762,7 +759,7 @@ static int __btrfs_update_extent_ref(struct btrfs_trans_handle *trans, | |||
762 | return -ENOMEM; | 759 | return -ENOMEM; |
763 | ret = lookup_extent_backref(trans, extent_root, path, | 760 | ret = lookup_extent_backref(trans, extent_root, path, |
764 | bytenr, orig_parent, orig_root, | 761 | bytenr, orig_parent, orig_root, |
765 | orig_generation, 1); | 762 | orig_generation, owner_objectid, 1); |
766 | if (ret) | 763 | if (ret) |
767 | goto out; | 764 | goto out; |
768 | ret = remove_extent_backref(trans, extent_root, path); | 765 | ret = remove_extent_backref(trans, extent_root, path); |
@@ -770,7 +767,7 @@ static int __btrfs_update_extent_ref(struct btrfs_trans_handle *trans, | |||
770 | goto out; | 767 | goto out; |
771 | ret = insert_extent_backref(trans, extent_root, path, bytenr, | 768 | ret = insert_extent_backref(trans, extent_root, path, bytenr, |
772 | parent, ref_root, ref_generation, | 769 | parent, ref_root, ref_generation, |
773 | owner_objectid, owner_offset); | 770 | owner_objectid); |
774 | BUG_ON(ret); | 771 | BUG_ON(ret); |
775 | finish_current_insert(trans, extent_root); | 772 | finish_current_insert(trans, extent_root); |
776 | del_pending_extents(trans, extent_root); | 773 | del_pending_extents(trans, extent_root); |
@@ -783,7 +780,7 @@ int btrfs_update_extent_ref(struct btrfs_trans_handle *trans, | |||
783 | struct btrfs_root *root, u64 bytenr, | 780 | struct btrfs_root *root, u64 bytenr, |
784 | u64 orig_parent, u64 parent, | 781 | u64 orig_parent, u64 parent, |
785 | u64 ref_root, u64 ref_generation, | 782 | u64 ref_root, u64 ref_generation, |
786 | u64 owner_objectid, u64 owner_offset) | 783 | u64 owner_objectid) |
787 | { | 784 | { |
788 | int ret; | 785 | int ret; |
789 | if (ref_root == BTRFS_TREE_LOG_OBJECTID && | 786 | if (ref_root == BTRFS_TREE_LOG_OBJECTID && |
@@ -793,7 +790,7 @@ int btrfs_update_extent_ref(struct btrfs_trans_handle *trans, | |||
793 | ret = __btrfs_update_extent_ref(trans, root, bytenr, orig_parent, | 790 | ret = __btrfs_update_extent_ref(trans, root, bytenr, orig_parent, |
794 | parent, ref_root, ref_root, | 791 | parent, ref_root, ref_root, |
795 | ref_generation, ref_generation, | 792 | ref_generation, ref_generation, |
796 | owner_objectid, owner_offset); | 793 | owner_objectid); |
797 | maybe_unlock_mutex(root); | 794 | maybe_unlock_mutex(root); |
798 | return ret; | 795 | return ret; |
799 | } | 796 | } |
@@ -803,7 +800,7 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
803 | u64 orig_parent, u64 parent, | 800 | u64 orig_parent, u64 parent, |
804 | u64 orig_root, u64 ref_root, | 801 | u64 orig_root, u64 ref_root, |
805 | u64 orig_generation, u64 ref_generation, | 802 | u64 orig_generation, u64 ref_generation, |
806 | u64 owner_objectid, u64 owner_offset) | 803 | u64 owner_objectid) |
807 | { | 804 | { |
808 | struct btrfs_path *path; | 805 | struct btrfs_path *path; |
809 | int ret; | 806 | int ret; |
@@ -845,7 +842,7 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
845 | ret = insert_extent_backref(trans, root->fs_info->extent_root, | 842 | ret = insert_extent_backref(trans, root->fs_info->extent_root, |
846 | path, bytenr, parent, | 843 | path, bytenr, parent, |
847 | ref_root, ref_generation, | 844 | ref_root, ref_generation, |
848 | owner_objectid, owner_offset); | 845 | owner_objectid); |
849 | BUG_ON(ret); | 846 | BUG_ON(ret); |
850 | finish_current_insert(trans, root->fs_info->extent_root); | 847 | finish_current_insert(trans, root->fs_info->extent_root); |
851 | del_pending_extents(trans, root->fs_info->extent_root); | 848 | del_pending_extents(trans, root->fs_info->extent_root); |
@@ -858,7 +855,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
858 | struct btrfs_root *root, | 855 | struct btrfs_root *root, |
859 | u64 bytenr, u64 num_bytes, u64 parent, | 856 | u64 bytenr, u64 num_bytes, u64 parent, |
860 | u64 ref_root, u64 ref_generation, | 857 | u64 ref_root, u64 ref_generation, |
861 | u64 owner_objectid, u64 owner_offset) | 858 | u64 owner_objectid) |
862 | { | 859 | { |
863 | int ret; | 860 | int ret; |
864 | if (ref_root == BTRFS_TREE_LOG_OBJECTID && | 861 | if (ref_root == BTRFS_TREE_LOG_OBJECTID && |
@@ -867,7 +864,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
867 | maybe_lock_mutex(root); | 864 | maybe_lock_mutex(root); |
868 | ret = __btrfs_inc_extent_ref(trans, root, bytenr, 0, parent, | 865 | ret = __btrfs_inc_extent_ref(trans, root, bytenr, 0, parent, |
869 | 0, ref_root, 0, ref_generation, | 866 | 0, ref_root, 0, ref_generation, |
870 | owner_objectid, owner_offset); | 867 | owner_objectid); |
871 | maybe_unlock_mutex(root); | 868 | maybe_unlock_mutex(root); |
872 | return ret; | 869 | return ret; |
873 | } | 870 | } |
@@ -1179,7 +1176,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1179 | int ret = 0; | 1176 | int ret = 0; |
1180 | int faili = 0; | 1177 | int faili = 0; |
1181 | int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, | 1178 | int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, |
1182 | u64, u64, u64, u64, u64, u64, u64, u64, u64); | 1179 | u64, u64, u64, u64, u64, u64, u64, u64); |
1183 | 1180 | ||
1184 | ref_root = btrfs_header_owner(buf); | 1181 | ref_root = btrfs_header_owner(buf); |
1185 | ref_generation = btrfs_header_generation(buf); | 1182 | ref_generation = btrfs_header_generation(buf); |
@@ -1223,7 +1220,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1223 | orig_buf->start, buf->start, | 1220 | orig_buf->start, buf->start, |
1224 | orig_root, ref_root, | 1221 | orig_root, ref_root, |
1225 | orig_generation, ref_generation, | 1222 | orig_generation, ref_generation, |
1226 | key.objectid, key.offset); | 1223 | key.objectid); |
1227 | maybe_unlock_mutex(root); | 1224 | maybe_unlock_mutex(root); |
1228 | 1225 | ||
1229 | if (ret) { | 1226 | if (ret) { |
@@ -1238,7 +1235,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1238 | orig_buf->start, buf->start, | 1235 | orig_buf->start, buf->start, |
1239 | orig_root, ref_root, | 1236 | orig_root, ref_root, |
1240 | orig_generation, ref_generation, | 1237 | orig_generation, ref_generation, |
1241 | level - 1, 0); | 1238 | level - 1); |
1242 | maybe_unlock_mutex(root); | 1239 | maybe_unlock_mutex(root); |
1243 | if (ret) { | 1240 | if (ret) { |
1244 | faili = i; | 1241 | faili = i; |
@@ -1314,7 +1311,7 @@ int btrfs_update_ref(struct btrfs_trans_handle *trans, | |||
1314 | orig_buf->start, buf->start, | 1311 | orig_buf->start, buf->start, |
1315 | orig_root, ref_root, | 1312 | orig_root, ref_root, |
1316 | orig_generation, ref_generation, | 1313 | orig_generation, ref_generation, |
1317 | key.objectid, key.offset); | 1314 | key.objectid); |
1318 | maybe_unlock_mutex(root); | 1315 | maybe_unlock_mutex(root); |
1319 | if (ret) | 1316 | if (ret) |
1320 | goto fail; | 1317 | goto fail; |
@@ -1325,7 +1322,7 @@ int btrfs_update_ref(struct btrfs_trans_handle *trans, | |||
1325 | orig_buf->start, buf->start, | 1322 | orig_buf->start, buf->start, |
1326 | orig_root, ref_root, | 1323 | orig_root, ref_root, |
1327 | orig_generation, ref_generation, | 1324 | orig_generation, ref_generation, |
1328 | level - 1, 0); | 1325 | level - 1); |
1329 | maybe_unlock_mutex(root); | 1326 | maybe_unlock_mutex(root); |
1330 | if (ret) | 1327 | if (ret) |
1331 | goto fail; | 1328 | goto fail; |
@@ -1781,13 +1778,14 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
1781 | start, extent_op->parent, | 1778 | start, extent_op->parent, |
1782 | extent_root->root_key.objectid, | 1779 | extent_root->root_key.objectid, |
1783 | extent_op->generation, | 1780 | extent_op->generation, |
1784 | extent_op->level, 0); | 1781 | extent_op->level); |
1785 | BUG_ON(err); | 1782 | BUG_ON(err); |
1786 | } else if (extent_op->type == PENDING_BACKREF_UPDATE) { | 1783 | } else if (extent_op->type == PENDING_BACKREF_UPDATE) { |
1787 | err = lookup_extent_backref(trans, extent_root, path, | 1784 | err = lookup_extent_backref(trans, extent_root, path, |
1788 | start, extent_op->orig_parent, | 1785 | start, extent_op->orig_parent, |
1789 | extent_root->root_key.objectid, | 1786 | extent_root->root_key.objectid, |
1790 | extent_op->orig_generation, 0); | 1787 | extent_op->orig_generation, |
1788 | extent_op->level, 0); | ||
1791 | BUG_ON(err); | 1789 | BUG_ON(err); |
1792 | 1790 | ||
1793 | clear_extent_bits(&info->extent_ins, start, end, | 1791 | clear_extent_bits(&info->extent_ins, start, end, |
@@ -1870,8 +1868,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, | |||
1870 | struct btrfs_root *root, | 1868 | struct btrfs_root *root, |
1871 | u64 bytenr, u64 num_bytes, u64 parent, | 1869 | u64 bytenr, u64 num_bytes, u64 parent, |
1872 | u64 root_objectid, u64 ref_generation, | 1870 | u64 root_objectid, u64 ref_generation, |
1873 | u64 owner_objectid, u64 owner_offset, | 1871 | u64 owner_objectid, int pin, int mark_free) |
1874 | int pin, int mark_free) | ||
1875 | { | 1872 | { |
1876 | struct btrfs_path *path; | 1873 | struct btrfs_path *path; |
1877 | struct btrfs_key key; | 1874 | struct btrfs_key key; |
@@ -1894,8 +1891,9 @@ static int __free_extent(struct btrfs_trans_handle *trans, | |||
1894 | return -ENOMEM; | 1891 | return -ENOMEM; |
1895 | 1892 | ||
1896 | path->reada = 1; | 1893 | path->reada = 1; |
1897 | ret = lookup_extent_backref(trans, extent_root, path, bytenr, parent, | 1894 | ret = lookup_extent_backref(trans, extent_root, path, |
1898 | root_objectid, ref_generation, 1); | 1895 | bytenr, parent, root_objectid, |
1896 | ref_generation, owner_objectid, 1); | ||
1899 | if (ret == 0) { | 1897 | if (ret == 0) { |
1900 | struct btrfs_key found_key; | 1898 | struct btrfs_key found_key; |
1901 | extent_slot = path->slots[0]; | 1899 | extent_slot = path->slots[0]; |
@@ -1926,9 +1924,8 @@ static int __free_extent(struct btrfs_trans_handle *trans, | |||
1926 | btrfs_print_leaf(extent_root, path->nodes[0]); | 1924 | btrfs_print_leaf(extent_root, path->nodes[0]); |
1927 | WARN_ON(1); | 1925 | WARN_ON(1); |
1928 | printk("Unable to find ref byte nr %Lu root %Lu " | 1926 | printk("Unable to find ref byte nr %Lu root %Lu " |
1929 | " gen %Lu owner %Lu offset %Lu\n", bytenr, | 1927 | "gen %Lu owner %Lu\n", bytenr, |
1930 | root_objectid, ref_generation, owner_objectid, | 1928 | root_objectid, ref_generation, owner_objectid); |
1931 | owner_offset); | ||
1932 | } | 1929 | } |
1933 | 1930 | ||
1934 | leaf = path->nodes[0]; | 1931 | leaf = path->nodes[0]; |
@@ -2068,7 +2065,7 @@ free_extent: | |||
2068 | extent_op->orig_parent, | 2065 | extent_op->orig_parent, |
2069 | extent_root->root_key.objectid, | 2066 | extent_root->root_key.objectid, |
2070 | extent_op->orig_generation, | 2067 | extent_op->orig_generation, |
2071 | extent_op->level, 0, 0, mark_free); | 2068 | extent_op->level, 0, mark_free); |
2072 | kfree(extent_op); | 2069 | kfree(extent_op); |
2073 | } else { | 2070 | } else { |
2074 | kfree(extent_op); | 2071 | kfree(extent_op); |
@@ -2107,7 +2104,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
2107 | struct btrfs_root *root, | 2104 | struct btrfs_root *root, |
2108 | u64 bytenr, u64 num_bytes, u64 parent, | 2105 | u64 bytenr, u64 num_bytes, u64 parent, |
2109 | u64 root_objectid, u64 ref_generation, | 2106 | u64 root_objectid, u64 ref_generation, |
2110 | u64 owner_objectid, u64 owner_offset, int pin) | 2107 | u64 owner_objectid, int pin) |
2111 | { | 2108 | { |
2112 | struct btrfs_root *extent_root = root->fs_info->extent_root; | 2109 | struct btrfs_root *extent_root = root->fs_info->extent_root; |
2113 | int pending_ret; | 2110 | int pending_ret; |
@@ -2156,8 +2153,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
2156 | pin = 1; | 2153 | pin = 1; |
2157 | 2154 | ||
2158 | ret = __free_extent(trans, root, bytenr, num_bytes, parent, | 2155 | ret = __free_extent(trans, root, bytenr, num_bytes, parent, |
2159 | root_objectid, ref_generation, owner_objectid, | 2156 | root_objectid, ref_generation, |
2160 | owner_offset, pin, pin == 0); | 2157 | owner_objectid, pin, pin == 0); |
2161 | 2158 | ||
2162 | finish_current_insert(trans, root->fs_info->extent_root); | 2159 | finish_current_insert(trans, root->fs_info->extent_root); |
2163 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root); | 2160 | pending_ret = del_pending_extents(trans, root->fs_info->extent_root); |
@@ -2168,14 +2165,14 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
2168 | struct btrfs_root *root, | 2165 | struct btrfs_root *root, |
2169 | u64 bytenr, u64 num_bytes, u64 parent, | 2166 | u64 bytenr, u64 num_bytes, u64 parent, |
2170 | u64 root_objectid, u64 ref_generation, | 2167 | u64 root_objectid, u64 ref_generation, |
2171 | u64 owner_objectid, u64 owner_offset, int pin) | 2168 | u64 owner_objectid, int pin) |
2172 | { | 2169 | { |
2173 | int ret; | 2170 | int ret; |
2174 | 2171 | ||
2175 | maybe_lock_mutex(root); | 2172 | maybe_lock_mutex(root); |
2176 | ret = __btrfs_free_extent(trans, root, bytenr, num_bytes, parent, | 2173 | ret = __btrfs_free_extent(trans, root, bytenr, num_bytes, parent, |
2177 | root_objectid, ref_generation, | 2174 | root_objectid, ref_generation, |
2178 | owner_objectid, owner_offset, pin); | 2175 | owner_objectid, pin); |
2179 | maybe_unlock_mutex(root); | 2176 | maybe_unlock_mutex(root); |
2180 | return ret; | 2177 | return ret; |
2181 | } | 2178 | } |
@@ -2522,8 +2519,7 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, | |||
2522 | static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | 2519 | static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, |
2523 | struct btrfs_root *root, u64 parent, | 2520 | struct btrfs_root *root, u64 parent, |
2524 | u64 root_objectid, u64 ref_generation, | 2521 | u64 root_objectid, u64 ref_generation, |
2525 | u64 owner, u64 owner_offset, | 2522 | u64 owner, struct btrfs_key *ins) |
2526 | struct btrfs_key *ins) | ||
2527 | { | 2523 | { |
2528 | int ret; | 2524 | int ret; |
2529 | int pending_ret; | 2525 | int pending_ret; |
@@ -2597,7 +2593,6 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2597 | btrfs_set_ref_root(path->nodes[0], ref, root_objectid); | 2593 | btrfs_set_ref_root(path->nodes[0], ref, root_objectid); |
2598 | btrfs_set_ref_generation(path->nodes[0], ref, ref_generation); | 2594 | btrfs_set_ref_generation(path->nodes[0], ref, ref_generation); |
2599 | btrfs_set_ref_objectid(path->nodes[0], ref, owner); | 2595 | btrfs_set_ref_objectid(path->nodes[0], ref, owner); |
2600 | btrfs_set_ref_offset(path->nodes[0], ref, owner_offset); | ||
2601 | btrfs_set_ref_num_refs(path->nodes[0], ref, 1); | 2596 | btrfs_set_ref_num_refs(path->nodes[0], ref, 1); |
2602 | 2597 | ||
2603 | btrfs_mark_buffer_dirty(path->nodes[0]); | 2598 | btrfs_mark_buffer_dirty(path->nodes[0]); |
@@ -2629,17 +2624,15 @@ out: | |||
2629 | int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | 2624 | int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, |
2630 | struct btrfs_root *root, u64 parent, | 2625 | struct btrfs_root *root, u64 parent, |
2631 | u64 root_objectid, u64 ref_generation, | 2626 | u64 root_objectid, u64 ref_generation, |
2632 | u64 owner, u64 owner_offset, | 2627 | u64 owner, struct btrfs_key *ins) |
2633 | struct btrfs_key *ins) | ||
2634 | { | 2628 | { |
2635 | int ret; | 2629 | int ret; |
2636 | 2630 | ||
2637 | if (root_objectid == BTRFS_TREE_LOG_OBJECTID) | 2631 | if (root_objectid == BTRFS_TREE_LOG_OBJECTID) |
2638 | return 0; | 2632 | return 0; |
2639 | maybe_lock_mutex(root); | 2633 | maybe_lock_mutex(root); |
2640 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, | 2634 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, root_objectid, |
2641 | root_objectid, ref_generation, | 2635 | ref_generation, owner, ins); |
2642 | owner, owner_offset, ins); | ||
2643 | update_reserved_extents(root, ins->objectid, ins->offset, 0); | 2636 | update_reserved_extents(root, ins->objectid, ins->offset, 0); |
2644 | maybe_unlock_mutex(root); | 2637 | maybe_unlock_mutex(root); |
2645 | return ret; | 2638 | return ret; |
@@ -2653,8 +2646,7 @@ int btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans, | |||
2653 | int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, | 2646 | int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, |
2654 | struct btrfs_root *root, u64 parent, | 2647 | struct btrfs_root *root, u64 parent, |
2655 | u64 root_objectid, u64 ref_generation, | 2648 | u64 root_objectid, u64 ref_generation, |
2656 | u64 owner, u64 owner_offset, | 2649 | u64 owner, struct btrfs_key *ins) |
2657 | struct btrfs_key *ins) | ||
2658 | { | 2650 | { |
2659 | int ret; | 2651 | int ret; |
2660 | struct btrfs_block_group_cache *block_group; | 2652 | struct btrfs_block_group_cache *block_group; |
@@ -2665,9 +2657,8 @@ int btrfs_alloc_logged_extent(struct btrfs_trans_handle *trans, | |||
2665 | 2657 | ||
2666 | ret = btrfs_remove_free_space(block_group, ins->objectid, ins->offset); | 2658 | ret = btrfs_remove_free_space(block_group, ins->objectid, ins->offset); |
2667 | BUG_ON(ret); | 2659 | BUG_ON(ret); |
2668 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, | 2660 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, root_objectid, |
2669 | root_objectid, ref_generation, | 2661 | ref_generation, owner, ins); |
2670 | owner, owner_offset, ins); | ||
2671 | maybe_unlock_mutex(root); | 2662 | maybe_unlock_mutex(root); |
2672 | return ret; | 2663 | return ret; |
2673 | } | 2664 | } |
@@ -2683,8 +2674,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
2683 | struct btrfs_root *root, | 2674 | struct btrfs_root *root, |
2684 | u64 num_bytes, u64 parent, u64 min_alloc_size, | 2675 | u64 num_bytes, u64 parent, u64 min_alloc_size, |
2685 | u64 root_objectid, u64 ref_generation, | 2676 | u64 root_objectid, u64 ref_generation, |
2686 | u64 owner_objectid, u64 owner_offset, | 2677 | u64 owner_objectid, u64 empty_size, u64 hint_byte, |
2687 | u64 empty_size, u64 hint_byte, | ||
2688 | u64 search_end, struct btrfs_key *ins, u64 data) | 2678 | u64 search_end, struct btrfs_key *ins, u64 data) |
2689 | { | 2679 | { |
2690 | int ret; | 2680 | int ret; |
@@ -2698,7 +2688,7 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
2698 | if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { | 2688 | if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { |
2699 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, | 2689 | ret = __btrfs_alloc_reserved_extent(trans, root, parent, |
2700 | root_objectid, ref_generation, | 2690 | root_objectid, ref_generation, |
2701 | owner_objectid, owner_offset, ins); | 2691 | owner_objectid, ins); |
2702 | BUG_ON(ret); | 2692 | BUG_ON(ret); |
2703 | 2693 | ||
2704 | } else { | 2694 | } else { |
@@ -2750,7 +2740,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
2750 | struct extent_buffer *buf; | 2740 | struct extent_buffer *buf; |
2751 | 2741 | ||
2752 | ret = btrfs_alloc_extent(trans, root, blocksize, parent, blocksize, | 2742 | ret = btrfs_alloc_extent(trans, root, blocksize, parent, blocksize, |
2753 | root_objectid, ref_generation, level, 0, | 2743 | root_objectid, ref_generation, level, |
2754 | empty_size, hint, (u64)-1, &ins, 0); | 2744 | empty_size, hint, (u64)-1, &ins, 0); |
2755 | if (ret) { | 2745 | if (ret) { |
2756 | BUG_ON(ret > 0); | 2746 | BUG_ON(ret > 0); |
@@ -2800,7 +2790,7 @@ int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
2800 | ret = __btrfs_free_extent(trans, root, disk_bytenr, | 2790 | ret = __btrfs_free_extent(trans, root, disk_bytenr, |
2801 | btrfs_file_extent_disk_num_bytes(leaf, fi), | 2791 | btrfs_file_extent_disk_num_bytes(leaf, fi), |
2802 | leaf->start, leaf_owner, leaf_generation, | 2792 | leaf->start, leaf_owner, leaf_generation, |
2803 | key.objectid, key.offset, 0); | 2793 | key.objectid, 0); |
2804 | mutex_unlock(&root->fs_info->alloc_mutex); | 2794 | mutex_unlock(&root->fs_info->alloc_mutex); |
2805 | BUG_ON(ret); | 2795 | BUG_ON(ret); |
2806 | 2796 | ||
@@ -2824,7 +2814,7 @@ static int noinline cache_drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
2824 | ret = __btrfs_free_extent(trans, root, info->bytenr, | 2814 | ret = __btrfs_free_extent(trans, root, info->bytenr, |
2825 | info->num_bytes, ref->bytenr, | 2815 | info->num_bytes, ref->bytenr, |
2826 | ref->owner, ref->generation, | 2816 | ref->owner, ref->generation, |
2827 | info->objectid, info->offset, 0); | 2817 | info->objectid, 0); |
2828 | mutex_unlock(&root->fs_info->alloc_mutex); | 2818 | mutex_unlock(&root->fs_info->alloc_mutex); |
2829 | 2819 | ||
2830 | atomic_inc(&root->fs_info->throttle_gen); | 2820 | atomic_inc(&root->fs_info->throttle_gen); |
@@ -2940,7 +2930,8 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2940 | mutex_lock(&root->fs_info->alloc_mutex); | 2930 | mutex_lock(&root->fs_info->alloc_mutex); |
2941 | ret = __btrfs_free_extent(trans, root, bytenr, | 2931 | ret = __btrfs_free_extent(trans, root, bytenr, |
2942 | blocksize, parent->start, | 2932 | blocksize, parent->start, |
2943 | root_owner, root_gen, 0, 0, 1); | 2933 | root_owner, root_gen, |
2934 | *level - 1, 1); | ||
2944 | BUG_ON(ret); | 2935 | BUG_ON(ret); |
2945 | mutex_unlock(&root->fs_info->alloc_mutex); | 2936 | mutex_unlock(&root->fs_info->alloc_mutex); |
2946 | 2937 | ||
@@ -2970,9 +2961,10 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2970 | *level = 0; | 2961 | *level = 0; |
2971 | break; | 2962 | break; |
2972 | } | 2963 | } |
2973 | if (printk_ratelimit()) | 2964 | if (printk_ratelimit()) { |
2974 | printk("leaf ref miss for bytenr %llu\n", | 2965 | printk("leaf ref miss for bytenr %llu\n", |
2975 | (unsigned long long)bytenr); | 2966 | (unsigned long long)bytenr); |
2967 | } | ||
2976 | } | 2968 | } |
2977 | next = btrfs_find_tree_block(root, bytenr, blocksize); | 2969 | next = btrfs_find_tree_block(root, bytenr, blocksize); |
2978 | if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) { | 2970 | if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) { |
@@ -3020,7 +3012,7 @@ out: | |||
3020 | mutex_lock(&root->fs_info->alloc_mutex); | 3012 | mutex_lock(&root->fs_info->alloc_mutex); |
3021 | ret = __btrfs_free_extent(trans, root, bytenr, blocksize, | 3013 | ret = __btrfs_free_extent(trans, root, bytenr, blocksize, |
3022 | parent->start, root_owner, root_gen, | 3014 | parent->start, root_owner, root_gen, |
3023 | 0, 0, 1); | 3015 | *level, 1); |
3024 | mutex_unlock(&root->fs_info->alloc_mutex); | 3016 | mutex_unlock(&root->fs_info->alloc_mutex); |
3025 | free_extent_buffer(path->nodes[*level]); | 3017 | free_extent_buffer(path->nodes[*level]); |
3026 | path->nodes[*level] = NULL; | 3018 | path->nodes[*level] = NULL; |
@@ -3073,8 +3065,8 @@ static int noinline walk_up_tree(struct btrfs_trans_handle *trans, | |||
3073 | ret = btrfs_free_extent(trans, root, | 3065 | ret = btrfs_free_extent(trans, root, |
3074 | path->nodes[*level]->start, | 3066 | path->nodes[*level]->start, |
3075 | path->nodes[*level]->len, | 3067 | path->nodes[*level]->len, |
3076 | parent->start, | 3068 | parent->start, root_owner, |
3077 | root_owner, root_gen, 0, 0, 1); | 3069 | root_gen, *level, 1); |
3078 | BUG_ON(ret); | 3070 | BUG_ON(ret); |
3079 | free_extent_buffer(path->nodes[*level]); | 3071 | free_extent_buffer(path->nodes[*level]); |
3080 | path->nodes[*level] = NULL; | 3072 | path->nodes[*level] = NULL; |
@@ -3308,7 +3300,6 @@ struct btrfs_ref_path { | |||
3308 | u64 root_objectid; | 3300 | u64 root_objectid; |
3309 | u64 root_generation; | 3301 | u64 root_generation; |
3310 | u64 owner_objectid; | 3302 | u64 owner_objectid; |
3311 | u64 owner_offset; | ||
3312 | u32 num_refs; | 3303 | u32 num_refs; |
3313 | int lowest_level; | 3304 | int lowest_level; |
3314 | int current_level; | 3305 | int current_level; |
@@ -3480,7 +3471,6 @@ found: | |||
3480 | 3471 | ||
3481 | if (ref_path->lowest_level == level) { | 3472 | if (ref_path->lowest_level == level) { |
3482 | ref_path->owner_objectid = ref_objectid; | 3473 | ref_path->owner_objectid = ref_objectid; |
3483 | ref_path->owner_offset = btrfs_ref_offset(leaf, ref); | ||
3484 | ref_path->num_refs = btrfs_ref_num_refs(leaf, ref); | 3474 | ref_path->num_refs = btrfs_ref_num_refs(leaf, ref); |
3485 | } | 3475 | } |
3486 | 3476 | ||
@@ -3686,16 +3676,20 @@ static int noinline replace_one_extent(struct btrfs_trans_handle *trans, | |||
3686 | u64 ext_offset; | 3676 | u64 ext_offset; |
3687 | u64 first_pos; | 3677 | u64 first_pos; |
3688 | u32 nritems; | 3678 | u32 nritems; |
3679 | int nr_scaned = 0; | ||
3689 | int extent_locked = 0; | 3680 | int extent_locked = 0; |
3690 | int ret; | 3681 | int ret; |
3691 | 3682 | ||
3692 | first_pos = ref_path->owner_offset; | 3683 | memcpy(&key, leaf_key, sizeof(key)); |
3684 | first_pos = INT_LIMIT(loff_t) - extent_key->offset; | ||
3693 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) { | 3685 | if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) { |
3694 | key.objectid = ref_path->owner_objectid; | 3686 | if (key.objectid < ref_path->owner_objectid || |
3695 | key.offset = ref_path->owner_offset; | 3687 | (key.objectid == ref_path->owner_objectid && |
3696 | key.type = BTRFS_EXTENT_DATA_KEY; | 3688 | key.type < BTRFS_EXTENT_DATA_KEY)) { |
3697 | } else { | 3689 | key.objectid = ref_path->owner_objectid; |
3698 | memcpy(&key, leaf_key, sizeof(key)); | 3690 | key.type = BTRFS_EXTENT_DATA_KEY; |
3691 | key.offset = 0; | ||
3692 | } | ||
3699 | } | 3693 | } |
3700 | 3694 | ||
3701 | while (1) { | 3695 | while (1) { |
@@ -3718,8 +3712,7 @@ next: | |||
3718 | } | 3712 | } |
3719 | 3713 | ||
3720 | if (path->slots[0] >= nritems) { | 3714 | if (path->slots[0] >= nritems) { |
3721 | if (ref_path->owner_objectid == | 3715 | if (++nr_scaned > 2) |
3722 | BTRFS_MULTIPLE_OBJECTIDS) | ||
3723 | break; | 3716 | break; |
3724 | 3717 | ||
3725 | BUG_ON(extent_locked); | 3718 | BUG_ON(extent_locked); |
@@ -3858,7 +3851,7 @@ next: | |||
3858 | leaf->start, | 3851 | leaf->start, |
3859 | root->root_key.objectid, | 3852 | root->root_key.objectid, |
3860 | trans->transid, | 3853 | trans->transid, |
3861 | key.objectid, key.offset); | 3854 | key.objectid); |
3862 | BUG_ON(ret); | 3855 | BUG_ON(ret); |
3863 | 3856 | ||
3864 | ret = btrfs_free_extent(trans, root, | 3857 | ret = btrfs_free_extent(trans, root, |
@@ -3867,7 +3860,7 @@ next: | |||
3867 | leaf->start, | 3860 | leaf->start, |
3868 | btrfs_header_owner(leaf), | 3861 | btrfs_header_owner(leaf), |
3869 | btrfs_header_generation(leaf), | 3862 | btrfs_header_generation(leaf), |
3870 | key.objectid, key.offset, 0); | 3863 | key.objectid, 0); |
3871 | BUG_ON(ret); | 3864 | BUG_ON(ret); |
3872 | 3865 | ||
3873 | btrfs_release_path(root, path); | 3866 | btrfs_release_path(root, path); |
@@ -3925,8 +3918,7 @@ next: | |||
3925 | new_extents[i].disk_num_bytes, | 3918 | new_extents[i].disk_num_bytes, |
3926 | leaf->start, | 3919 | leaf->start, |
3927 | root->root_key.objectid, | 3920 | root->root_key.objectid, |
3928 | trans->transid, | 3921 | trans->transid, key.objectid); |
3929 | key.objectid, key.offset); | ||
3930 | BUG_ON(ret); | 3922 | BUG_ON(ret); |
3931 | btrfs_release_path(root, path); | 3923 | btrfs_release_path(root, path); |
3932 | 3924 | ||
@@ -4182,14 +4174,13 @@ static int noinline replace_extents_in_leaf(struct btrfs_trans_handle *trans, | |||
4182 | new_extent->disk_num_bytes, | 4174 | new_extent->disk_num_bytes, |
4183 | leaf->start, | 4175 | leaf->start, |
4184 | root->root_key.objectid, | 4176 | root->root_key.objectid, |
4185 | trans->transid, | 4177 | trans->transid, key.objectid); |
4186 | key.objectid, key.offset); | ||
4187 | BUG_ON(ret); | 4178 | BUG_ON(ret); |
4188 | ret = btrfs_free_extent(trans, root, | 4179 | ret = btrfs_free_extent(trans, root, |
4189 | bytenr, num_bytes, leaf->start, | 4180 | bytenr, num_bytes, leaf->start, |
4190 | btrfs_header_owner(leaf), | 4181 | btrfs_header_owner(leaf), |
4191 | btrfs_header_generation(leaf), | 4182 | btrfs_header_generation(leaf), |
4192 | key.objectid, key.offset, 0); | 4183 | key.objectid, 0); |
4193 | BUG_ON(ret); | 4184 | BUG_ON(ret); |
4194 | cond_resched(); | 4185 | cond_resched(); |
4195 | } | 4186 | } |