From: "zhangyi (F)" yi.zhang@huawei.com
hulk inclusion category: bugfix bugzilla: 34619 CVE: NA ---------------------------
This reverts commit a8fcabe57a1803790fd48f1e00ec3af4db27ab2a. The upstream fix this problem throuth <7b97d868b7ab> "ext4, jbd2: ensure panic by fix a race between jbd2 abort and ext4 error handlers", so revert this patch and backport <7b97d868b7ab>.
Signed-off-by: zhangyi (F) yi.zhang@huawei.com Reviewed-by: Zhang Xiaoxu zhangxiaoxu5@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/super.c | 25 ++++++++++++------------- fs/jbd2/journal.c | 6 ++++-- include/linux/jbd2.h | 6 +----- 3 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b10f96860dd8..553932670b80 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -498,8 +498,6 @@ static void ext4_netlink_send_info(struct super_block *sb, int ext4_errno)
static void ext4_handle_error(struct super_block *sb) { - struct ext4_sb_info *sbi = EXT4_SB(sb); - if (test_opt(sb, WARN_ON_ERROR)) WARN_ON_ONCE(1);
@@ -507,9 +505,9 @@ static void ext4_handle_error(struct super_block *sb) return;
if (!test_opt(sb, ERRORS_CONT)) { - journal_t *journal = sbi->s_journal; + journal_t *journal = EXT4_SB(sb)->s_journal;
- sbi->s_mount_flags |= EXT4_MF_FS_ABORTED; + EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED; if (journal) jbd2_journal_abort(journal, -EIO); } @@ -530,8 +528,9 @@ static void ext4_handle_error(struct super_block *sb) smp_wmb(); sb->s_flags |= SB_RDONLY; } else if (test_opt(sb, ERRORS_PANIC)) { - if (sbi->s_journal && is_journal_aborted(sbi->s_journal)) - wait_for_completion(&sbi->s_journal->j_record_errno); + if (EXT4_SB(sb)->s_journal && + !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR)) + return; panic("EXT4-fs (device %s): panic forced after error\n", sb->s_id); } @@ -720,11 +719,10 @@ void __ext4_std_error(struct super_block *sb, const char *function, void __ext4_abort(struct super_block *sb, const char *function, unsigned int line, const char *fmt, ...) { - struct ext4_sb_info *sbi = EXT4_SB(sb); struct va_format vaf; va_list args;
- if (unlikely(ext4_forced_shutdown(sbi))) + if (unlikely(ext4_forced_shutdown(EXT4_SB(sb)))) return;
save_error_info(sb, function, line); @@ -737,21 +735,22 @@ void __ext4_abort(struct super_block *sb, const char *function,
if (sb_rdonly(sb) == 0) { ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); - sbi->s_mount_flags |= EXT4_MF_FS_ABORTED; + EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED; /* * Make sure updated value of ->s_mount_flags will be visible * before ->s_flags update */ smp_wmb(); sb->s_flags |= SB_RDONLY; - if (sbi->s_journal) - jbd2_journal_abort(sbi->s_journal, -EIO); + if (EXT4_SB(sb)->s_journal) + jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); save_error_info(sb, function, line); ext4_netlink_send_info(sb, 2); } if (test_opt(sb, ERRORS_PANIC) && !system_going_down()) { - if (sbi->s_journal && is_journal_aborted(sbi->s_journal)) - wait_for_completion(&sbi->s_journal->j_record_errno); + if (EXT4_SB(sb)->s_journal && + !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR)) + return; panic("EXT4-fs panic from previous error\n"); } } diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 753cbe3c50a8..7301bb766172 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1142,7 +1142,6 @@ static journal_t *journal_init_common(struct block_device *bdev, init_waitqueue_head(&journal->j_wait_commit); init_waitqueue_head(&journal->j_wait_updates); init_waitqueue_head(&journal->j_wait_reserved); - init_completion(&journal->j_record_errno); mutex_init(&journal->j_barrier); mutex_init(&journal->j_checkpoint_mutex); spin_lock_init(&journal->j_revoke_lock); @@ -2188,7 +2187,10 @@ void jbd2_journal_abort(journal_t *journal, int errno) * layer could realise that a filesystem check is needed. */ jbd2_journal_update_sb_errno(journal); - complete_all(&journal->j_record_errno); + + write_lock(&journal->j_state_lock); + journal->j_flags |= JBD2_REC_ERR; + write_unlock(&journal->j_state_lock); }
/** diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index e87a6fd79d71..12b935c9ec1e 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -788,11 +788,6 @@ struct journal_s */ int j_errno;
- /** - * @j_record_errno: complete to record errno in the journal superblock - */ - struct completion j_record_errno; - /** * @j_sb_buffer: The first part of the superblock buffer. */ @@ -1275,6 +1270,7 @@ JBD2_FEATURE_INCOMPAT_FUNCS(csum3, CSUM_V3) #define JBD2_ABORT_ON_SYNCDATA_ERR 0x040 /* Abort the journal on file * data write error in ordered * mode */ +#define JBD2_REC_ERR 0x080 /* The errno in the sb has been recorded */
/* * Function declarations for the journaling transaction and buffer