diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 0e661c569660..fb940c22ab0d 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); |
@@ -777,6 +778,9 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
777 | seq_printf(seq, ",inode_readahead_blks=%u", | 778 | seq_printf(seq, ",inode_readahead_blks=%u", |
778 | sbi->s_inode_readahead_blks); | 779 | sbi->s_inode_readahead_blks); |
779 | 780 | ||
781 | if (test_opt(sb, DATA_ERR_ABORT)) | ||
782 | seq_puts(seq, ",data_err=abort"); | ||
783 | |||
780 | ext4_show_quota_options(seq, sb); | 784 | ext4_show_quota_options(seq, sb); |
781 | return 0; | 785 | return 0; |
782 | } | 786 | } |
@@ -906,6 +910,7 @@ enum { | |||
906 | Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, | 910 | Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev, |
907 | Opt_journal_checksum, Opt_journal_async_commit, | 911 | Opt_journal_checksum, Opt_journal_async_commit, |
908 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, | 912 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, |
913 | Opt_data_err_abort, Opt_data_err_ignore, | ||
909 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, | 914 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
910 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 915 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
911 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, | 916 | Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, |
@@ -952,6 +957,8 @@ static match_table_t tokens = { | |||
952 | {Opt_data_journal, "data=journal"}, | 957 | {Opt_data_journal, "data=journal"}, |
953 | {Opt_data_ordered, "data=ordered"}, | 958 | {Opt_data_ordered, "data=ordered"}, |
954 | {Opt_data_writeback, "data=writeback"}, | 959 | {Opt_data_writeback, "data=writeback"}, |
960 | {Opt_data_err_abort, "data_err=abort"}, | ||
961 | {Opt_data_err_ignore, "data_err=ignore"}, | ||
955 | {Opt_offusrjquota, "usrjquota="}, | 962 | {Opt_offusrjquota, "usrjquota="}, |
956 | {Opt_usrjquota, "usrjquota=%s"}, | 963 | {Opt_usrjquota, "usrjquota=%s"}, |
957 | {Opt_offgrpjquota, "grpjquota="}, | 964 | {Opt_offgrpjquota, "grpjquota="}, |
@@ -1186,6 +1193,12 @@ static int parse_options(char *options, struct super_block *sb, | |||
1186 | sbi->s_mount_opt |= data_opt; | 1193 | sbi->s_mount_opt |= data_opt; |
1187 | } | 1194 | } |
1188 | break; | 1195 | break; |
1196 | case Opt_data_err_abort: | ||
1197 | set_opt(sbi->s_mount_opt, DATA_ERR_ABORT); | ||
1198 | break; | ||
1199 | case Opt_data_err_ignore: | ||
1200 | clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT); | ||
1201 | break; | ||
1189 | #ifdef CONFIG_QUOTA | 1202 | #ifdef CONFIG_QUOTA |
1190 | case Opt_usrjquota: | 1203 | case Opt_usrjquota: |
1191 | qtype = USRQUOTA; | 1204 | qtype = USRQUOTA; |
@@ -2218,6 +2231,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2218 | goto failed_mount; | 2231 | goto failed_mount; |
2219 | } | 2232 | } |
2220 | 2233 | ||
2234 | #ifdef CONFIG_PROC_FS | ||
2221 | if (ext4_proc_root) | 2235 | if (ext4_proc_root) |
2222 | sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root); | 2236 | sbi->s_proc = proc_mkdir(sb->s_id, ext4_proc_root); |
2223 | 2237 | ||
@@ -2225,6 +2239,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2225 | proc_create_data("inode_readahead_blks", 0644, sbi->s_proc, | 2239 | proc_create_data("inode_readahead_blks", 0644, sbi->s_proc, |
2226 | &ext4_ui_proc_fops, | 2240 | &ext4_ui_proc_fops, |
2227 | &sbi->s_inode_readahead_blks); | 2241 | &sbi->s_inode_readahead_blks); |
2242 | #endif | ||
2228 | 2243 | ||
2229 | bgl_lock_init(&sbi->s_blockgroup_lock); | 2244 | bgl_lock_init(&sbi->s_blockgroup_lock); |
2230 | 2245 | ||
@@ -2534,6 +2549,10 @@ static void ext4_init_journal_params(struct super_block *sb, journal_t *journal) | |||
2534 | journal->j_flags |= JBD2_BARRIER; | 2549 | journal->j_flags |= JBD2_BARRIER; |
2535 | else | 2550 | else |
2536 | journal->j_flags &= ~JBD2_BARRIER; | 2551 | journal->j_flags &= ~JBD2_BARRIER; |
2552 | if (test_opt(sb, DATA_ERR_ABORT)) | ||
2553 | journal->j_flags |= JBD2_ABORT_ON_SYNCDATA_ERR; | ||
2554 | else | ||
2555 | journal->j_flags &= ~JBD2_ABORT_ON_SYNCDATA_ERR; | ||
2537 | spin_unlock(&journal->j_state_lock); | 2556 | spin_unlock(&journal->j_state_lock); |
2538 | } | 2557 | } |
2539 | 2558 | ||
@@ -2853,7 +2872,9 @@ static void ext4_mark_recovery_complete(struct super_block *sb, | |||
2853 | journal_t *journal = EXT4_SB(sb)->s_journal; | 2872 | journal_t *journal = EXT4_SB(sb)->s_journal; |
2854 | 2873 | ||
2855 | jbd2_journal_lock_updates(journal); | 2874 | jbd2_journal_lock_updates(journal); |
2856 | jbd2_journal_flush(journal); | 2875 | if (jbd2_journal_flush(journal) < 0) |
2876 | goto out; | ||
2877 | |||
2857 | lock_super(sb); | 2878 | lock_super(sb); |
2858 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && | 2879 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && |
2859 | sb->s_flags & MS_RDONLY) { | 2880 | sb->s_flags & MS_RDONLY) { |
@@ -2862,6 +2883,8 @@ static void ext4_mark_recovery_complete(struct super_block *sb, | |||
2862 | ext4_commit_super(sb, es, 1); | 2883 | ext4_commit_super(sb, es, 1); |
2863 | } | 2884 | } |
2864 | unlock_super(sb); | 2885 | unlock_super(sb); |
2886 | |||
2887 | out: | ||
2865 | jbd2_journal_unlock_updates(journal); | 2888 | jbd2_journal_unlock_updates(journal); |
2866 | } | 2889 | } |
2867 | 2890 | ||
@@ -2962,7 +2985,13 @@ static void ext4_write_super_lockfs(struct super_block *sb) | |||
2962 | 2985 | ||
2963 | /* Now we set up the journal barrier. */ | 2986 | /* Now we set up the journal barrier. */ |
2964 | jbd2_journal_lock_updates(journal); | 2987 | jbd2_journal_lock_updates(journal); |
2965 | jbd2_journal_flush(journal); | 2988 | |
2989 | /* | ||
2990 | * We don't want to clear needs_recovery flag when we failed | ||
2991 | * to flush the journal. | ||
2992 | */ | ||
2993 | if (jbd2_journal_flush(journal) < 0) | ||
2994 | return; | ||
2966 | 2995 | ||
2967 | /* Journal blocked and flushed, clear needs_recovery flag. */ | 2996 | /* Journal blocked and flushed, clear needs_recovery flag. */ |
2968 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 2997 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
@@ -3402,8 +3431,12 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
3402 | * otherwise be livelocked... | 3431 | * otherwise be livelocked... |
3403 | */ | 3432 | */ |
3404 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 3433 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
3405 | jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 3434 | err = jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
3406 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 3435 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); |
3436 | if (err) { | ||
3437 | path_put(&nd.path); | ||
3438 | return err; | ||
3439 | } | ||
3407 | } | 3440 | } |
3408 | 3441 | ||
3409 | err = vfs_quota_on_path(sb, type, format_id, &nd.path); | 3442 | err = vfs_quota_on_path(sb, type, format_id, &nd.path); |