summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--btrfs-find-root.c58
1 files changed, 57 insertions, 1 deletions
diff --git a/btrfs-find-root.c b/btrfs-find-root.c
index cdbcca6d..74a52b7b 100644
--- a/btrfs-find-root.c
+++ b/btrfs-find-root.c
@@ -275,6 +275,61 @@ static int find_root(struct btrfs_root *root)
return ret;
}
+/*
+ * Get reliable generation and level for given root.
+ *
+ * We have two sources of gen/level: superblock and tree root.
+ * superblock include the following level:
+ * Root, chunk, log
+ * and the following generations:
+ * Root, chunk, uuid
+ * Other gen/leven can only be read from its btrfs_tree_root if possible.
+ *
+ * Currently we only believe things from superblock.
+ */
+static void get_root_gen_and_level(u64 objectid, struct btrfs_fs_info *fs_info,
+ u64 *ret_gen, u8 *ret_level)
+{
+ struct btrfs_super_block *super = fs_info->super_copy;
+ u64 gen = (u64)-1;
+ u8 level = (u8)-1;
+
+ switch (objectid) {
+ case BTRFS_ROOT_TREE_OBJECTID:
+ level = btrfs_super_root_level(super);
+ gen = btrfs_super_generation(super);
+ break;
+ case BTRFS_CHUNK_TREE_OBJECTID:
+ level = btrfs_super_chunk_root_level(super);
+ gen = btrfs_super_chunk_root_generation(super);
+ printf("Search for chunk root is not supported yet\n");
+ break;
+ case BTRFS_TREE_LOG_OBJECTID:
+ level = btrfs_super_log_root_level(super);
+ gen = btrfs_super_log_root_transid(super);
+ break;
+ case BTRFS_UUID_TREE_OBJECTID:
+ gen = btrfs_super_uuid_tree_generation(super);
+ break;
+ }
+ if (gen != (u64)-1) {
+ printf("Superblock thinks the generation is %llu\n", gen);
+ if (ret_gen)
+ *ret_gen = gen;
+ } else {
+ printf("Superblock doesn't contain generation info for root %llu\n",
+ objectid);
+ }
+ if (level != (u8)-1) {
+ printf("Superblock thinks the level is %u\n", level);
+ if (ret_level)
+ *ret_level = level;
+ } else {
+ printf("Superblock doesn't contain the level info for root %llu\n",
+ objectid);
+ }
+}
+
int main(int argc, char **argv)
{
struct btrfs_root *root;
@@ -312,7 +367,8 @@ int main(int argc, char **argv)
}
if (search_generation == 0)
- search_generation = btrfs_super_generation(root->fs_info->super_copy);
+ get_root_gen_and_level(search_objectid, root->fs_info,
+ &search_generation, NULL);
csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
ret = find_root(root);