Btrfs-progs: fix unresolved ref root message
authorMiao Xie <miaox@cn.fujitsu.com>
Fri, 10 Aug 2012 08:14:02 +0000 (16:14 +0800)
committerroot <root@localhost.localdomain>
Thu, 4 Oct 2012 20:26:31 +0000 (16:26 -0400)
btrfsck misinformed "unresolved ref root" message when there were several
snapshots in the file system. The patch(commit cfdd42686c70) tried to fix
this bug, but didn't fix it completely. If the metadata was stored in a
shared leaf of the tree, the problem would happen again. This patch fixes
it by another way, we don't check the relationship of the trees when we
traverse the fs/file tree, we just do the check when we merge the snapshot
records to the root cache.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
btrfsck.c

index f09a4a417d2060e7c754c479ddc5ca1d79081c2b..918d1540a7541059ea0642f2c802c5388a59ab26 100644 (file)
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -857,13 +857,10 @@ static int process_dir_item(struct btrfs_root *root,
                                          key->objectid, key->offset, namebuf,
                                          len, filetype, key->type, error);
                } else if (location.type == BTRFS_ROOT_ITEM_KEY) {
-                       u64 parent = root->objectid;
-
-                       if (is_child_root(root, parent, location.objectid))
-                               add_inode_backref(root_cache, location.objectid,
-                                                 key->objectid, key->offset,
-                                                 namebuf, len, filetype,
-                                                 key->type, error);
+                       add_inode_backref(root_cache, location.objectid,
+                                         key->objectid, key->offset,
+                                         namebuf, len, filetype,
+                                         key->type, error);
                } else {
                        fprintf(stderr, "warning line %d\n", __LINE__);
                }
@@ -1489,6 +1486,9 @@ static int merge_root_recs(struct btrfs_root *root,
                remove_cache_extent(src_cache, &node->cache);
                free(node);
 
+               if (!is_child_root(root, root->objectid, rec->ino))
+                       goto skip;
+
                list_for_each_entry(backref, &rec->backrefs, list) {
                        BUG_ON(backref->found_inode_ref);
                        if (backref->found_dir_item)
@@ -1504,6 +1504,7 @@ static int merge_root_recs(struct btrfs_root *root,
                                        backref->namelen, BTRFS_DIR_INDEX_KEY,
                                        backref->errors);
                }
+skip:
                free_inode_rec(rec);
        }
        return 0;