X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=cmds-inspect-dump-super.c;h=e965267c5d96571539a267d7e16458fb897c6746;hb=refs%2Fheads%2Ftizen_5.5_tv;hp=12d93c5422c5a7064404eed2b61dbbd7d2aa5cfa;hpb=eaa93e3b0295fc94c774ec73056559a6b8c78b42;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/cmds-inspect-dump-super.c b/cmds-inspect-dump-super.c index 12d93c5..e965267 100644 --- a/cmds-inspect-dump-super.c +++ b/cmds-inspect-dump-super.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "ctree.h" #include "disk-io.h" @@ -32,14 +33,14 @@ #include "utils.h" #include "commands.h" #include "crc32c.h" -#include "cmds-inspect-dump-super.h" +#include "help.h" static int check_csum_sblock(void *sb, int csum_size) { - char result[BTRFS_CSUM_SIZE]; + u8 result[BTRFS_CSUM_SIZE]; u32 crc = ~(u32)0; - crc = btrfs_csum_data(NULL, (char *)sb + BTRFS_CSUM_SIZE, + crc = btrfs_csum_data((char *)sb + BTRFS_CSUM_SIZE, crc, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); btrfs_csum_final(crc, result); @@ -62,14 +63,22 @@ static void print_sys_chunk_array(struct btrfs_super_block *sb) buf = malloc(sizeof(*buf) + sizeof(*sb)); if (!buf) { - fprintf(stderr, "%s\n", strerror(ENOMEM)); - goto out; + error("not enough memory"); + return; } write_extent_buffer(buf, sb, 0, sizeof(*sb)); + buf->len = sizeof(*sb); array_size = btrfs_super_sys_array_size(sb); array_ptr = sb->sys_chunk_array; sb_array_offset = offsetof(struct btrfs_super_block, sys_chunk_array); + + if (array_size > BTRFS_SYSTEM_CHUNK_ARRAY_SIZE) { + error("sys_array_size %u shouldn't exceed %u bytes", + array_size, BTRFS_SYSTEM_CHUNK_ARRAY_SIZE); + goto out; + } + cur_offset = 0; item = 0; @@ -99,20 +108,19 @@ static void print_sys_chunk_array(struct btrfs_super_block *sb) if (cur_offset + len > array_size) goto out_short_read; - print_chunk(buf, chunk); num_stripes = btrfs_chunk_num_stripes(buf, chunk); if (!num_stripes) { - printk( - "ERROR: invalid number of stripes %u in sys_array at offset %u\n", + error( + "invalid number of stripes %u in sys_array at offset %u", num_stripes, cur_offset); break; } len = btrfs_chunk_item_size(num_stripes); if (cur_offset + len > array_size) goto out_short_read; + print_chunk_item(buf, chunk); } else { - printk( - "ERROR: unexpected item type %u in sys_array at offset %u\n", + error("unexpected item type %u in sys_array at offset %u", (u32)key.type, cur_offset); break; } @@ -123,12 +131,12 @@ static void print_sys_chunk_array(struct btrfs_super_block *sb) item++; } - free(buf); out: + free(buf); return; out_short_read: - printk("ERROR: sys_array too short to read %u bytes at offset %u\n", + error("sys_array too short to read %u bytes at offset %u", len, cur_offset); free(buf); } @@ -197,6 +205,16 @@ struct readable_flag_entry { char *output; }; +#define DEF_COMPAT_RO_FLAG_ENTRY(bit_name) \ + {BTRFS_FEATURE_COMPAT_RO_##bit_name, #bit_name} + +static struct readable_flag_entry compat_ro_flags_array[] = { + DEF_COMPAT_RO_FLAG_ENTRY(FREE_SPACE_TREE), + DEF_COMPAT_RO_FLAG_ENTRY(FREE_SPACE_TREE_VALID), +}; +static const int compat_ro_flags_num = sizeof(compat_ro_flags_array) / + sizeof(struct readable_flag_entry); + #define DEF_INCOMPAT_FLAG_ENTRY(bit_name) \ {BTRFS_FEATURE_INCOMPAT_##bit_name, #bit_name} @@ -205,7 +223,7 @@ static struct readable_flag_entry incompat_flags_array[] = { DEF_INCOMPAT_FLAG_ENTRY(DEFAULT_SUBVOL), DEF_INCOMPAT_FLAG_ENTRY(MIXED_GROUPS), DEF_INCOMPAT_FLAG_ENTRY(COMPRESS_LZO), - DEF_INCOMPAT_FLAG_ENTRY(COMPRESS_LZOv2), + DEF_INCOMPAT_FLAG_ENTRY(COMPRESS_ZSTD), DEF_INCOMPAT_FLAG_ENTRY(BIG_METADATA), DEF_INCOMPAT_FLAG_ENTRY(EXTENDED_IREF), DEF_INCOMPAT_FLAG_ENTRY(RAID56), @@ -268,6 +286,19 @@ static void __print_readable_flag(u64 flag, struct readable_flag_entry *array, printf(")\n"); } +static void print_readable_compat_ro_flag(u64 flag) +{ + /* + * We know about the FREE_SPACE_TREE{,_VALID} bits, but we don't + * actually support them yet. + */ + return __print_readable_flag(flag, compat_ro_flags_array, + compat_ro_flags_num, + BTRFS_FEATURE_COMPAT_RO_SUPP | + BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE | + BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID); +} + static void print_readable_incompat_flag(u64 flag) { return __print_readable_flag(flag, incompat_flags_array, @@ -286,11 +317,32 @@ static void dump_superblock(struct btrfs_super_block *sb, int full) int i; char *s, buf[BTRFS_UUID_UNPARSED_SIZE]; u8 *p; + u32 csum_size; + u16 csum_type; + + csum_type = btrfs_super_csum_type(sb); + csum_size = BTRFS_CSUM_SIZE; + printf("csum_type\t\t%hu (", csum_type); + if (csum_type >= ARRAY_SIZE(btrfs_csum_sizes)) { + printf("INVALID"); + } else { + if (csum_type == BTRFS_CSUM_TYPE_CRC32) { + printf("crc32c"); + csum_size = btrfs_csum_sizes[csum_type]; + } else { + printf("unknown"); + } + } + printf(")\n"); + printf("csum_size\t\t%llu\n", (unsigned long long)csum_size); printf("csum\t\t\t0x"); - for (i = 0, p = sb->csum; i < btrfs_super_csum_size(sb); i++) + for (i = 0, p = sb->csum; i < csum_size; i++) printf("%02x", p[i]); - if (check_csum_sblock(sb, btrfs_super_csum_size(sb))) + if (csum_type != BTRFS_CSUM_TYPE_CRC32 || + csum_size != btrfs_csum_sizes[BTRFS_CSUM_TYPE_CRC32]) + printf(" [UNKNOWN CSUM TYPE OR SIZE]"); + else if (check_csum_sblock(sb, csum_size)) printf(" [match]"); else printf(" [DON'T MATCH]"); @@ -347,8 +399,8 @@ static void dump_superblock(struct btrfs_super_block *sb, int full) (unsigned long long)btrfs_super_sectorsize(sb)); printf("nodesize\t\t%llu\n", (unsigned long long)btrfs_super_nodesize(sb)); - printf("leafsize\t\t%llu\n", - (unsigned long long)btrfs_super_leafsize(sb)); + printf("leafsize (deprecated)\t\t%u\n", + le32_to_cpu(sb->__unused_leafsize)); printf("stripesize\t\t%llu\n", (unsigned long long)btrfs_super_stripesize(sb)); printf("root_dir\t\t%llu\n", @@ -359,13 +411,10 @@ static void dump_superblock(struct btrfs_super_block *sb, int full) (unsigned long long)btrfs_super_compat_flags(sb)); printf("compat_ro_flags\t\t0x%llx\n", (unsigned long long)btrfs_super_compat_ro_flags(sb)); + print_readable_compat_ro_flag(btrfs_super_compat_ro_flags(sb)); printf("incompat_flags\t\t0x%llx\n", (unsigned long long)btrfs_super_incompat_flags(sb)); print_readable_incompat_flag(btrfs_super_incompat_flags(sb)); - printf("csum_type\t\t%llu\n", - (unsigned long long)btrfs_super_csum_type(sb)); - printf("csum_size\t\t%llu\n", - (unsigned long long)btrfs_super_csum_size(sb)); printf("cache_generation\t%llu\n", (unsigned long long)btrfs_super_cache_generation(sb)); printf("uuid_tree_generation\t%llu\n", @@ -424,19 +473,16 @@ static int load_and_dump_sb(char *filename, int fd, u64 sb_bytenr, int full, if (ret == 0 && errno == 0) return 0; - fprintf(stderr, - "ERROR: Failed to read the superblock on %s at %llu\n", - filename, (unsigned long long)sb_bytenr); - fprintf(stderr, - "ERROR: error = '%s', errno = %d\n", strerror(errno), errno); + error("failed to read the superblock on %s at %llu", + filename, (unsigned long long)sb_bytenr); + error("error = '%m', errno = %d", errno); return 1; } printf("superblock: bytenr=%llu, device=%s\n", sb_bytenr, filename); 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); + error("bad magic on superblock on %s at %llu", + filename, (unsigned long long)sb_bytenr); } else { dump_superblock(sb, full); } @@ -445,18 +491,24 @@ static int load_and_dump_sb(char *filename, int fd, u64 sb_bytenr, int full, const char * const cmd_inspect_dump_super_usage[] = { "btrfs inspect-internal dump-super [options] device [device...]", - "Dump superblock from a device", - "-f print full superblock information", - "-a print information of all superblocks", - "-i specify which mirror to print out", - "-F attempt to dump superblocks with bad magic", - "-s specify alternate superblock offset", + "Dump superblock from a device in a textual form", + "-f|--full print full superblock information, backup roots etc.", + "-a|--all print information about all superblocks", + "-s|--super specify which copy to print out (values: 0, 1, 2)", + "-F|--force attempt to dump superblocks with bad magic", + "--bytenr specify alternate superblock offset", + "", + "Deprecated syntax:", + "-s specify alternate superblock offset, values other than 0, 1, 2", + " will be interpreted as --bytenr for backward compatibility,", + " option renamed for consistency with other tools (eg. check)", + "-i specify which copy to print out (values: 0, 1, 2), now moved", + " to -s|--super", NULL }; int cmd_inspect_dump_super(int argc, char **argv) { - int opt; int all = 0; int full = 0; int force = 0; @@ -467,15 +519,31 @@ int cmd_inspect_dump_super(int argc, char **argv) u64 arg; u64 sb_bytenr = btrfs_sb_offset(0); - while ((opt = getopt(argc, argv, "fFai:s:")) != -1) { - switch (opt) { + while (1) { + int c; + enum { GETOPT_VAL_BYTENR = 257 }; + static const struct option long_options[] = { + {"all", no_argument, NULL, 'a'}, + {"bytenr", required_argument, NULL, GETOPT_VAL_BYTENR }, + {"full", no_argument, NULL, 'f'}, + {"force", no_argument, NULL, 'F'}, + {"super", required_argument, NULL, 's' }, + {NULL, 0, NULL, 0} + }; + + c = getopt_long(argc, argv, "fFai:s:", long_options, NULL); + if (c < 0) + break; + + switch (c) { case 'i': + warning( + "option -i is deprecated, please use -s or --super"); arg = arg_strtou64(optarg); if (arg >= BTRFS_SUPER_MIRROR_MAX) { - fprintf(stderr, - "Illegal super_mirror %llu\n", - arg); - usage(cmd_inspect_dump_super_usage); + error("super mirror too big: %llu >= %d", + arg, BTRFS_SUPER_MIRROR_MAX); + return 1; } sb_bytenr = btrfs_sb_offset(arg); break; @@ -490,7 +558,20 @@ int cmd_inspect_dump_super(int argc, char **argv) force = 1; break; case 's': - sb_bytenr = arg_strtou64(optarg); + arg = arg_strtou64(optarg); + if (BTRFS_SUPER_MIRROR_MAX <= arg) { + warning( + "deprecated use of -s with %llu, assuming --bytenr", + (unsigned long long)arg); + sb_bytenr = arg; + } else { + sb_bytenr = btrfs_sb_offset(arg); + } + all = 0; + break; + case GETOPT_VAL_BYTENR: + arg = arg_strtou64(optarg); + sb_bytenr = arg; all = 0; break; default: @@ -503,9 +584,9 @@ int cmd_inspect_dump_super(int argc, char **argv) for (i = optind; i < argc; i++) { filename = argv[i]; - fd = open(filename, O_RDONLY, 0666); + fd = open(filename, O_RDONLY); if (fd < 0) { - fprintf(stderr, "Could not open %s\n", filename); + error("cannot open %s: %m", filename); ret = 1; goto out; }