summaryrefslogtreecommitdiff
path: root/fs/jbd2
diff options
context:
space:
mode:
authorKai Li <li.kai4@h3c.com>2020-01-11 05:25:42 +0300
committerTheodore Ts'o <tytso@mit.edu>2020-01-18 00:25:47 +0300
commita09decff5c32060639a685581c380f51b14e1fc2 (patch)
tree033847dab80bd04b8bc6605e5da4e7365894307a /fs/jbd2
parent71b565ceff377a52e7d58cd871745cd339447323 (diff)
downloadlinux-a09decff5c32060639a685581c380f51b14e1fc2.tar.xz
jbd2: clear JBD2_ABORT flag before journal_reset to update log tail info when load journal
If the journal is dirty when the filesystem is mounted, jbd2 will replay the journal but the journal superblock will not be updated by journal_reset() because JBD2_ABORT flag is still set (it was set in journal_init_common()). This is problematic because when a new transaction is then committed, it will be recorded in block 1 (journal->j_tail was set to 1 in journal_reset()). If unclean shutdown happens again before the journal superblock is updated, the new recorded transaction will not be replayed during the next mount (because of stale sb->s_start and sb->s_sequence values) which can lead to filesystem corruption. Fixes: 85e0c4e89c1b ("jbd2: if the journal is aborted then don't allow update of the log tail") Signed-off-by: Kai Li <li.kai4@h3c.com> Link: https://lore.kernel.org/r/20200111022542.5008-1-li.kai4@h3c.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/jbd2')
-rw-r--r--fs/jbd2/journal.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 5e408ee24a1a..069b22eba795 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1710,6 +1710,11 @@ int jbd2_journal_load(journal_t *journal)
journal->j_devname);
return -EFSCORRUPTED;
}
+ /*
+ * clear JBD2_ABORT flag initialized in journal_init_common
+ * here to update log tail information with the newest seq.
+ */
+ journal->j_flags &= ~JBD2_ABORT;
/* OK, we've finished with the dynamic journal bits:
* reinitialise the dynamic contents of the superblock in memory
@@ -1717,7 +1722,6 @@ int jbd2_journal_load(journal_t *journal)
if (journal_reset(journal))
goto recovery_error;
- journal->j_flags &= ~JBD2_ABORT;
journal->j_flags |= JBD2_LOADED;
return 0;