diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2008-10-09 11:46:24 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-10-09 11:46:24 -0400 |
commit | 3bb1a1bc42f2ae9582c28adf620484efcd4da38d (patch) | |
tree | 4e65ee859e73ea9558e33a02ba10e1d9d54756f3 /fs/btrfs/extent-tree.c | |
parent | a76a3cd40c1127ca199d4f7f37bf0d541bf44eb2 (diff) |
Btrfs: Remove offset field from struct btrfs_extent_ref
The offset field in struct btrfs_extent_ref records the position
inside file that file extent is referenced by. In the new back
reference system, tree leaves holding references to file extent
are recorded explicitly. We can scan these tree leaves very quickly, so the
offset field is not required.
This patch also makes the back reference system check the objectid
when extents are in deleting.
Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
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 | } |