* [PATCH] Btrfs-progs: fix unresolved refs bug of btrfsck
@ 2012-06-21 12:17 Liu Bo
0 siblings, 0 replies; only message in thread
From: Liu Bo @ 2012-06-21 12:17 UTC (permalink / raw)
To: linux-btrfs
$ btrfs sub snap /mnt/ /mnt/s1
$ btrfs sub snap /mnt/ /mnt/s2
$ btrfsck disk
then we'll get several "unresolved ref" info, which is not expected.
The cause is that when we make a snapshot, we won't insert root ref/backref
for the snapshot, and btrfsck will report errors.
This is a btrfsck bug, since our metadata is all right, so we make such a rule:
When the src has the ref/backref on A, src's snapshot also has the ref/backref
on A.
Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
---
btrfsck.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 82 insertions(+), 0 deletions(-)
diff --git a/btrfsck.c b/btrfsck.c
index 7aac736..3a2b4ec 100644
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -1439,6 +1439,76 @@ static int merge_root_recs(struct btrfs_root *root,
return 0;
}
+/*
+ * 1: a snapshot,
+ * 0: not.
+ */
+static int check_snapshot(struct btrfs_root *root, u64 ref_root, u64 *root_ret)
+{
+ struct btrfs_root *tree_root = root->fs_info->tree_root;
+ struct btrfs_key key;
+ struct btrfs_path path;
+ struct extent_buffer *leaf;
+ int ret = 0;
+
+ *root_ret = 0;
+
+ btrfs_init_path(&path);
+
+ key.offset = 0;
+ key.objectid = ref_root;
+ key.type = BTRFS_ROOT_ITEM_KEY;
+ ret = btrfs_search_slot(NULL, tree_root, &key, &path, 0, 0);
+ BUG_ON(ret < 0);
+
+ leaf = path.nodes[0];
+ btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
+ if (key.type != BTRFS_ROOT_ITEM_KEY) {
+ ret = -ENOENT;
+ goto out;
+ }
+ if (key.offset == 0) {
+ ret = 0;
+ goto out;
+ }
+
+ /* key.offset is non-zero, a snapshot */
+ path.slots[0]++;
+ while (1) {
+ leaf = path.nodes[0];
+ if (path.slots[0] >= btrfs_header_nritems(leaf)) {
+ ret = btrfs_next_leaf(tree_root, &path);
+ if (ret != 0)
+ break;
+ leaf = path.nodes[0];
+ }
+ btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
+ if (key.type == BTRFS_ROOT_BACKREF_KEY) {
+ *root_ret = key.offset;
+ break;
+ }
+ path.slots[0]++;
+ }
+
+out:
+ btrfs_release_path(tree_root, &path);
+ return ret;
+}
+
+static void update_backref(struct root_record *rec, struct root_backref *ref,
+ u64 ref_root)
+{
+ struct root_backref *backref;
+
+ list_for_each_entry(backref, &rec->backrefs, list) {
+ if (backref->ref_root == ref_root) {
+ ref->found_back_ref = backref->found_back_ref;
+ ref->found_forward_ref = backref->found_forward_ref;
+ break;
+ }
+ }
+}
+
static int check_root_refs(struct btrfs_root *root,
struct cache_tree *root_cache)
{
@@ -1511,6 +1581,18 @@ static int check_root_refs(struct btrfs_root *root,
backref->errors |= REF_ERR_NO_DIR_ITEM;
if (!backref->found_dir_index)
backref->errors |= REF_ERR_NO_DIR_INDEX;
+ if (!backref->found_back_ref &&
+ !backref->found_forward_ref) {
+ u64 ref_root_objectid = 0;
+ int is_snap = 0;
+
+ is_snap = check_snapshot(root,
+ backref->ref_root,
+ &ref_root_objectid);
+ if (is_snap && ref_root_objectid)
+ update_backref(rec, backref,
+ ref_root_objectid);
+ }
if (!backref->found_back_ref)
backref->errors |= REF_ERR_NO_ROOT_BACKREF;
if (!backref->found_forward_ref)
--
1.6.5.2
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2012-06-21 12:09 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-21 12:17 [PATCH] Btrfs-progs: fix unresolved refs bug of btrfsck Liu Bo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).