+static errcode_t e2fsck_check_mmp(ext2_filsys fs, e2fsck_t ctx)
+{
+ struct mmp_struct *mmp_s;
+ unsigned int mmp_check_interval;
+ errcode_t retval = 0;
+ struct problem_context pctx;
+ unsigned int wait_time = 0;
+
+ clear_problem_context(&pctx);
+ if (fs->mmp_buf == NULL) {
+ retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf);
+ if (retval)
+ goto check_error;
+ }
+
+ retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf);
+ if (retval)
+ goto check_error;
+
+ mmp_s = fs->mmp_buf;
+
+ mmp_check_interval = fs->super->s_mmp_update_interval;
+ if (mmp_check_interval < EXT4_MMP_MIN_CHECK_INTERVAL)
+ mmp_check_interval = EXT4_MMP_MIN_CHECK_INTERVAL;
+
+ /*
+ * If check_interval in MMP block is larger, use that instead of
+ * check_interval from the superblock.
+ */
+ if (mmp_s->mmp_check_interval > mmp_check_interval)
+ mmp_check_interval = mmp_s->mmp_check_interval;
+
+ wait_time = mmp_check_interval * 2 + 1;
+
+ if (mmp_s->mmp_seq == EXT4_MMP_SEQ_CLEAN)
+ retval = 0;
+ else if (mmp_s->mmp_seq == EXT4_MMP_SEQ_FSCK)
+ retval = EXT2_ET_MMP_FSCK_ON;
+ else if (mmp_s->mmp_seq > EXT4_MMP_SEQ_MAX)
+ retval = EXT2_ET_MMP_UNKNOWN_SEQ;
+
+ if (retval)
+ goto check_error;
+
+ /* Print warning if e2fck will wait for more than 20 secs. */
+ if (verbose || wait_time > EXT4_MMP_MIN_CHECK_INTERVAL * 4) {
+ log_out(ctx, _("MMP interval is %u seconds and total wait "
+ "time is %u seconds. Please wait...\n"),
+ mmp_check_interval, wait_time * 2);
+ }
+
+ return 0;
+
+check_error:
+
+ if (retval == EXT2_ET_MMP_BAD_BLOCK) {
+ if (fix_problem(ctx, PR_0_MMP_INVALID_BLK, &pctx)) {
+ fs->super->s_mmp_block = 0;
+ ext2fs_mark_super_dirty(fs);
+ retval = 0;
+ }
+ } else if (retval == EXT2_ET_MMP_FAILED) {
+ com_err(ctx->program_name, retval,
+ _("while checking MMP block"));
+ dump_mmp_msg(fs->mmp_buf, NULL);
+ } else if (retval == EXT2_ET_MMP_FSCK_ON ||
+ retval == EXT2_ET_MMP_UNKNOWN_SEQ) {
+ com_err(ctx->program_name, retval,
+ _("while checking MMP block"));
+ dump_mmp_msg(fs->mmp_buf,
+ _("If you are sure the filesystem is not "
+ "in use on any node, run:\n"
+ "'tune2fs -f -E clear_mmp {device}'\n"));
+ } else if (retval == EXT2_ET_MMP_MAGIC_INVALID) {
+ if (fix_problem(ctx, PR_0_MMP_INVALID_MAGIC, &pctx)) {
+ ext2fs_mmp_clear(fs);
+ retval = 0;
+ }
+ } else if (retval == EXT2_ET_MMP_CSUM_INVALID) {
+ if (fix_problem(ctx, PR_0_MMP_CSUM_INVALID, &pctx)) {
+ ext2fs_mmp_clear(fs);
+ retval = 0;
+ }
+ }
+ return retval;
+}
+