On 2025/2/6 17:46, Jan Kara wrote: > If a journal is wiped, we will set journal->j_tail to 0. However if > 'write' argument is not set (as it happens for read-only device or for > ocfs2), the on-disk superblock is not updated accordingly and thus > jbd2_journal_recover() cat try to recover the wiped journal. Fix the > check in jbd2_journal_recover() to use journal->j_tail for checking > empty journal instead. > > Signed-off-by: Jan Kara <jack@xxxxxxx> Ha, right, it looks good to me. Reviewed-by: Zhang Yi <yi.zhang@xxxxxxxxxx> > --- > fs/jbd2/recovery.c | 11 ++++++----- > 1 file changed, 6 insertions(+), 5 deletions(-) > > diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c > index 9192be7c19d8..23502f1a67c1 100644 > --- a/fs/jbd2/recovery.c > +++ b/fs/jbd2/recovery.c > @@ -287,19 +287,20 @@ static int fc_do_one_pass(journal_t *journal, > int jbd2_journal_recover(journal_t *journal) > { > int err, err2; > - journal_superblock_t * sb; > - > struct recovery_info info; > > memset(&info, 0, sizeof(info)); > - sb = journal->j_superblock; > > /* > * The journal superblock's s_start field (the current log head) > * is always zero if, and only if, the journal was cleanly > - * unmounted. > + * unmounted. We use its in-memory version j_tail here because > + * jbd2_journal_wipe() could have updated it without updating journal > + * superblock. > */ > - if (!sb->s_start) { > + if (!journal->j_tail) { > + journal_superblock_t *sb = journal->j_superblock; > + > jbd2_debug(1, "No recovery required, last transaction %d, head block %u\n", > be32_to_cpu(sb->s_sequence), be32_to_cpu(sb->s_head)); > journal->j_transaction_sequence = be32_to_cpu(sb->s_sequence) + 1;