mirror of
https://github.com/kdave/btrfs-progs
synced 2025-02-26 15:01:03 +00:00
Add options to btrfs-find-root to control generation and level
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
This commit is contained in:
parent
e035bcdddb
commit
f4ca892339
@ -37,10 +37,13 @@
|
|||||||
|
|
||||||
static u16 csum_size = 0;
|
static u16 csum_size = 0;
|
||||||
static u64 search_objectid = BTRFS_ROOT_TREE_OBJECTID;
|
static u64 search_objectid = BTRFS_ROOT_TREE_OBJECTID;
|
||||||
|
static u64 search_generation = 0;
|
||||||
|
static unsigned long search_level = 0;
|
||||||
|
|
||||||
static void usage()
|
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)
|
int csum_block(void *buf, u32 len)
|
||||||
@ -126,10 +129,10 @@ out:
|
|||||||
static int search_iobuf(struct btrfs_root *root, void *iobuf,
|
static int search_iobuf(struct btrfs_root *root, void *iobuf,
|
||||||
size_t iobuf_size, off_t offset)
|
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;
|
u64 objectid = search_objectid;
|
||||||
u32 size = btrfs_super_nodesize(root->fs_info->super_copy);
|
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;
|
size_t block_off = 0;
|
||||||
|
|
||||||
while (block_off < iobuf_size) {
|
while (block_off < iobuf_size) {
|
||||||
@ -147,8 +150,9 @@ static int search_iobuf(struct btrfs_root *root, void *iobuf,
|
|||||||
goto next;
|
goto next;
|
||||||
if (h_byte != (offset + block_off))
|
if (h_byte != (offset + block_off))
|
||||||
goto next;
|
goto next;
|
||||||
if (h_level != level)
|
if (h_level < level)
|
||||||
goto next;
|
goto next;
|
||||||
|
level = h_level;
|
||||||
if (csum_block(block, size)) {
|
if (csum_block(block, size)) {
|
||||||
fprintf(stderr, "Well block %Lu seems good, "
|
fprintf(stderr, "Well block %Lu seems good, "
|
||||||
"but the csum doesn't match\n",
|
"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) {
|
if (h_gen != gen) {
|
||||||
fprintf(stderr, "Well block %Lu seems great, "
|
fprintf(stderr, "Well block %Lu seems great, "
|
||||||
"but generation doesn't match, "
|
"but generation doesn't match, "
|
||||||
"have=%Lu, want=%Lu\n", h_byte, h_gen,
|
"have=%Lu, want=%Lu level %Lu\n", h_byte,
|
||||||
gen);
|
h_gen, gen, h_level);
|
||||||
goto next;
|
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;
|
return 0;
|
||||||
next:
|
next:
|
||||||
block_off += size;
|
block_off += size;
|
||||||
@ -281,10 +286,10 @@ int main(int argc, char **argv)
|
|||||||
int opt;
|
int opt;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "o:")) != -1) {
|
while ((opt = getopt(argc, argv, "l:o:g:")) != -1) {
|
||||||
switch(opt) {
|
switch(opt) {
|
||||||
case 'o':
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
case 'o':
|
||||||
search_objectid = (u64)strtoll(optarg, NULL,
|
search_objectid = (u64)strtoll(optarg, NULL,
|
||||||
10);
|
10);
|
||||||
if (errno) {
|
if (errno) {
|
||||||
@ -293,6 +298,23 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
usage();
|
usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -318,6 +340,9 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
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);
|
csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
|
||||||
ret = find_root(root);
|
ret = find_root(root);
|
||||||
close_ctree(root);
|
close_ctree(root);
|
||||||
|
Loading…
Reference in New Issue
Block a user