@@ -65,6 +65,7 @@ static struct ratelimit_state ext4_mount_msg_ratelimit;
65
65
static int ext4_load_journal (struct super_block * , struct ext4_super_block * ,
66
66
unsigned long journal_devnum );
67
67
static int ext4_show_options (struct seq_file * seq , struct dentry * root );
68
+ static void ext4_update_super (struct super_block * sb );
68
69
static int ext4_commit_super (struct super_block * sb );
69
70
static int ext4_mark_recovery_complete (struct super_block * sb ,
70
71
struct ext4_super_block * es );
@@ -586,9 +587,9 @@ static int ext4_errno_to_code(int errno)
586
587
return EXT4_ERR_UNKNOWN ;
587
588
}
588
589
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 )
592
593
{
593
594
struct ext4_sb_info * sbi = EXT4_SB (sb );
594
595
@@ -615,15 +616,6 @@ static void __save_error_info(struct super_block *sb, int error,
615
616
spin_unlock (& sbi -> s_error_lock );
616
617
}
617
618
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
-
627
619
/* Deal with the reporting of failure conditions on a filesystem such as
628
620
* inconsistencies detected or read IO failures.
629
621
*
@@ -649,20 +641,35 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error,
649
641
const char * func , unsigned int line )
650
642
{
651
643
journal_t * journal = EXT4_SB (sb )-> s_journal ;
644
+ bool continue_fs = !force_ro && test_opt (sb , ERRORS_CONT );
652
645
653
646
EXT4_SB (sb )-> s_mount_state |= EXT4_ERROR_FS ;
654
647
if (test_opt (sb , WARN_ON_ERROR ))
655
648
WARN_ON_ONCE (1 );
656
649
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 )) {
658
657
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
+ }
659
669
660
- if (sb_rdonly (sb ) || (! force_ro && test_opt ( sb , ERRORS_CONT )) )
670
+ if (sb_rdonly (sb ) || continue_fs )
661
671
return ;
662
672
663
- ext4_set_mount_flag (sb , EXT4_MF_FS_ABORTED );
664
- if (journal )
665
- jbd2_journal_abort (journal , - EIO );
666
673
/*
667
674
* We force ERRORS_RO behavior when system is rebooting. Otherwise we
668
675
* 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)
685
692
{
686
693
struct ext4_sb_info * sbi = container_of (work , struct ext4_sb_info ,
687
694
s_error_work );
695
+ journal_t * journal = sbi -> s_journal ;
696
+ handle_t * handle ;
688
697
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
+ */
689
727
ext4_commit_super (sbi -> s_sb );
690
728
}
691
729
@@ -944,9 +982,11 @@ __acquires(bitlock)
944
982
if (test_opt (sb , WARN_ON_ERROR ))
945
983
WARN_ON_ONCE (1 );
946
984
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 );
949
988
schedule_work (& EXT4_SB (sb )-> s_error_work );
989
+ }
950
990
return ;
951
991
}
952
992
ext4_unlock_group (sb , grp );
@@ -5434,15 +5474,12 @@ static int ext4_load_journal(struct super_block *sb,
5434
5474
return err ;
5435
5475
}
5436
5476
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 )
5438
5479
{
5439
5480
struct ext4_sb_info * sbi = EXT4_SB (sb );
5440
5481
struct ext4_super_block * es = EXT4_SB (sb )-> s_es ;
5441
5482
struct buffer_head * sbh = EXT4_SB (sb )-> s_sbh ;
5442
- int error = 0 ;
5443
-
5444
- if (!sbh || block_device_ejected (sb ))
5445
- return error ;
5446
5483
5447
5484
lock_buffer (sbh );
5448
5485
/*
@@ -5514,8 +5551,20 @@ static int ext4_commit_super(struct super_block *sb)
5514
5551
}
5515
5552
spin_unlock (& sbi -> s_error_lock );
5516
5553
5517
- BUFFER_TRACE (sbh , "marking dirty" );
5518
5554
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
+
5519
5568
if (buffer_write_io_error (sbh ) || !buffer_uptodate (sbh )) {
5520
5569
/*
5521
5570
* Oh, dear. A previous attempt to write the
@@ -5530,8 +5579,8 @@ static int ext4_commit_super(struct super_block *sb)
5530
5579
clear_buffer_write_io_error (sbh );
5531
5580
set_buffer_uptodate (sbh );
5532
5581
}
5582
+ BUFFER_TRACE (sbh , "marking dirty" );
5533
5583
mark_buffer_dirty (sbh );
5534
- unlock_buffer (sbh );
5535
5584
error = __sync_dirty_buffer (sbh ,
5536
5585
REQ_SYNC | (test_opt (sb , BARRIER ) ? REQ_FUA : 0 ));
5537
5586
if (buffer_write_io_error (sbh )) {
0 commit comments