1 ext4: pass -ESHUTDOWN code to jbd2 layer
3 Previously the jbd2 layer assumed that a file system check would be
4 required after a journal abort. In the case of the deliberate file
5 system shutdown, this should not be necessary. Allow the jbd2 layer
6 to distinguish between these two cases by using the ESHUTDOWN errno.
8 Also add proper locking to __journal_abort_soft().
10 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
11 Cc: stable@vger.kernel.org
13 fs/ext4/ioctl.c | 4 ++--
14 fs/jbd2/journal.c | 25 +++++++++++++++++++------
15 2 files changed, 21 insertions(+), 8 deletions(-)
17 diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
18 index 16d3d1325f5b..9ac33a7cbd32 100644
21 @@ -493,13 +493,13 @@ static int ext4_shutdown(struct super_block *sb, unsigned long arg)
22 set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
23 if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) {
24 (void) ext4_force_commit(sb);
25 - jbd2_journal_abort(sbi->s_journal, 0);
26 + jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN);
29 case EXT4_GOING_FLAGS_NOLOGFLUSH:
30 set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
31 if (sbi->s_journal && !is_journal_aborted(sbi->s_journal))
32 - jbd2_journal_abort(sbi->s_journal, 0);
33 + jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN);
37 diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
38 index 3fbf48ec2188..efa0c72a0b9f 100644
39 --- a/fs/jbd2/journal.c
40 +++ b/fs/jbd2/journal.c
41 @@ -1483,12 +1483,15 @@ static void jbd2_mark_journal_empty(journal_t *journal, int write_op)
42 void jbd2_journal_update_sb_errno(journal_t *journal)
44 journal_superblock_t *sb = journal->j_superblock;
47 read_lock(&journal->j_state_lock);
48 - jbd_debug(1, "JBD2: updating superblock error (errno %d)\n",
50 - sb->s_errno = cpu_to_be32(journal->j_errno);
51 + errcode = journal->j_errno;
52 read_unlock(&journal->j_state_lock);
53 + if (errcode == -ESHUTDOWN)
55 + jbd_debug(1, "JBD2: updating superblock error (errno %d)\n", errcode);
56 + sb->s_errno = cpu_to_be32(errcode);
58 jbd2_write_superblock(journal, REQ_SYNC | REQ_FUA);
60 @@ -2105,12 +2108,22 @@ void __jbd2_journal_abort_hard(journal_t *journal)
61 * but don't do any other IO. */
62 static void __journal_abort_soft (journal_t *journal, int errno)
64 - if (journal->j_flags & JBD2_ABORT)
68 - if (!journal->j_errno)
69 + write_lock(&journal->j_state_lock);
70 + old_errno = journal->j_errno;
71 + if (!journal->j_errno || errno == -ESHUTDOWN)
72 journal->j_errno = errno;
74 + if (journal->j_flags & JBD2_ABORT) {
75 + write_unlock(&journal->j_state_lock);
76 + if (!old_errno && old_errno != -ESHUTDOWN &&
77 + errno == -ESHUTDOWN)
78 + jbd2_journal_update_sb_errno(journal);
81 + write_unlock(&journal->j_state_lock);
83 __jbd2_journal_abort_hard(journal);