aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorHidehiro Kawai <hidehiro.kawai.ez@hitachi.com>2008-10-10 20:29:21 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-10-10 20:29:21 -0400
commit7ffe1ea8949c75ecffb7a4d988bb881a9fa62fbe (patch)
tree42dc4e7dd16a33ba4c9b74cda41934e1fe27beb5 /fs/ext4/super.c
parent44519faf22ad6ce924ad0352d3dc200d9e0b66e8 (diff)
ext4: add checks for errors from jbd2
If the journal has aborted due to a checkpointing failure, we have to keep the contents of the journal space. Otherwise, the filesystem will lose uncheckpointed metadata completely and become inconsistent. To avoid this, we need to keep needs_recovery flag if checkpoint has failed. With this patch, ext4_put_super() detects a checkpointing failure from the return value of journal_destroy(), then it invokes ext4_abort() to make the filesystem read only and keep needs_recovery flag. Errors from jbd2_journal_flush() are also handled by this patch in some places. Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 0e661c569660..79bd3989e84f 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -507,7 +507,8 @@ static void ext4_put_super(struct super_block *sb)
507 ext4_mb_release(sb); 507 ext4_mb_release(sb);
508 ext4_ext_release(sb); 508 ext4_ext_release(sb);
509 ext4_xattr_put_super(sb); 509 ext4_xattr_put_super(sb);
510 jbd2_journal_destroy(sbi->s_journal); 510 if (jbd2_journal_destroy(sbi->s_journal) < 0)
511 ext4_abort(sb, __func__, "Couldn't clean up the journal");
511 sbi->s_journal = NULL; 512 sbi->s_journal = NULL;
512 if (!(sb->s_flags & MS_RDONLY)) { 513 if (!(sb->s_flags & MS_RDONLY)) {
513 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 514 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
@@ -2853,7 +2854,9 @@ static void ext4_mark_recovery_complete(struct super_block *sb,
2853 journal_t *journal = EXT4_SB(sb)->s_journal; 2854 journal_t *journal = EXT4_SB(sb)->s_journal;
2854 2855
2855 jbd2_journal_lock_updates(journal); 2856 jbd2_journal_lock_updates(journal);
2856 jbd2_journal_flush(journal); 2857 if (jbd2_journal_flush(journal) < 0)
2858 goto out;
2859
2857 lock_super(sb); 2860 lock_super(sb);
2858 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && 2861 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) &&
2859 sb->s_flags & MS_RDONLY) { 2862 sb->s_flags & MS_RDONLY) {
@@ -2862,6 +2865,8 @@ static void ext4_mark_recovery_complete(struct super_block *sb,
2862 ext4_commit_super(sb, es, 1); 2865 ext4_commit_super(sb, es, 1);
2863 } 2866 }
2864 unlock_super(sb); 2867 unlock_super(sb);
2868
2869out:
2865 jbd2_journal_unlock_updates(journal); 2870 jbd2_journal_unlock_updates(journal);
2866} 2871}
2867 2872
@@ -2962,7 +2967,13 @@ static void ext4_write_super_lockfs(struct super_block *sb)
2962 2967
2963 /* Now we set up the journal barrier. */ 2968 /* Now we set up the journal barrier. */
2964 jbd2_journal_lock_updates(journal); 2969 jbd2_journal_lock_updates(journal);
2965 jbd2_journal_flush(journal); 2970
2971 /*
2972 * We don't want to clear needs_recovery flag when we failed
2973 * to flush the journal.
2974 */
2975 if (jbd2_journal_flush(journal) < 0)
2976 return;
2966 2977
2967 /* Journal blocked and flushed, clear needs_recovery flag. */ 2978 /* Journal blocked and flushed, clear needs_recovery flag. */
2968 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 2979 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
@@ -3402,8 +3413,12 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
3402 * otherwise be livelocked... 3413 * otherwise be livelocked...
3403 */ 3414 */
3404 jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); 3415 jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
3405 jbd2_journal_flush(EXT4_SB(sb)->s_journal); 3416 err = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
3406 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 3417 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
3418 if (err) {
3419 path_put(&nd.path);
3420 return err;
3421 }
3407 } 3422 }
3408 3423
3409 err = vfs_quota_on_path(sb, type, format_id, &nd.path); 3424 err = vfs_quota_on_path(sb, type, format_id, &nd.path);