diff options
author | Theodore Ts'o <tytso@mit.edu> | 2008-06-06 17:50:40 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-06-06 17:50:40 -0400 |
commit | 624080eded68738daee041ad64672a9d2614754f (patch) | |
tree | c1350c70233c1f7536a1927bacabe4084770d3c7 | |
parent | 8ea76900be3b4522396e2021260d2818a27b3a5b (diff) |
jbd2: If a journal checksum error is detected, propagate the error to ext4
If a journal checksum error is detected, the ext4 filesystem will call
ext4_error(), and the mount will either continue, become a read-only
mount, or cause a kernel panic based on the superblock flags
indicating the user's preference of what to do in case of filesystem
corruption being detected.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | fs/ext4/super.c | 23 | ||||
-rw-r--r-- | fs/jbd2/recovery.c | 11 | ||||
-rw-r--r-- | include/linux/jbd2.h | 3 |
3 files changed, 30 insertions, 7 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 09d9359c8055..d01a32e8b50a 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -2189,6 +2189,29 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
2189 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { | 2189 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { |
2190 | if (ext4_load_journal(sb, es, journal_devnum)) | 2190 | if (ext4_load_journal(sb, es, journal_devnum)) |
2191 | goto failed_mount3; | 2191 | goto failed_mount3; |
2192 | if (!(sb->s_flags & MS_RDONLY) && | ||
2193 | EXT4_SB(sb)->s_journal->j_failed_commit) { | ||
2194 | printk(KERN_CRIT "EXT4-fs error (device %s): " | ||
2195 | "ext4_fill_super: Journal transaction " | ||
2196 | "%u is corrupt\n", sb->s_id, | ||
2197 | EXT4_SB(sb)->s_journal->j_failed_commit); | ||
2198 | if (test_opt (sb, ERRORS_RO)) { | ||
2199 | printk (KERN_CRIT | ||
2200 | "Mounting filesystem read-only\n"); | ||
2201 | sb->s_flags |= MS_RDONLY; | ||
2202 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
2203 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | ||
2204 | } | ||
2205 | if (test_opt(sb, ERRORS_PANIC)) { | ||
2206 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
2207 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | ||
2208 | ext4_commit_super(sb, es, 1); | ||
2209 | printk(KERN_CRIT | ||
2210 | "EXT4-fs (device %s): mount failed\n", | ||
2211 | sb->s_id); | ||
2212 | goto failed_mount4; | ||
2213 | } | ||
2214 | } | ||
2192 | } else if (journal_inum) { | 2215 | } else if (journal_inum) { |
2193 | if (ext4_create_journal(sb, es, journal_inum)) | 2216 | if (ext4_create_journal(sb, es, journal_inum)) |
2194 | goto failed_mount3; | 2217 | goto failed_mount3; |
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index 7199db52b2fd..058f50f65b76 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c | |||
@@ -611,9 +611,8 @@ static int do_one_pass(journal_t *journal, | |||
611 | chksum_err = chksum_seen = 0; | 611 | chksum_err = chksum_seen = 0; |
612 | 612 | ||
613 | if (info->end_transaction) { | 613 | if (info->end_transaction) { |
614 | printk(KERN_ERR "JBD: Transaction %u " | 614 | journal->j_failed_commit = |
615 | "found to be corrupt.\n", | 615 | info->end_transaction; |
616 | next_commit_ID - 1); | ||
617 | brelse(bh); | 616 | brelse(bh); |
618 | break; | 617 | break; |
619 | } | 618 | } |
@@ -644,10 +643,8 @@ static int do_one_pass(journal_t *journal, | |||
644 | 643 | ||
645 | if (!JBD2_HAS_INCOMPAT_FEATURE(journal, | 644 | if (!JBD2_HAS_INCOMPAT_FEATURE(journal, |
646 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)){ | 645 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)){ |
647 | printk(KERN_ERR | 646 | journal->j_failed_commit = |
648 | "JBD: Transaction %u " | 647 | next_commit_ID; |
649 | "found to be corrupt.\n", | ||
650 | next_commit_ID); | ||
651 | brelse(bh); | 648 | brelse(bh); |
652 | break; | 649 | break; |
653 | } | 650 | } |
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 05e2b307161a..d147f0f90360 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h | |||
@@ -919,6 +919,9 @@ struct journal_s | |||
919 | struct proc_dir_entry *j_proc_entry; | 919 | struct proc_dir_entry *j_proc_entry; |
920 | struct transaction_stats_s j_stats; | 920 | struct transaction_stats_s j_stats; |
921 | 921 | ||
922 | /* Failed journal commit ID */ | ||
923 | unsigned int j_failed_commit; | ||
924 | |||
922 | /* | 925 | /* |
923 | * An opaque pointer to fs-private information. ext3 puts its | 926 | * An opaque pointer to fs-private information. ext3 puts its |
924 | * superblock pointer here | 927 | * superblock pointer here |