From: Liu Bo <liubo2009@cn.fujitsu.com>
To: <linux-btrfs@vger.kernel.org>
Subject: [PATCH] Btrfs-progs: fix unresolved refs bug of btrfsck
Date: Thu, 21 Jun 2012 20:17:28 +0800 [thread overview]
Message-ID: <1340281048-4133-1-git-send-email-liubo2009@cn.fujitsu.com> (raw)
$ 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
reply other threads:[~2012-06-21 12:09 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1340281048-4133-1-git-send-email-liubo2009@cn.fujitsu.com \
--to=liubo2009@cn.fujitsu.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).