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.c68
1 files changed, 32 insertions, 36 deletions
diff --git a/fs/btrfs/ref-verify.c b/fs/btrfs/ref-verify.c
index d09b6cdb785a..5cec2c6970f2 100644
--- a/fs/btrfs/ref-verify.c
+++ b/fs/btrfs/ref-verify.c
@@ -205,28 +205,17 @@ static struct root_entry *lookup_root_entry(struct rb_root *root, u64 objectid)
205#ifdef CONFIG_STACKTRACE 205#ifdef CONFIG_STACKTRACE
206static void __save_stack_trace(struct ref_action *ra) 206static void __save_stack_trace(struct ref_action *ra)
207{ 207{
208 struct stack_trace stack_trace; 208 ra->trace_len = stack_trace_save(ra->trace, MAX_TRACE, 2);
209
210 stack_trace.max_entries = MAX_TRACE;
211 stack_trace.nr_entries = 0;
212 stack_trace.entries = ra->trace;
213 stack_trace.skip = 2;
214 save_stack_trace(&stack_trace);
215 ra->trace_len = stack_trace.nr_entries;
216} 209}
217 210
218static void __print_stack_trace(struct btrfs_fs_info *fs_info, 211static void __print_stack_trace(struct btrfs_fs_info *fs_info,
219 struct ref_action *ra) 212 struct ref_action *ra)
220{ 213{
221 struct stack_trace trace;
222
223 if (ra->trace_len == 0) { 214 if (ra->trace_len == 0) {
224 btrfs_err(fs_info, " ref-verify: no stacktrace"); 215 btrfs_err(fs_info, " ref-verify: no stacktrace");
225 return; 216 return;
226 } 217 }
227 trace.nr_entries = ra->trace_len; 218 stack_trace_print(ra->trace, ra->trace_len, 2);
228 trace.entries = ra->trace;
229 print_stack_trace(&trace, 2);
230} 219}
231#else 220#else
232static void inline __save_stack_trace(struct ref_action *ra) 221static void inline __save_stack_trace(struct ref_action *ra)
@@ -670,36 +659,43 @@ static void dump_block_entry(struct btrfs_fs_info *fs_info,
670 659
671/* 660/*
672 * 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
673 * @root: the root we are making this modification from.
674 * @bytenr: the bytenr we are modifying.
675 * @num_bytes: number of bytes.
676 * @parent: the parent bytenr.
677 * @ref_root: the original root owner of the bytenr.
678 * @owner: level in the case of metadata, inode in the case of data.
679 * @offset: 0 for metadata, file offset for data.
680 * @action: the action that we are doing, this is the same as the delayed ref
681 * action.
682 * 662 *
683 * 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
684 * 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
685 * 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
686 * our sanity checks pass as they are no longer needed. 666 * our sanity checks pass as they are no longer needed.
687 */ 667 */
688int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes, 668int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info,
689 u64 parent, u64 ref_root, u64 owner, u64 offset, 669 struct btrfs_ref *generic_ref)
690 int action)
691{ 670{
692 struct btrfs_fs_info *fs_info = root->fs_info;
693 struct ref_entry *ref = NULL, *exist; 671 struct ref_entry *ref = NULL, *exist;
694 struct ref_action *ra = NULL; 672 struct ref_action *ra = NULL;
695 struct block_entry *be = NULL; 673 struct block_entry *be = NULL;
696 struct root_entry *re = NULL; 674 struct root_entry *re = NULL;
675 int action = generic_ref->action;
697 int ret = 0; 676 int ret = 0;
698 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;
699 684
700 if (!btrfs_test_opt(root->fs_info, REF_VERIFY)) 685 if (!btrfs_test_opt(fs_info, REF_VERIFY))
701 return 0; 686 return 0;
702 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
703 ref = kzalloc(sizeof(struct ref_entry), GFP_NOFS); 699 ref = kzalloc(sizeof(struct ref_entry), GFP_NOFS);
704 ra = kmalloc(sizeof(struct ref_action), GFP_NOFS); 700 ra = kmalloc(sizeof(struct ref_action), GFP_NOFS);
705 if (!ra || !ref) { 701 if (!ra || !ref) {
@@ -732,7 +728,7 @@ int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes,
732 728
733 INIT_LIST_HEAD(&ra->list); 729 INIT_LIST_HEAD(&ra->list);
734 ra->action = action; 730 ra->action = action;
735 ra->root = root->root_key.objectid; 731 ra->root = generic_ref->real_root;
736 732
737 /* 733 /*
738 * 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
@@ -745,7 +741,7 @@ int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes,
745 * 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
746 * 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.
747 */ 743 */
748 be = add_block_entry(root->fs_info, bytenr, num_bytes, ref_root); 744 be = add_block_entry(fs_info, bytenr, num_bytes, ref_root);
749 if (IS_ERR(be)) { 745 if (IS_ERR(be)) {
750 kfree(ra); 746 kfree(ra);
751 ret = PTR_ERR(be); 747 ret = PTR_ERR(be);
@@ -787,13 +783,13 @@ int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes,
787 * one we want to lookup below when we modify the 783 * one we want to lookup below when we modify the
788 * re->num_refs. 784 * re->num_refs.
789 */ 785 */
790 ref_root = root->root_key.objectid; 786 ref_root = generic_ref->real_root;
791 re->root_objectid = root->root_key.objectid; 787 re->root_objectid = generic_ref->real_root;
792 re->num_refs = 0; 788 re->num_refs = 0;
793 } 789 }
794 790
795 spin_lock(&root->fs_info->ref_verify_lock); 791 spin_lock(&fs_info->ref_verify_lock);
796 be = lookup_block_entry(&root->fs_info->block_tree, bytenr); 792 be = lookup_block_entry(&fs_info->block_tree, bytenr);
797 if (!be) { 793 if (!be) {
798 btrfs_err(fs_info, 794 btrfs_err(fs_info,
799"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!",
@@ -862,7 +858,7 @@ int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes,
862 * didn't think of some other corner case. 858 * didn't think of some other corner case.
863 */ 859 */
864 btrfs_err(fs_info, "failed to find root %llu for %llu", 860 btrfs_err(fs_info, "failed to find root %llu for %llu",
865 root->root_key.objectid, be->bytenr); 861 generic_ref->real_root, be->bytenr);
866 dump_block_entry(fs_info, be); 862 dump_block_entry(fs_info, be);
867 dump_ref_action(fs_info, ra); 863 dump_ref_action(fs_info, ra);
868 kfree(ra); 864 kfree(ra);
@@ -881,7 +877,7 @@ int btrfs_ref_tree_mod(struct btrfs_root *root, u64 bytenr, u64 num_bytes,
881 list_add_tail(&ra->list, &be->actions); 877 list_add_tail(&ra->list, &be->actions);
882 ret = 0; 878 ret = 0;
883out_unlock: 879out_unlock:
884 spin_unlock(&root->fs_info->ref_verify_lock); 880 spin_unlock(&fs_info->ref_verify_lock);
885out: 881out:
886 if (ret) 882 if (ret)
887 btrfs_clear_opt(fs_info->mount_opt, REF_VERIFY); 883 btrfs_clear_opt(fs_info->mount_opt, REF_VERIFY);