aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 8f7e0be8ab1b..e5f06a5f045e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -51,7 +51,7 @@ struct proc_dir_entry *ext4_proc_root;
51 51
52static int ext4_load_journal(struct super_block *, struct ext4_super_block *, 52static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
53 unsigned long journal_devnum); 53 unsigned long journal_devnum);
54static void ext4_commit_super(struct super_block *sb, 54static int ext4_commit_super(struct super_block *sb,
55 struct ext4_super_block *es, int sync); 55 struct ext4_super_block *es, int sync);
56static void ext4_mark_recovery_complete(struct super_block *sb, 56static void ext4_mark_recovery_complete(struct super_block *sb,
57 struct ext4_super_block *es); 57 struct ext4_super_block *es);
@@ -62,9 +62,9 @@ static const char *ext4_decode_error(struct super_block *sb, int errno,
62 char nbuf[16]); 62 char nbuf[16]);
63static int ext4_remount(struct super_block *sb, int *flags, char *data); 63static int ext4_remount(struct super_block *sb, int *flags, char *data);
64static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf); 64static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf);
65static void ext4_unlockfs(struct super_block *sb); 65static int ext4_unfreeze(struct super_block *sb);
66static void ext4_write_super(struct super_block *sb); 66static void ext4_write_super(struct super_block *sb);
67static void ext4_write_super_lockfs(struct super_block *sb); 67static int ext4_freeze(struct super_block *sb);
68 68
69 69
70ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, 70ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
@@ -978,8 +978,8 @@ static const struct super_operations ext4_sops = {
978 .put_super = ext4_put_super, 978 .put_super = ext4_put_super,
979 .write_super = ext4_write_super, 979 .write_super = ext4_write_super,
980 .sync_fs = ext4_sync_fs, 980 .sync_fs = ext4_sync_fs,
981 .write_super_lockfs = ext4_write_super_lockfs, 981 .freeze_fs = ext4_freeze,
982 .unlockfs = ext4_unlockfs, 982 .unfreeze_fs = ext4_unfreeze,
983 .statfs = ext4_statfs, 983 .statfs = ext4_statfs,
984 .remount_fs = ext4_remount, 984 .remount_fs = ext4_remount,
985 .clear_inode = ext4_clear_inode, 985 .clear_inode = ext4_clear_inode,
@@ -2888,13 +2888,14 @@ static int ext4_load_journal(struct super_block *sb,
2888 return 0; 2888 return 0;
2889} 2889}
2890 2890
2891static void ext4_commit_super(struct super_block *sb, 2891static int ext4_commit_super(struct super_block *sb,
2892 struct ext4_super_block *es, int sync) 2892 struct ext4_super_block *es, int sync)
2893{ 2893{
2894 struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; 2894 struct buffer_head *sbh = EXT4_SB(sb)->s_sbh;
2895 int error = 0;
2895 2896
2896 if (!sbh) 2897 if (!sbh)
2897 return; 2898 return error;
2898 if (buffer_write_io_error(sbh)) { 2899 if (buffer_write_io_error(sbh)) {
2899 /* 2900 /*
2900 * Oh, dear. A previous attempt to write the 2901 * Oh, dear. A previous attempt to write the
@@ -2918,14 +2919,19 @@ static void ext4_commit_super(struct super_block *sb,
2918 BUFFER_TRACE(sbh, "marking dirty"); 2919 BUFFER_TRACE(sbh, "marking dirty");
2919 mark_buffer_dirty(sbh); 2920 mark_buffer_dirty(sbh);
2920 if (sync) { 2921 if (sync) {
2921 sync_dirty_buffer(sbh); 2922 error = sync_dirty_buffer(sbh);
2922 if (buffer_write_io_error(sbh)) { 2923 if (error)
2924 return error;
2925
2926 error = buffer_write_io_error(sbh);
2927 if (error) {
2923 printk(KERN_ERR "EXT4-fs: I/O error while writing " 2928 printk(KERN_ERR "EXT4-fs: I/O error while writing "
2924 "superblock for %s.\n", sb->s_id); 2929 "superblock for %s.\n", sb->s_id);
2925 clear_buffer_write_io_error(sbh); 2930 clear_buffer_write_io_error(sbh);
2926 set_buffer_uptodate(sbh); 2931 set_buffer_uptodate(sbh);
2927 } 2932 }
2928 } 2933 }
2934 return error;
2929} 2935}
2930 2936
2931 2937
@@ -3058,12 +3064,14 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
3058 * LVM calls this function before a (read-only) snapshot is created. This 3064 * LVM calls this function before a (read-only) snapshot is created. This
3059 * gives us a chance to flush the journal completely and mark the fs clean. 3065 * gives us a chance to flush the journal completely and mark the fs clean.
3060 */ 3066 */
3061static void ext4_write_super_lockfs(struct super_block *sb) 3067static int ext4_freeze(struct super_block *sb)
3062{ 3068{
3069 int error = 0;
3070 journal_t *journal;
3063 sb->s_dirt = 0; 3071 sb->s_dirt = 0;
3064 3072
3065 if (!(sb->s_flags & MS_RDONLY)) { 3073 if (!(sb->s_flags & MS_RDONLY)) {
3066 journal_t *journal = EXT4_SB(sb)->s_journal; 3074 journal = EXT4_SB(sb)->s_journal;
3067 3075
3068 if (journal) { 3076 if (journal) {
3069 /* Now we set up the journal barrier. */ 3077 /* Now we set up the journal barrier. */
@@ -3073,21 +3081,29 @@ static void ext4_write_super_lockfs(struct super_block *sb)
3073 * We don't want to clear needs_recovery flag when we 3081 * We don't want to clear needs_recovery flag when we
3074 * failed to flush the journal. 3082 * failed to flush the journal.
3075 */ 3083 */
3076 if (jbd2_journal_flush(journal) < 0) 3084 error = jbd2_journal_flush(journal);
3077 return; 3085 if (error < 0)
3086 goto out;
3078 } 3087 }
3079 3088
3080 /* Journal blocked and flushed, clear needs_recovery flag. */ 3089 /* Journal blocked and flushed, clear needs_recovery flag. */
3081 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 3090 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
3082 ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); 3091 ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
3092 error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1);
3093 if (error)
3094 goto out;
3083 } 3095 }
3096 return 0;
3097out:
3098 jbd2_journal_unlock_updates(journal);
3099 return error;
3084} 3100}
3085 3101
3086/* 3102/*
3087 * Called by LVM after the snapshot is done. We need to reset the RECOVER 3103 * Called by LVM after the snapshot is done. We need to reset the RECOVER
3088 * flag here, even though the filesystem is not technically dirty yet. 3104 * flag here, even though the filesystem is not technically dirty yet.
3089 */ 3105 */
3090static void ext4_unlockfs(struct super_block *sb) 3106static int ext4_unfreeze(struct super_block *sb)
3091{ 3107{
3092 if (EXT4_SB(sb)->s_journal && !(sb->s_flags & MS_RDONLY)) { 3108 if (EXT4_SB(sb)->s_journal && !(sb->s_flags & MS_RDONLY)) {
3093 lock_super(sb); 3109 lock_super(sb);
@@ -3097,6 +3113,7 @@ static void ext4_unlockfs(struct super_block *sb)
3097 unlock_super(sb); 3113 unlock_super(sb);
3098 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 3114 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
3099 } 3115 }
3116 return 0;
3100} 3117}
3101 3118
3102static int ext4_remount(struct super_block *sb, int *flags, char *data) 3119static int ext4_remount(struct super_block *sb, int *flags, char *data)