From f4ca8923398f72c4ff3f4b60bb46f33994c0bc6c Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 5 Jul 2013 12:11:22 -0400 Subject: [PATCH] Add options to btrfs-find-root to control generation and level Signed-off-by: Chris Mason --- btrfs-find-root.c | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/btrfs-find-root.c b/btrfs-find-root.c index f2cc1bf..9b3d7df 100644 --- a/btrfs-find-root.c +++ b/btrfs-find-root.c @@ -37,10 +37,13 @@ static u16 csum_size = 0; static u64 search_objectid = BTRFS_ROOT_TREE_OBJECTID; +static u64 search_generation = 0; +static unsigned long search_level = 0; static void usage() { - fprintf(stderr, "Usage: find-roots [-o search_objectid] \n"); + fprintf(stderr, "Usage: find-roots [-o search_objectid] " + "[ -g search_generation ] [ -l search_level ] \n"); } int csum_block(void *buf, u32 len) @@ -126,10 +129,10 @@ out: static int search_iobuf(struct btrfs_root *root, void *iobuf, size_t iobuf_size, off_t offset) { - u64 gen = btrfs_super_generation(root->fs_info->super_copy); + u64 gen = search_generation; u64 objectid = search_objectid; u32 size = btrfs_super_nodesize(root->fs_info->super_copy); - u8 level = root->fs_info->super_copy->root_level; + u8 level = search_level; size_t block_off = 0; while (block_off < iobuf_size) { @@ -147,8 +150,9 @@ static int search_iobuf(struct btrfs_root *root, void *iobuf, goto next; if (h_byte != (offset + block_off)) goto next; - if (h_level != level) + if (h_level < level) goto next; + level = h_level; if (csum_block(block, size)) { fprintf(stderr, "Well block %Lu seems good, " "but the csum doesn't match\n", @@ -158,11 +162,12 @@ static int search_iobuf(struct btrfs_root *root, void *iobuf, if (h_gen != gen) { fprintf(stderr, "Well block %Lu seems great, " "but generation doesn't match, " - "have=%Lu, want=%Lu\n", h_byte, h_gen, - gen); + "have=%Lu, want=%Lu level %Lu\n", h_byte, + h_gen, gen, h_level); goto next; } - printf("Found tree root at %Lu\n", h_byte); + printf("Found tree root at %Lu gen %Lu level %Lu\n", h_byte, + h_gen, h_level); return 0; next: block_off += size; @@ -281,10 +286,10 @@ int main(int argc, char **argv) int opt; int ret; - while ((opt = getopt(argc, argv, "o:")) != -1) { + while ((opt = getopt(argc, argv, "l:o:g:")) != -1) { switch(opt) { + errno = 0; case 'o': - errno = 0; search_objectid = (u64)strtoll(optarg, NULL, 10); if (errno) { @@ -293,6 +298,23 @@ int main(int argc, char **argv) exit(1); } break; + case 'g': + search_generation = (u64)strtoll(optarg, NULL, + 10); + if (errno) { + fprintf(stderr, "Error parsing " + "generation\n"); + exit(1); + } + break; + case 'l': + search_level = strtol(optarg, NULL, 10); + if (errno) { + fprintf(stderr, "Error parsing " + "level\n"); + exit(1); + } + break; default: usage(); exit(1); @@ -318,6 +340,9 @@ int main(int argc, char **argv) exit(1); } + if (search_generation == 0) + search_generation = btrfs_super_generation(root->fs_info->super_copy); + csum_size = btrfs_super_csum_size(root->fs_info->super_copy); ret = find_root(root); close_ctree(root); -- 2.7.4