Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git...
[muen/linux.git] / fs / ext4 / super.c
index f5b828bf1299f1998d7b8ac2696b979c8f303079..6ed4eb81e67437dc2dddbbce8ae9f7f2b59681d1 100644 (file)
@@ -430,6 +430,12 @@ static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn)
        spin_unlock(&sbi->s_md_lock);
 }
 
+static bool system_going_down(void)
+{
+       return system_state == SYSTEM_HALT || system_state == SYSTEM_POWER_OFF
+               || system_state == SYSTEM_RESTART;
+}
+
 /* Deal with the reporting of failure conditions on a filesystem such as
  * inconsistencies detected or read IO failures.
  *
@@ -460,7 +466,12 @@ static void ext4_handle_error(struct super_block *sb)
                if (journal)
                        jbd2_journal_abort(journal, -EIO);
        }
-       if (test_opt(sb, ERRORS_RO)) {
+       /*
+        * We force ERRORS_RO behavior when system is rebooting. Otherwise we
+        * could panic during 'reboot -f' as the underlying device got already
+        * disabled.
+        */
+       if (test_opt(sb, ERRORS_RO) || system_going_down()) {
                ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
                /*
                 * Make sure updated value of ->s_mount_flags will be visible
@@ -468,8 +479,7 @@ static void ext4_handle_error(struct super_block *sb)
                 */
                smp_wmb();
                sb->s_flags |= SB_RDONLY;
-       }
-       if (test_opt(sb, ERRORS_PANIC)) {
+       } else if (test_opt(sb, ERRORS_PANIC)) {
                if (EXT4_SB(sb)->s_journal &&
                  !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
                        return;