Whamcloud - gitweb
misc: remove broken whole device check
[tools/e2fsprogs.git] / misc / dumpe2fs.c
index 73555a9..89a1d81 100644 (file)
@@ -37,24 +37,25 @@ extern int optind;
 
 #include "ext2fs/ext2fs.h"
 #include "e2p/e2p.h"
-#include "jfs_user.h"
+#include "ext2fs/kernel-jbd.h"
 #include <uuid/uuid.h>
 
 #include "../version.h"
 #include "nls-enable.h"
+#include "plausible.h"
 
 #define in_use(m, x)   (ext2fs_test_bit ((x), (m)))
 
-const char * program_name = "dumpe2fs";
-char * device_name = NULL;
-int hex_format = 0;
-int blocks64 = 0;
+static const char * program_name = "dumpe2fs";
+static char * device_name = NULL;
+static int hex_format = 0;
+static int blocks64 = 0;
 
 static void usage(void)
 {
-       fprintf (stderr, _("Usage: %s [-bfhixV] [-o superblock=<num>] "
+       fprintf(stderr, _("Usage: %s [-bfghixV] [-o superblock=<num>] "
                 "[-o blocksize=<num>] device\n"), program_name);
-       exit (1);
+       exit(1);
 }
 
 static void print_number(unsigned long long num)
@@ -150,7 +151,7 @@ static void print_bg_rel_offset(ext2_filsys fs, blk64_t block, int itable,
        }
 }
 
-static void list_desc (ext2_filsys fs)
+static void list_desc(ext2_filsys fs, int grp_only)
 {
        unsigned long i;
        blk64_t first_block, last_block;
@@ -187,6 +188,8 @@ static void list_desc (ext2_filsys fs)
                old_desc_blocks = fs->super->s_first_meta_bg;
        else
                old_desc_blocks = fs->desc_blocks;
+       if (grp_only)
+               printf("group:block:super:gdt:bbitmap:ibitmap:itable\n");
        for (i = 0; i < fs->group_desc_count; i++) {
                first_block = ext2fs_group_first_block2(fs, i);
                last_block = ext2fs_group_last_block2(fs, i);
@@ -194,20 +197,39 @@ static void list_desc (ext2_filsys fs)
                ext2fs_super_and_bgd_loc2(fs, i, &super_blk,
                                          &old_desc_blk, &new_desc_blk, 0);
 
-               printf (_("Group %lu: (Blocks "), i);
+               if (grp_only) {
+                       printf("%lu:%llu:", i, first_block);
+                       if (i == 0 || super_blk)
+                               printf("%llu:", super_blk);
+                       else
+                               printf("-1:");
+                       if (old_desc_blk) {
+                               print_range(old_desc_blk,
+                                           old_desc_blk + old_desc_blocks - 1);
+                               printf(":");
+                       } else if (new_desc_blk)
+                               printf("%llu:", new_desc_blk);
+                       else
+                               printf("-1:");
+                       printf("%llu:%llu:%llu\n",
+                              ext2fs_block_bitmap_loc(fs, i),
+                              ext2fs_inode_bitmap_loc(fs, i),
+                              ext2fs_inode_table_loc(fs, i));
+                       continue;
+               }
+
+               printf(_("Group %lu: (Blocks "), i);
                print_range(first_block, last_block);
                fputs(")", stdout);
-               print_bg_opts(fs, i);
                if (ext2fs_has_group_desc_csum(fs)) {
                        unsigned csum = ext2fs_bg_checksum(fs, i);
                        unsigned exp_csum = ext2fs_group_desc_csum(fs, i);
 
-                       printf(_("  Checksum 0x%04x"), csum);
+                       printf(_(" csum 0x%04x"), csum);
                        if (csum != exp_csum)
                                printf(_(" (EXPECTED 0x%04x)"), exp_csum);
-                       printf(_(", unused inodes %u\n"),
-                              ext2fs_bg_itable_unused(fs, i));
                }
+               print_bg_opts(fs, i);
                has_super = ((i==0) || super_blk);
                if (has_super) {
                        printf (_("  %s superblock at "),
@@ -240,7 +262,11 @@ static void list_desc (ext2_filsys fs)
                    EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)
                        printf(_(", csum 0x%08x"),
                               ext2fs_block_bitmap_checksum(fs, i));
-               fputs(_(", Inode bitmap at "), stdout);
+               if (getenv("DUMPE2FS_IGNORE_80COL"))
+                       fputs(_(","), stdout);
+               else
+                       fputs(_("\n "), stdout);
+               fputs(_(" Inode bitmap at "), stdout);
                print_number(ext2fs_inode_bitmap_loc(fs, i));
                print_bg_rel_offset(fs, ext2fs_inode_bitmap_loc(fs, i), 0,
                                    first_block, last_block);
@@ -355,6 +381,8 @@ static void print_inline_journal_information(ext2_filsys fs)
        __u32                   *mask_ptr, mask, m;
        int                     i, j, size, printed = 0;
 
+       if (fs->flags & EXT2_FLAG_IMAGE_FILE)
+               return;
        retval = ext2fs_read_inode(fs, ino,  &inode);
        if (retval) {
                com_err(program_name, retval, "%s",
@@ -412,9 +440,11 @@ static void print_inline_journal_information(ext2_filsys fs)
               (unsigned int)ntohl(jsb->s_start));
        if (jsb->s_feature_compat &
            ext2fs_cpu_to_be32(JFS_FEATURE_COMPAT_CHECKSUM))
-               printf(_("Journal checksum type:    crc32\n"));
-       if (jsb->s_feature_incompat &
-           ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_CSUM_V2))
+               printf("%s", _("Journal checksum type:    crc32\n"));
+       if ((jsb->s_feature_incompat &
+            ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_CSUM_V3)) ||
+           (jsb->s_feature_incompat &
+            ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_CSUM_V2)))
                printf(_("Journal checksum type:    %s\n"
                         "Journal checksum:         0x%08x\n"),
                       journal_checksum_type_str(jsb->s_checksum_type),
@@ -429,8 +459,9 @@ static void print_journal_information(ext2_filsys fs)
        errcode_t       retval;
        char            buf[1024];
        char            str[80];
-       unsigned int    i;
+       unsigned int    i, j, printed = 0;
        journal_superblock_t    *jsb;
+       __u32                   *mask_ptr, mask, m;
 
        /* Get the journal superblock */
        if ((retval = io_channel_read_blk64(fs->io,
@@ -451,14 +482,27 @@ static void print_journal_information(ext2_filsys fs)
 
        if (jsb->s_feature_compat &
            ext2fs_cpu_to_be32(JFS_FEATURE_COMPAT_CHECKSUM))
-               printf(_("Journal checksum type:    crc32\n"));
-       if (jsb->s_feature_incompat &
-           ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_CSUM_V2))
+               printf("%s", _("Journal checksum type:    crc32\n"));
+       if ((jsb->s_feature_incompat &
+            ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_CSUM_V3)) ||
+           (jsb->s_feature_incompat &
+            ext2fs_cpu_to_be32(JFS_FEATURE_INCOMPAT_CSUM_V2)))
                printf(_("Journal checksum type:    %s\n"
                         "Journal checksum:         0x%08x\n"),
                       journal_checksum_type_str(jsb->s_checksum_type),
                       ext2fs_be32_to_cpu(jsb->s_checksum));
 
+       printf("%s", _("Journal features:        "));
+       for (i = 0, mask_ptr = &jsb->s_feature_compat; i < 3; i++, mask_ptr++) {
+               mask = be32_to_cpu(*mask_ptr);
+               for (j = 0, m = 1; j < 32; j++, m <<= 1) {
+                       if (mask & m) {
+                               printf(" %s", e2p_jrnl_feature2string(i, m));
+                               printed++;
+                       }
+               }
+       }
+
        printf(_("\nJournal block size:       %u\n"
                 "Journal length:           %u\n"
                 "Journal first block:      %u\n"
@@ -566,6 +610,7 @@ int main (int argc, char ** argv)
        int             flags;
        int             header_only = 0;
        int             c;
+       int             grp_only = 0;
 
 #ifdef ENABLE_NLS
        setlocale(LC_MESSAGES, "");
@@ -580,7 +625,7 @@ int main (int argc, char ** argv)
        if (argc && *argv)
                program_name = *argv;
 
-       while ((c = getopt (argc, argv, "bfhixVo:")) != EOF) {
+       while ((c = getopt(argc, argv, "bfghixVo:")) != EOF) {
                switch (c) {
                case 'b':
                        print_badblocks++;
@@ -588,6 +633,9 @@ int main (int argc, char ** argv)
                case 'f':
                        force++;
                        break;
+               case 'g':
+                       grp_only++;
+                       break;
                case 'h':
                        header_only++;
                        break;
@@ -610,15 +658,17 @@ int main (int argc, char ** argv)
                        usage();
                }
        }
-       if (optind > argc - 1)
+       if (optind != argc - 1) {
                usage();
+               exit(1);
+       }
        device_name = argv[optind++];
        flags = EXT2_FLAG_JOURNAL_DEV_OK | EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS;
        if (force)
                flags |= EXT2_FLAG_FORCE;
        if (image_dump)
                flags |= EXT2_FLAG_IMAGE_FILE;
-
+try_open_again:
        if (use_superblock && !use_blocksize) {
                for (use_blocksize = EXT2_MIN_BLOCK_SIZE;
                     use_blocksize <= EXT2_MAX_BLOCK_SIZE;
@@ -633,10 +683,19 @@ int main (int argc, char ** argv)
        } else
                retval = ext2fs_open (device_name, flags, use_superblock,
                                      use_blocksize, unix_io_manager, &fs);
+       if (retval && !(flags & EXT2_FLAG_IGNORE_CSUM_ERRORS)) {
+               flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
+               goto try_open_again;
+       }
+       if (!retval && (fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS))
+               printf("%s", _("\n*** Checksum errors detected in filesystem!  Run e2fsck now!\n\n"));
+       flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
        if (retval) {
                com_err (program_name, retval, _("while trying to open %s"),
                         device_name);
                printf("%s", _("Couldn't find valid filesystem superblock.\n"));
+               if (retval == EXT2_ET_BAD_MAGIC)
+                       check_plausibility(device_name, CHECK_FS_EXIST, NULL);
                exit (1);
        }
        fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE;
@@ -645,11 +704,13 @@ int main (int argc, char ** argv)
        if (print_badblocks) {
                list_bad_blocks(fs, 1);
        } else {
+               if (grp_only)
+                       goto just_descriptors;
                list_super (fs->super);
                if (fs->super->s_feature_incompat &
                      EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
                        print_journal_information(fs);
-                       ext2fs_close(fs);
+                       ext2fs_close_free(&fs);
                        exit(0);
                }
                if ((fs->super->s_feature_compat &
@@ -658,18 +719,27 @@ int main (int argc, char ** argv)
                        print_inline_journal_information(fs);
                list_bad_blocks(fs, 0);
                if (header_only) {
-                       ext2fs_close (fs);
+                       ext2fs_close_free(&fs);
                        exit (0);
                }
+               fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
+try_bitmaps_again:
                retval = ext2fs_read_bitmaps (fs);
-               list_desc (fs);
+               if (retval && !(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS)) {
+                       fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
+                       goto try_bitmaps_again;
+               }
+               if (!retval && (fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS))
+                       printf("%s", _("\n*** Checksum errors detected in bitmaps!  Run e2fsck now!\n\n"));
+just_descriptors:
+               list_desc(fs, grp_only);
                if (retval) {
                        printf(_("\n%s: %s: error reading bitmaps: %s\n"),
                               program_name, device_name,
                               error_message(retval));
                }
        }
-       ext2fs_close (fs);
+       ext2fs_close_free(&fs);
        remove_error_table(&et_ext2_error_table);
        exit (0);
 }