aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ref-verify.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ref-verify.c')
-rw-r--r--fs/btrfs/ref-verify.c53
1 files changed, 30 insertions, 23 deletions
diff --git a/fs/btrfs/ref-verify.c b/fs/btrfs/ref-verify.c
index b283d3a6e837..5cec2c6970f2 100644
--- a/fs/btrfs/ref-verify.c
+++ b/fs/btrfs/ref-verify.c
@@ -659,36 +659,43 @@ static void dump_block_entry(struct btrfs_fs_info *fs_info,
659 659
660/* 660/*
661 * btrfs_ref_tree_mod: called when we modify a ref for a bytenr 661 * btrfs_ref_tree_mod: called when we modify a ref for a bytenr
662 * @root: the root we are making this modification from.
663 * @bytenr: the bytenr we are modifying.
664 * @num_bytes: number of bytes.
665 * @parent: the parent bytenr.
666 * @ref_root: the original root owner of the bytenr.
667 * @owner: level in the case of metadata, inode in the case of data.
668 * @offset: 0 for metadata, file offset for data.
669 * @action: the action that we are doing, this is the same as the delayed ref
670 * action.
671 * 662 *
672 * This will add an action item to the given bytenr and do sanity checks to make 663 * This will add an action item to the given bytenr and do sanity checks to make
673 * sure we haven't messed something up. If we are making a new allocation and 664 * sure we haven't messed something up. If we are making a new allocation and
674 * this block entry has history we will delete all previous actions as long as 665 * this block entry has history we will delete all previous actions as long as
675 * our sanity checks pass as they are no longer needed. 666 * our sanity checks pass as they are no longer needed.
676 */ 667 */
677int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes, 668int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info,
678 u64 parent, u64 ref_root, u64 owner, u64 offset, 669 struct btrfs_ref *generic_ref)
679 int action)
680{ 670{
681 struct btrfs_fs_info *fs_info = root->fs_info;
682 struct ref_entry *ref = NULL, *exist; 671 struct ref_entry *ref = NULL, *exist;
683 struct ref_action *ra = NULL; 672 struct ref_action *ra = NULL;
684 struct block_entry *be = NULL; 673 struct block_entry *be = NULL;
685 struct root_entry *re = NULL; 674 struct root_entry *re = NULL;
675 int action = generic_ref->action;
686 int ret = 0; 676 int ret = 0;
687 bool metadata = owner < BTRFS_FIRST_FREE_OBJECTID; 677 bool metadata;
678 u64 bytenr = generic_ref->bytenr;
679 u64 num_bytes = generic_ref->len;
680 u64 parent = generic_ref->parent;
681 u64 ref_root;
682 u64 owner;
683 u64 offset;
688 684
689 if (!btrfs_test_opt(root->fs_info, REF_VERIFY)) 685 if (!btrfs_test_opt(fs_info, REF_VERIFY))
690 return 0; 686 return 0;
691 687
688 if (generic_ref->type == BTRFS_REF_METADATA) {
689 ref_root = generic_ref->tree_ref.root;
690 owner = generic_ref->tree_ref.level;
691 offset = 0;
692 } else {
693 ref_root = generic_ref->data_ref.ref_root;
694 owner = generic_ref->data_ref.ino;
695 offset = generic_ref->data_ref.offset;
696 }
697 metadata = owner < BTRFS_FIRST_FREE_OBJECTID;
698
692 ref = kzalloc(sizeof(struct ref_entry), GFP_NOFS); 699 ref = kzalloc(sizeof(struct ref_entry), GFP_NOFS);
693 ra = kmalloc(sizeof(struct ref_action), GFP_NOFS); 700 ra = kmalloc(sizeof(struct ref_action), GFP_NOFS);
694 if (!ra || !ref) { 701 if (!ra || !ref) {
@@ -721,7 +728,7 @@ int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes,
721 728
722 INIT_LIST_HEAD(&ra->list); 729 INIT_LIST_HEAD(&ra->list);
723 ra->action = action; 730 ra->action = action;
724 ra->root = root->root_key.objectid; 731 ra->root = generic_ref->real_root;
725 732
726 /* 733 /*
727 * This is an allocation, preallocate the block_entry in case we haven't 734 * This is an allocation, preallocate the block_entry in case we haven't
@@ -734,7 +741,7 @@ int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes,
734 * is and the new root objectid, so let's not treat the passed 741 * is and the new root objectid, so let's not treat the passed
735 * in root as if it really has a ref for this bytenr. 742 * in root as if it really has a ref for this bytenr.
736 */ 743 */
737 be = add_block_entry(root->fs_info, bytenr, num_bytes, ref_root); 744 be = add_block_entry(fs_info, bytenr, num_bytes, ref_root);
738 if (IS_ERR(be)) { 745 if (IS_ERR(be)) {
739 kfree(ra); 746 kfree(ra);
740 ret = PTR_ERR(be); 747 ret = PTR_ERR(be);
@@ -776,13 +783,13 @@ int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes,
776 * one we want to lookup below when we modify the 783 * one we want to lookup below when we modify the
777 * re->num_refs. 784 * re->num_refs.
778 */ 785 */
779 ref_root = root->root_key.objectid; 786 ref_root = generic_ref->real_root;
780 re->root_objectid = root->root_key.objectid; 787 re->root_objectid = generic_ref->real_root;
781 re->num_refs = 0; 788 re->num_refs = 0;
782 } 789 }
783 790
784 spin_lock(&root->fs_info->ref_verify_lock); 791 spin_lock(&fs_info->ref_verify_lock);
785 be = lookup_block_entry(&root->fs_info->block_tree, bytenr); 792 be = lookup_block_entry(&fs_info->block_tree, bytenr);
786 if (!be) { 793 if (!be) {
787 btrfs_err(fs_info, 794 btrfs_err(fs_info,
788"trying to do action %d to bytenr %llu num_bytes %llu but there is no existing entry!", 795"trying to do action %d to bytenr %llu num_bytes %llu but there is no existing entry!",
@@ -851,7 +858,7 @@ int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes,
851 * didn't think of some other corner case. 858 * didn't think of some other corner case.
852 */ 859 */
853 btrfs_err(fs_info, "failed to find root %llu for %llu", 860 btrfs_err(fs_info, "failed to find root %llu for %llu",
854 root->root_key.objectid, be->bytenr); 861 generic_ref->real_root, be->bytenr);
855 dump_block_entry(fs_info, be); 862 dump_block_entry(fs_info, be);
856 dump_ref_action(fs_info, ra); 863 dump_ref_action(fs_info, ra);
857 kfree(ra); 864 kfree(ra);
@@ -870,7 +877,7 @@ int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes,
870 list_add_tail(&ra->list, &be->actions); 877 list_add_tail(&ra->list, &be->actions);
871 ret = 0; 878 ret = 0;
872out_unlock: 879out_unlock:
873 spin_unlock(&root->fs_info->ref_verify_lock); 880 spin_unlock(&fs_info->ref_verify_lock);
874out: 881out:
875 if (ret) 882 if (ret)
876 btrfs_clear_opt(fs_info->mount_opt, REF_VERIFY); 883 btrfs_clear_opt(fs_info->mount_opt, REF_VERIFY);