Whamcloud - gitweb
tune2fs: if turning off csum_seed and the UUID has changed, require fsck
[tools/e2fsprogs.git] / misc / tune2fs.c
index 99c17cc..b11b2e3 100644 (file)
@@ -116,6 +116,8 @@ struct blk_move {
 
 errcode_t ext2fs_run_ext3_journal(ext2_filsys *fs);
 
+static const char *fsck_explain = N_("\nThis operation requires a freshly checked filesystem.\n");
+
 static const char *please_fsck = N_("Please run e2fsck -f on the filesystem.\n");
 static const char *please_dir_fsck =
                N_("Please run e2fsck -fD on the filesystem.\n");
@@ -135,9 +137,8 @@ static void usage(void)
                  "[-g group]\n"
                  "\t[-i interval[d|m|w]] [-j] [-J journal_options] [-l]\n"
                  "\t[-m reserved_blocks_percent] [-o [^]mount_options[,...]]\n"
-                 "\t[-p mmp_update_interval] [-r reserved_blocks_count] "
-                 "[-u user]\n"
-                 "\t[-C mount_count] [-L volume_label] [-M last_mounted_dir]\n"
+                 "\t[-r reserved_blocks_count] [-u user] [-C mount_count]\n"
+                 "\t[-L volume_label] [-M last_mounted_dir]\n"
                  "\t[-O [^]feature[,...]] [-Q quota_options]\n"
                  "\t[-E extended-option[,...]] [-T last_check_time] "
                  "[-U UUID]\n\t[-I new_inode_size] [-z undo_file] device\n"),
@@ -419,7 +420,8 @@ static void check_fsck_needed(ext2_filsys fs, const char *prompt)
        if (!(fs->super->s_state & EXT2_VALID_FS) ||
            (fs->super->s_state & EXT2_ERROR_FS) ||
            (fs->super->s_lastcheck < fs->super->s_mtime)) {
-               printf("\n%s\n", _(please_fsck));
+               puts(_(fsck_explain));
+               puts(_(please_fsck));
                if (mount_flags & EXT2_MF_READONLY)
                        printf("%s", _("(and reboot afterwards!)\n"));
                exit(1);
@@ -441,7 +443,8 @@ static void request_dir_fsck_afterwards(ext2_filsys fs)
                return;
        fsck_requested++;
        fs->super->s_state &= ~EXT2_VALID_FS;
-       printf("\n%s\n", _(please_dir_fsck));
+       puts(_(fsck_explain));
+       puts(_(please_dir_fsck));
        if (mount_flags & EXT2_MF_READONLY)
                printf("%s", _("(and reboot afterwards!)\n"));
 }
@@ -461,9 +464,6 @@ static void request_fsck_afterwards(ext2_filsys fs)
 
 static void convert_64bit(ext2_filsys fs, int direction)
 {
-       if (!direction)
-               return;
-
        /*
         * Is resize2fs going to demand a fsck run? Might as well tell the
         * user now.
@@ -1366,16 +1366,18 @@ mmp_error:
 
                uuid_seed = ext2fs_crc32c_le(~0, fs->super->s_uuid,
                                        sizeof(fs->super->s_uuid));
-               if (fs->super->s_checksum_seed != uuid_seed &&
-                   (mount_flags & EXT2_MF_MOUNTED)) {
-                       fputs(_("UUID has changed since enabling "
-                               "metadata_csum.  Filesystem must be unmounted "
-                               "\nto safely rewrite all metadata to "
-                               "match the new UUID.\n"), stderr);
-                       return 1;
+               if (fs->super->s_checksum_seed != uuid_seed) {
+                       if (mount_flags & (EXT2_MF_BUSY|EXT2_MF_MOUNTED)) {
+                               fputs(_("UUID has changed since enabling "
+               "metadata_csum.  Filesystem must be unmounted "
+               "\nto safely rewrite all metadata to match the new UUID.\n"),
+                                     stderr);
+                               return 1;
+                       }
+                       check_fsck_needed(fs, _("Recalculating checksums "
+                                               "could take some time."));
+                       rewrite_checksums = 1;
                }
-
-               rewrite_checksums = 1;
        }
 
        if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
@@ -2084,6 +2086,7 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts)
                        "\tclear_mmp\n"
                        "\thash_alg=<hash algorithm>\n"
                        "\tmount_opts=<extended default mount options>\n"
+                       "\tmmp_update_interval=<mmp update interval in seconds>\n"
                        "\tstride=<RAID per-disk chunk size in blocks>\n"
                        "\tstripe_width=<RAID stride*data disks in blocks>\n"
                        "\ttest_fs\n"
@@ -2909,6 +2912,36 @@ retry_open:
                rc = 1;
                goto closefs;
        }
+
+#ifdef NO_RECOVERY
+       /* Warn if file system needs recovery and it is opened for writing. */
+       if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & EXT2_MF_MOUNTED) &&
+           (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
+           (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER)) {
+               fprintf(stderr,
+_("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
+  "\te2fsck -E journal_only %s\n\n"
+  "then rerun this command.  Otherwise, any changes made may be overwritten\n"
+  "by journal recovery.\n"), device_name);
+       }
+#else
+       /* Recover the journal if possible. */
+       if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & (EXT2_MF_BUSY | EXT2_MF_MOUNTED)) &&
+           ext2fs_has_feature_journal_needs_recovery(fs->super)) {
+               errcode_t err;
+
+               printf(_("Recovering journal.\n"));
+               err = ext2fs_run_ext3_journal(&fs);
+               if (err) {
+                       com_err("tune2fs", err, "while recovering journal.\n");
+                       printf(_("Please run e2fsck -fy %s.\n"), argv[1]);
+                       if (fs)
+                               ext2fs_close_free(&fs);
+                       exit(1);
+               }
+       }
+#endif
+
        /* Normally we only need to write out the superblock */
        fs->flags |= EXT2_FLAG_SUPER_ONLY;
 
@@ -3212,35 +3245,6 @@ retry_open:
                free(ext_mount_opts);
        }
 
-#ifdef NO_RECOVERY
-       /* Warn if file system needs recovery and it is opened for writing. */
-       if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & EXT2_MF_MOUNTED) &&
-           (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
-           (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER)) {
-               fprintf(stderr,
-_("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
-  "\te2fsck -E journal_only %s\n\n"
-  "then rerun this command.  Otherwise, any changes made may be overwritten\n"
-  "by journal recovery.\n"), device_name);
-       }
-#else
-       /* Recover the journal if possible. */
-       if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & EXT2_MF_MOUNTED) &&
-           ext2fs_has_feature_journal_needs_recovery(fs->super)) {
-               errcode_t err;
-
-               printf(_("Recovering journal.\n"));
-               err = ext2fs_run_ext3_journal(&fs);
-               if (err) {
-                       com_err("tune2fs", err, "while recovering journal.\n");
-                       printf(_("Please run e2fsck -fy %s.\n"), argv[1]);
-                       goto closefs;
-               }
-               ext2fs_clear_feature_journal_needs_recovery(fs->super);
-               ext2fs_mark_super_dirty(fs);
-       }
-#endif
-
        free(device_name);
        remove_error_table(&et_ext2_error_table);
 
@@ -3252,6 +3256,7 @@ closefs:
 #endif
        }
 
-       convert_64bit(fs, feature_64bit);
+       if (feature_64bit)
+               convert_64bit(fs, feature_64bit);
        return (ext2fs_close_free(&fs) ? 1 : 0);
 }