btrfs-progs: check: introduce repair_chunk_item()
authorSu Yue <suy.fnst@cn.fujitsu.com>
Fri, 1 Sep 2017 06:22:37 +0000 (14:22 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 16 Oct 2017 18:33:01 +0000 (20:33 +0200)
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>
cmds-check.c

index 00eea0a..e9f9d68 100644 (file)
@@ -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: