summaryrefslogtreecommitdiff
path: root/cmds-check.c
diff options
context:
space:
mode:
authorSu Yue <suy.fnst@cn.fujitsu.com>2017-09-01 14:22:37 +0800
committerDavid Sterba <dsterba@suse.com>2017-10-16 20:33:01 +0200
commita8ede30f93ad3f2c64b93f93713d89b15d5077a1 (patch)
tree2af84f8778a363540802bd346ad99f262b4aa571 /cmds-check.c
parente3541e93e8c31e019541161cabddc03165b2e26d (diff)
btrfs-progs: check: introduce repair_chunk_item()
Because this patchset concentrates on repair of extent tree, repair_chunk_item() now only inserts missed chunk group item into extent tree. There are some things left TODO, for example dev_item fix. Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'cmds-check.c')
-rw-r--r--cmds-check.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/cmds-check.c b/cmds-check.c
index 00eea0a4..e9f9d683 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -12643,6 +12643,49 @@ out:
}
/*
+ * Add block group item to the extent tree if @err contains REFERENCER_MISSING.
+ * FIXME: We still need to repair error of dev_item.
+ *
+ * Returns error after repair.
+ */
+static int repair_chunk_item(struct btrfs_trans_handle *trans,
+ struct btrfs_root *chunk_root,
+ struct btrfs_path *path, int err)
+{
+ struct btrfs_chunk *chunk;
+ struct btrfs_key chunk_key;
+ struct extent_buffer *eb = path->nodes[0];
+ u64 length;
+ int slot = path->slots[0];
+ u64 type;
+ int ret = 0;
+
+ btrfs_item_key_to_cpu(eb, &chunk_key, slot);
+ if (chunk_key.type != BTRFS_CHUNK_ITEM_KEY)
+ return err;
+ chunk = btrfs_item_ptr(eb, slot, struct btrfs_chunk);
+ type = btrfs_chunk_type(path->nodes[0], chunk);
+ length = btrfs_chunk_length(eb, chunk);
+
+ if (err & REFERENCER_MISSING) {
+ ret = btrfs_make_block_group(trans, chunk_root->fs_info, 0,
+ type, chunk_key.objectid, chunk_key.offset, length);
+ if (ret) {
+ error("fail to add block group item[%llu %llu]",
+ chunk_key.offset, length);
+ goto out;
+ } else {
+ err &= ~REFERENCER_MISSING;
+ printf("Added block group item[%llu %llu]\n",
+ chunk_key.offset, length);
+ }
+ }
+
+out:
+ return err;
+}
+
+/*
* Check a chunk item.
* Including checking all referred dev_extents and block group
*/
@@ -12829,6 +12872,8 @@ again:
break;
case BTRFS_CHUNK_ITEM_KEY:
ret = check_chunk_item(fs_info, eb, slot);
+ if (repair && ret)
+ ret = repair_chunk_item(trans, root, path, ret);
err |= ret;
break;
case BTRFS_DEV_EXTENT_KEY: