aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2018-02-18 23:45:18 -0500
committerTheodore Ts'o <tytso@mit.edu>2018-02-18 23:45:18 -0500
commitfb7c02445c497943e7296cd3deee04422b63acb8 (patch)
treea324e598b3ad8c07e0f9d94b48389094cd2f298a
parenta6d9946bb925293fda9f5ed6d33d8580b001f006 (diff)
ext4: pass -ESHUTDOWN code to jbd2 layer
Previously the jbd2 layer assumed that a file system check would be required after a journal abort. In the case of the deliberate file system shutdown, this should not be necessary. Allow the jbd2 layer to distinguish between these two cases by using the ESHUTDOWN errno. Also add proper locking to __journal_abort_soft(). Signed-off-by: Theodore Ts'o <tytso@mit.edu> Cc: stable@vger.kernel.org
-rw-r--r--fs/ext4/ioctl.c4
-rw-r--r--fs/jbd2/journal.c25
2 files changed, 21 insertions, 8 deletions
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 16d3d1325f5b..9ac33a7cbd32 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -493,13 +493,13 @@ static int ext4_shutdown(struct super_block *sb, unsigned long arg)
493 set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); 493 set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
494 if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) { 494 if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) {
495 (void) ext4_force_commit(sb); 495 (void) ext4_force_commit(sb);
496 jbd2_journal_abort(sbi->s_journal, 0); 496 jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN);
497 } 497 }
498 break; 498 break;
499 case EXT4_GOING_FLAGS_NOLOGFLUSH: 499 case EXT4_GOING_FLAGS_NOLOGFLUSH:
500 set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); 500 set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
501 if (sbi->s_journal && !is_journal_aborted(sbi->s_journal)) 501 if (sbi->s_journal && !is_journal_aborted(sbi->s_journal))
502 jbd2_journal_abort(sbi->s_journal, 0); 502 jbd2_journal_abort(sbi->s_journal, -ESHUTDOWN);
503 break; 503 break;
504 default: 504 default:
505 return -EINVAL; 505 return -EINVAL;
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 3fbf48ec2188..efa0c72a0b9f 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1483,12 +1483,15 @@ static void jbd2_mark_journal_empty(journal_t *journal, int write_op)
1483void jbd2_journal_update_sb_errno(journal_t *journal) 1483void jbd2_journal_update_sb_errno(journal_t *journal)
1484{ 1484{
1485 journal_superblock_t *sb = journal->j_superblock; 1485 journal_superblock_t *sb = journal->j_superblock;
1486 int errcode;
1486 1487
1487 read_lock(&journal->j_state_lock); 1488 read_lock(&journal->j_state_lock);
1488 jbd_debug(1, "JBD2: updating superblock error (errno %d)\n", 1489 errcode = journal->j_errno;
1489 journal->j_errno);
1490 sb->s_errno = cpu_to_be32(journal->j_errno);
1491 read_unlock(&journal->j_state_lock); 1490 read_unlock(&journal->j_state_lock);
1491 if (errcode == -ESHUTDOWN)
1492 errcode = 0;
1493 jbd_debug(1, "JBD2: updating superblock error (errno %d)\n", errcode);
1494 sb->s_errno = cpu_to_be32(errcode);
1492 1495
1493 jbd2_write_superblock(journal, REQ_SYNC | REQ_FUA); 1496 jbd2_write_superblock(journal, REQ_SYNC | REQ_FUA);
1494} 1497}
@@ -2105,12 +2108,22 @@ void __jbd2_journal_abort_hard(journal_t *journal)
2105 * but don't do any other IO. */ 2108 * but don't do any other IO. */
2106static void __journal_abort_soft (journal_t *journal, int errno) 2109static void __journal_abort_soft (journal_t *journal, int errno)
2107{ 2110{
2108 if (journal->j_flags & JBD2_ABORT) 2111 int old_errno;
2109 return;
2110 2112
2111 if (!journal->j_errno) 2113 write_lock(&journal->j_state_lock);
2114 old_errno = journal->j_errno;
2115 if (!journal->j_errno || errno == -ESHUTDOWN)
2112 journal->j_errno = errno; 2116 journal->j_errno = errno;
2113 2117
2118 if (journal->j_flags & JBD2_ABORT) {
2119 write_unlock(&journal->j_state_lock);
2120 if (!old_errno && old_errno != -ESHUTDOWN &&
2121 errno == -ESHUTDOWN)
2122 jbd2_journal_update_sb_errno(journal);
2123 return;
2124 }
2125 write_unlock(&journal->j_state_lock);
2126
2114 __jbd2_journal_abort_hard(journal); 2127 __jbd2_journal_abort_hard(journal);
2115 2128
2116 if (errno) { 2129 if (errno) {