aboutsummaryrefslogtreecommitdiffstats
path: root/btrfs-find-root.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@fusionio.com>2013-07-05 12:11:22 -0400
committerChris Mason <chris.mason@fusionio.com>2013-07-05 12:12:35 -0400
commitf4ca8923398f72c4ff3f4b60bb46f33994c0bc6c (patch)
tree8575b20d841f069005582530f3c3c693893bd6fb /btrfs-find-root.c
parente035bcdddbd9dbe890e048066df6cbdd7cc06815 (diff)
downloadbtrfs-progs-f4ca8923398f72c4ff3f4b60bb46f33994c0bc6c.tar.gz
btrfs-progs-f4ca8923398f72c4ff3f4b60bb46f33994c0bc6c.tar.xz
btrfs-progs-f4ca8923398f72c4ff3f4b60bb46f33994c0bc6c.zip
Add options to btrfs-find-root to control generation and level
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'btrfs-find-root.c')
-rw-r--r--btrfs-find-root.c43
1 files 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] <device>\n");
+ fprintf(stderr, "Usage: find-roots [-o search_objectid] "
+ "[ -g search_generation ] [ -l search_level ] <device>\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);