Jounral superblock may be failed to update in e2fsck_journal_release. But if needs_recovery flag is cleared, e2fsck_check_ext3_journal will be failed.
To fix this case, we use "fatal_error" when recover journal failed. So we can reserve the recovery flag to recover the journal when try e2fsck again.
Fix issue:https://gitee.com/src-openeuler/e2fsprogs/issues/I4S0SD?from=project-issue
Reported-by: Liangyun liangyun2@huawei.com Signed-off-by: Liangyun liangyun2@huawei.com --- e2fsck/journal.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/e2fsck/journal.c b/e2fsck/journal.c index df4f354..a9b5b51 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -757,10 +757,12 @@ static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx, return 0; }
-static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal, +static errcode_t e2fsck_journal_release(e2fsck_t ctx, journal_t *journal, int reset, int drop) { journal_superblock_t *jsb; + errcode_t err = 0; + errcode_t err2;
if (drop) mark_buffer_clean(journal->j_sb_buffer); @@ -774,6 +776,16 @@ static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal, } brelse(journal->j_sb_buffer);
+ if(reset == 1 && drop == 0) { + err = sync_blockdev(journal->j_fs_dev); + /* Make sure all replayed data is on permanent storage */ + if (journal->j_flags & JFS_BARRIER) { + err2 = blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); + if (!err) + err = err2; + } + } + if (ctx->journal_io) { if (ctx->fs && ctx->fs->io != ctx->journal_io) io_channel_close(ctx->journal_io); @@ -787,6 +799,8 @@ static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal, if (journal->j_fs_dev) ext2fs_free_mem(&journal->j_fs_dev); ext2fs_free_mem(&journal); + + return err; }
/* @@ -925,6 +939,7 @@ static errcode_t recover_ext3_journal(e2fsck_t ctx) struct problem_context pctx; journal_t *journal; errcode_t retval; + errcode_t recover_retval;
clear_problem_context(&pctx);
@@ -964,7 +979,14 @@ static errcode_t recover_ext3_journal(e2fsck_t ctx) errout: journal_destroy_revoke(journal); journal_destroy_revoke_caches(); - e2fsck_journal_release(ctx, journal, 1, 0); + recover_retval = e2fsck_journal_release(ctx, journal, 1, 0); + if(recover_retval == -EIO) { + ctx->fs->flags &= ~EXT2_FLAG_VALID; + com_err(ctx->program_name, 0, + _("e2fsck journal release failed " + "on %s, retval=%d \n"), ctx->device_name, recover_retval); + fatal_error(ctx, 0); + } return retval; }