Skip to content

Commit 1dc1097

Browse files
jankaratytso
authored andcommitted
ext4: avoid panic during forced reboot
When admin calls "reboot -f" - i.e., does a hard system reboot by directly calling reboot(2) - ext4 filesystem mounted with errors=panic can panic the system. This happens because the underlying device gets disabled without unmounting the filesystem and thus some syscall running in parallel to reboot(2) can result in the filesystem getting IO errors. This is somewhat surprising to the users so try improve the behavior by switching to errors=remount-ro behavior when the system is running reboot(2). Signed-off-by: Jan Kara <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 372a03e commit 1dc1097

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

fs/ext4/super.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,12 @@ static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn)
430430
spin_unlock(&sbi->s_md_lock);
431431
}
432432

433+
static bool system_going_down(void)
434+
{
435+
return system_state == SYSTEM_HALT || system_state == SYSTEM_POWER_OFF
436+
|| system_state == SYSTEM_RESTART;
437+
}
438+
433439
/* Deal with the reporting of failure conditions on a filesystem such as
434440
* inconsistencies detected or read IO failures.
435441
*
@@ -460,16 +466,20 @@ static void ext4_handle_error(struct super_block *sb)
460466
if (journal)
461467
jbd2_journal_abort(journal, -EIO);
462468
}
463-
if (test_opt(sb, ERRORS_RO)) {
469+
/*
470+
* We force ERRORS_RO behavior when system is rebooting. Otherwise we
471+
* could panic during 'reboot -f' as the underlying device got already
472+
* disabled.
473+
*/
474+
if (test_opt(sb, ERRORS_RO) || system_going_down()) {
464475
ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
465476
/*
466477
* Make sure updated value of ->s_mount_flags will be visible
467478
* before ->s_flags update
468479
*/
469480
smp_wmb();
470481
sb->s_flags |= SB_RDONLY;
471-
}
472-
if (test_opt(sb, ERRORS_PANIC)) {
482+
} else if (test_opt(sb, ERRORS_PANIC)) {
473483
if (EXT4_SB(sb)->s_journal &&
474484
!(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
475485
return;

0 commit comments

Comments
 (0)