summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2014-10-10 16:57:15 -0400
committerDavid Sterba <dsterba@suse.cz>2014-10-14 10:47:59 +0200
commitc2e686d76a310623495c63b2e3dd8b5ec8bab194 (patch)
tree089f43d83695b2a55619566543bf24bd00491000
parentbb561f5485ab5852214e115116507524e45daff8 (diff)
Btrfs-progs: deal with mismatch index between dir index and inode ref
Sometimes we have a dir index and an inode ref that don't agree on the index. In this case just assume that the inode ref is the ultimate authority on the subject and delete the dir index. This means we have to not reset index if we find a mismatched inode ref to make sure we delete the right dir index. Thanks, Signed-off-by: Josef Bacik <jbacik@fb.com> Signed-off-by: David Sterba <dsterba@suse.cz>
-rw-r--r--cmds-check.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/cmds-check.c b/cmds-check.c
index 8150203f..6fada450 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -620,9 +620,10 @@ static int add_inode_backref(struct cache_tree *inode_cache,
backref->errors |= REF_ERR_DUP_INODE_REF;
if (backref->found_dir_index && backref->index != index)
backref->errors |= REF_ERR_INDEX_UNMATCH;
+ else
+ backref->index = index;
backref->ref_type = itemtype;
- backref->index = index;
backref->found_inode_ref = 1;
} else {
BUG_ON(1);
@@ -1719,8 +1720,10 @@ static int repair_inode_backrefs(struct btrfs_root *root,
if (rec->ino == root_dirid && backref->index == 0)
continue;
- if (delete && backref->found_dir_index &&
- !backref->found_inode_ref) {
+ if (delete &&
+ ((backref->found_dir_index && !backref->found_inode_ref) ||
+ (backref->found_dir_index && backref->found_inode_ref &&
+ (backref->errors & REF_ERR_INDEX_UNMATCH)))) {
ret = delete_dir_index(root, inode_cache, rec, backref);
if (ret)
break;