@@ -65,6 +65,7 @@ static struct ratelimit_state ext4_mount_msg_ratelimit;
6565static int ext4_load_journal (struct super_block * , struct ext4_super_block * ,
6666 unsigned long journal_devnum );
6767static int ext4_show_options (struct seq_file * seq , struct dentry * root );
68+ static void ext4_update_super (struct super_block * sb );
6869static int ext4_commit_super (struct super_block * sb );
6970static int ext4_mark_recovery_complete (struct super_block * sb ,
7071 struct ext4_super_block * es );
@@ -586,9 +587,9 @@ static int ext4_errno_to_code(int errno)
586587 return EXT4_ERR_UNKNOWN ;
587588}
588589
589- static void __save_error_info (struct super_block * sb , int error ,
590- __u32 ino , __u64 block ,
591- const char * func , unsigned int line )
590+ static void save_error_info (struct super_block * sb , int error ,
591+ __u32 ino , __u64 block ,
592+ const char * func , unsigned int line )
592593{
593594 struct ext4_sb_info * sbi = EXT4_SB (sb );
594595
@@ -615,15 +616,6 @@ static void __save_error_info(struct super_block *sb, int error,
615616 spin_unlock (& sbi -> s_error_lock );
616617}
617618
618- static void save_error_info (struct super_block * sb , int error ,
619- __u32 ino , __u64 block ,
620- const char * func , unsigned int line )
621- {
622- __save_error_info (sb , error , ino , block , func , line );
623- if (!bdev_read_only (sb -> s_bdev ))
624- ext4_commit_super (sb );
625- }
626-
627619/* Deal with the reporting of failure conditions on a filesystem such as
628620 * inconsistencies detected or read IO failures.
629621 *
@@ -649,20 +641,35 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error,
649641 const char * func , unsigned int line )
650642{
651643 journal_t * journal = EXT4_SB (sb )-> s_journal ;
644+ bool continue_fs = !force_ro && test_opt (sb , ERRORS_CONT );
652645
653646 EXT4_SB (sb )-> s_mount_state |= EXT4_ERROR_FS ;
654647 if (test_opt (sb , WARN_ON_ERROR ))
655648 WARN_ON_ONCE (1 );
656649
657- if (!bdev_read_only (sb -> s_bdev ))
650+ if (!continue_fs && !sb_rdonly (sb )) {
651+ ext4_set_mount_flag (sb , EXT4_MF_FS_ABORTED );
652+ if (journal )
653+ jbd2_journal_abort (journal , - EIO );
654+ }
655+
656+ if (!bdev_read_only (sb -> s_bdev )) {
658657 save_error_info (sb , error , ino , block , func , line );
658+ /*
659+ * In case the fs should keep running, we need to writeout
660+ * superblock through the journal. Due to lock ordering
661+ * constraints, it may not be safe to do it right here so we
662+ * defer superblock flushing to a workqueue.
663+ */
664+ if (continue_fs )
665+ schedule_work (& EXT4_SB (sb )-> s_error_work );
666+ else
667+ ext4_commit_super (sb );
668+ }
659669
660- if (sb_rdonly (sb ) || (! force_ro && test_opt ( sb , ERRORS_CONT )) )
670+ if (sb_rdonly (sb ) || continue_fs )
661671 return ;
662672
663- ext4_set_mount_flag (sb , EXT4_MF_FS_ABORTED );
664- if (journal )
665- jbd2_journal_abort (journal , - EIO );
666673 /*
667674 * We force ERRORS_RO behavior when system is rebooting. Otherwise we
668675 * could panic during 'reboot -f' as the underlying device got already
@@ -685,7 +692,38 @@ static void flush_stashed_error_work(struct work_struct *work)
685692{
686693 struct ext4_sb_info * sbi = container_of (work , struct ext4_sb_info ,
687694 s_error_work );
695+ journal_t * journal = sbi -> s_journal ;
696+ handle_t * handle ;
688697
698+ /*
699+ * If the journal is still running, we have to write out superblock
700+ * through the journal to avoid collisions of other journalled sb
701+ * updates.
702+ *
703+ * We use directly jbd2 functions here to avoid recursing back into
704+ * ext4 error handling code during handling of previous errors.
705+ */
706+ if (!sb_rdonly (sbi -> s_sb ) && journal ) {
707+ handle = jbd2_journal_start (journal , 1 );
708+ if (IS_ERR (handle ))
709+ goto write_directly ;
710+ if (jbd2_journal_get_write_access (handle , sbi -> s_sbh )) {
711+ jbd2_journal_stop (handle );
712+ goto write_directly ;
713+ }
714+ ext4_update_super (sbi -> s_sb );
715+ if (jbd2_journal_dirty_metadata (handle , sbi -> s_sbh )) {
716+ jbd2_journal_stop (handle );
717+ goto write_directly ;
718+ }
719+ jbd2_journal_stop (handle );
720+ return ;
721+ }
722+ write_directly :
723+ /*
724+ * Write through journal failed. Write sb directly to get error info
725+ * out and hope for the best.
726+ */
689727 ext4_commit_super (sbi -> s_sb );
690728}
691729
@@ -944,9 +982,11 @@ __acquires(bitlock)
944982 if (test_opt (sb , WARN_ON_ERROR ))
945983 WARN_ON_ONCE (1 );
946984 EXT4_SB (sb )-> s_mount_state |= EXT4_ERROR_FS ;
947- __save_error_info (sb , EFSCORRUPTED , ino , block , function , line );
948- if (!bdev_read_only (sb -> s_bdev ))
985+ if (!bdev_read_only (sb -> s_bdev )) {
986+ save_error_info (sb , EFSCORRUPTED , ino , block , function ,
987+ line );
949988 schedule_work (& EXT4_SB (sb )-> s_error_work );
989+ }
950990 return ;
951991 }
952992 ext4_unlock_group (sb , grp );
@@ -5434,15 +5474,12 @@ static int ext4_load_journal(struct super_block *sb,
54345474 return err ;
54355475}
54365476
5437- static int ext4_commit_super (struct super_block * sb )
5477+ /* Copy state of EXT4_SB(sb) into buffer for on-disk superblock */
5478+ static void ext4_update_super (struct super_block * sb )
54385479{
54395480 struct ext4_sb_info * sbi = EXT4_SB (sb );
54405481 struct ext4_super_block * es = EXT4_SB (sb )-> s_es ;
54415482 struct buffer_head * sbh = EXT4_SB (sb )-> s_sbh ;
5442- int error = 0 ;
5443-
5444- if (!sbh || block_device_ejected (sb ))
5445- return error ;
54465483
54475484 lock_buffer (sbh );
54485485 /*
@@ -5514,8 +5551,20 @@ static int ext4_commit_super(struct super_block *sb)
55145551 }
55155552 spin_unlock (& sbi -> s_error_lock );
55165553
5517- BUFFER_TRACE (sbh , "marking dirty" );
55185554 ext4_superblock_csum_set (sb );
5555+ unlock_buffer (sbh );
5556+ }
5557+
5558+ static int ext4_commit_super (struct super_block * sb )
5559+ {
5560+ struct buffer_head * sbh = EXT4_SB (sb )-> s_sbh ;
5561+ int error = 0 ;
5562+
5563+ if (!sbh || block_device_ejected (sb ))
5564+ return error ;
5565+
5566+ ext4_update_super (sb );
5567+
55195568 if (buffer_write_io_error (sbh ) || !buffer_uptodate (sbh )) {
55205569 /*
55215570 * Oh, dear. A previous attempt to write the
@@ -5530,8 +5579,8 @@ static int ext4_commit_super(struct super_block *sb)
55305579 clear_buffer_write_io_error (sbh );
55315580 set_buffer_uptodate (sbh );
55325581 }
5582+ BUFFER_TRACE (sbh , "marking dirty" );
55335583 mark_buffer_dirty (sbh );
5534- unlock_buffer (sbh );
55355584 error = __sync_dirty_buffer (sbh ,
55365585 REQ_SYNC | (test_opt (sb , BARRIER ) ? REQ_FUA : 0 ));
55375586 if (buffer_write_io_error (sbh )) {
0 commit comments