btrfs-show-super: don't try to print not-superblocks

If we point btrfs-show-super at a not-btrfs-device and
try to print all superblocks, bad things are apt to happen:

superblock: bytenr=274877906944, device=/dev/sdc2
---------------------------------------------------------
btrfs-show-super: ctree.h:1984: btrfs_super_csum_size: \
Assertion `!(t >= (sizeof(btrfs_csum_sizes) / sizeof((btrfs_csum_sizes)[0])))' failed.
csum			0xAborted

Don't try to print superblocks that don't look like superblocks,
and add an "-f" (force) option to try anyway, if the user
really wants to give it a shot.

Fix some spelling & capitalization while we're at it.

The manpage says that if any problem happens, 1 will
be returned, but that's already not true today LOL, so
I didn't bother to make it true when we detect bad
sb magic, either...

I figure it's worth continuing and trying all superblocks
in case just one has a corrupt magic.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
[renamed -f to -F due to clash with existing option, converted
relevant docs to asciidoc]
Signed-off-by: David Sterba <dsterba@suse.cz>
This commit is contained in:
Eric Sandeen 2014-05-13 21:03:04 -05:00 committed by David Sterba
parent da65695cc5
commit fd518cfcb1
2 changed files with 23 additions and 7 deletions

View File

@ -31,6 +31,10 @@ Specify which mirror to print out.
<super_mirror> is between 0 and 2. <super_mirror> is between 0 and 2.
If several '-i <super_mirror>' are given, only the last one is valid. If several '-i <super_mirror>' are given, only the last one is valid.
-F::
Attempt to print the superblock even if no superblock magic is found. May end
badly.
EXIT STATUS EXIT STATUS
----------- -----------
*btrfs-show-super* will return 0 if no error happened. *btrfs-show-super* will return 0 if no error happened.

View File

@ -40,16 +40,17 @@
static void print_usage(void); static void print_usage(void);
static void dump_superblock(struct btrfs_super_block *sb, int full); static void dump_superblock(struct btrfs_super_block *sb, int full);
int main(int argc, char **argv); int main(int argc, char **argv);
static int load_and_dump_sb(char *, int fd, u64 sb_bytenr, int full); static int load_and_dump_sb(char *, int fd, u64 sb_bytenr, int full, int force);
static void print_usage(void) static void print_usage(void)
{ {
fprintf(stderr, fprintf(stderr,
"usage: btrfs-show-super [-i super_mirror|-a|-f] dev [dev..]\n"); "usage: btrfs-show-super [-i super_mirror|-a|-f|-F] dev [dev..]\n");
fprintf(stderr, "\t-f : print full superblock information\n"); fprintf(stderr, "\t-f : print full superblock information\n");
fprintf(stderr, "\t-a : print information of all superblocks\n"); fprintf(stderr, "\t-a : print information of all superblocks\n");
fprintf(stderr, "\t-i <super_mirror> : specify which mirror to print out\n"); fprintf(stderr, "\t-i <super_mirror> : specify which mirror to print out\n");
fprintf(stderr, "\t-F : attempt to dump superblocks with bad magic\n");
fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION); fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
} }
@ -58,13 +59,14 @@ int main(int argc, char **argv)
int opt; int opt;
int all = 0; int all = 0;
int full = 0; int full = 0;
int force = 0;
char *filename; char *filename;
int fd = -1; int fd = -1;
int i; int i;
u64 arg; u64 arg;
u64 sb_bytenr = btrfs_sb_offset(0); u64 sb_bytenr = btrfs_sb_offset(0);
while ((opt = getopt(argc, argv, "fai:")) != -1) { while ((opt = getopt(argc, argv, "fFai:")) != -1) {
switch (opt) { switch (opt) {
case 'i': case 'i':
arg = arg_strtou64(optarg); arg = arg_strtou64(optarg);
@ -84,6 +86,9 @@ int main(int argc, char **argv)
case 'f': case 'f':
full = 1; full = 1;
break; break;
case 'F':
force = 1;
break;
default: default:
print_usage(); print_usage();
exit(1); exit(1);
@ -108,7 +113,7 @@ int main(int argc, char **argv)
for (idx = 0; idx < BTRFS_SUPER_MIRROR_MAX; idx++) { for (idx = 0; idx < BTRFS_SUPER_MIRROR_MAX; idx++) {
sb_bytenr = btrfs_sb_offset(idx); sb_bytenr = btrfs_sb_offset(idx);
if (load_and_dump_sb(filename, fd, if (load_and_dump_sb(filename, fd,
sb_bytenr, full)) { sb_bytenr, full, force)) {
close(fd); close(fd);
exit(1); exit(1);
} }
@ -116,7 +121,7 @@ int main(int argc, char **argv)
putchar('\n'); putchar('\n');
} }
} else { } else {
load_and_dump_sb(filename, fd, sb_bytenr, full); load_and_dump_sb(filename, fd, sb_bytenr, full, force);
putchar('\n'); putchar('\n');
} }
close(fd); close(fd);
@ -125,7 +130,8 @@ int main(int argc, char **argv)
exit(0); exit(0);
} }
static int load_and_dump_sb(char *filename, int fd, u64 sb_bytenr, int full) static int load_and_dump_sb(char *filename, int fd, u64 sb_bytenr, int full,
int force)
{ {
u8 super_block_data[BTRFS_SUPER_INFO_SIZE]; u8 super_block_data[BTRFS_SUPER_INFO_SIZE];
struct btrfs_super_block *sb; struct btrfs_super_block *sb;
@ -150,7 +156,13 @@ static int load_and_dump_sb(char *filename, int fd, u64 sb_bytenr, int full)
} }
printf("superblock: bytenr=%llu, device=%s\n", sb_bytenr, filename); printf("superblock: bytenr=%llu, device=%s\n", sb_bytenr, filename);
printf("---------------------------------------------------------\n"); printf("---------------------------------------------------------\n");
if (btrfs_super_magic(sb) != BTRFS_MAGIC && !force) {
fprintf(stderr,
"ERROR: bad magic on superblock on %s at %llu\n",
filename, (unsigned long long)sb_bytenr);
} else {
dump_superblock(sb, full); dump_superblock(sb, full);
}
return 0; return 0;
} }