1 ext4: journal superblock changes
3 There are a number of changes to the ext4 superblock during the mount
4 process which are done without using the journal, but instead via the
5 brute-force call to ext4_commit_super(). Concentrate these changes to
6 ext4_setup_super(), and make them using the journalling mechanism.
8 Not only is this more efficient, but it also avoids some cases where
9 the ext4 superblock's checksum was not properly set.
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
13 fs/ext4/super.c | 50 ++++++++++++++++++++++++++++----------------------
14 1 file changed, 28 insertions(+), 22 deletions(-)
16 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
17 index 680526e9ee96..ae86983cbf60 100644
20 @@ -2148,9 +2148,10 @@ int ext4_seq_options_show(struct seq_file *seq, void *offset)
23 static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
25 + unsigned long journal_devnum, int read_only)
27 struct ext4_sb_info *sbi = EXT4_SB(sb);
31 if (le32_to_cpu(es->s_rev_level) > EXT4_MAX_SUPP_REV) {
32 @@ -2158,7 +2159,7 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
33 "forcing read-only mode");
37 + if (read_only || err)
39 if (!(sbi->s_mount_state & EXT4_VALID_FS))
40 ext4_msg(sb, KERN_WARNING, "warning: mounting unchecked fs, "
41 @@ -2179,6 +2180,15 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
42 ext4_msg(sb, KERN_WARNING,
43 "warning: checktime reached, "
44 "running e2fsck is recommended");
45 + handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1);
47 + return PTR_ERR(handle);
48 + err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
51 + ext4_journal_stop(handle);
55 es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
56 if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
57 @@ -2188,7 +2198,17 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
58 ext4_update_dynamic_rev(sb);
60 ext4_set_feature_journal_needs_recovery(sb);
63 + es->s_journal_dev = cpu_to_le32(journal_devnum);
64 + if (DUMMY_ENCRYPTION_ENABLED(sbi))
65 + ext4_set_feature_encrypt(sb);
66 + err = ext4_handle_dirty_super(handle, sb);
69 + err = ext4_journal_stop(handle);
72 + ext4_journal_force_commit(sbi->s_journal);
73 err = ext4_commit_super(sb, 1);
75 if (test_opt(sb, DEBUG))
76 @@ -4229,8 +4249,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
78 set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
80 - sbi->s_journal->j_commit_callback = ext4_journal_commit_callback;
83 if (!test_opt(sb, NO_MBCACHE)) {
84 sbi->s_ea_block_cache = ext4_xattr_create_cache();
85 @@ -4257,12 +4275,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
89 - if (DUMMY_ENCRYPTION_ENABLED(sbi) && !sb_rdonly(sb) &&
90 - !ext4_has_feature_encrypt(sb)) {
91 - ext4_set_feature_encrypt(sb);
92 - ext4_commit_super(sb, 1);
96 * Get the # of file system overhead blocks from the
97 * superblock if present.
98 @@ -4311,7 +4323,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
102 - ret = ext4_setup_super(sb, es, sb_rdonly(sb));
103 + ret = ext4_setup_super(sb, es, journal_devnum, sb_rdonly(sb));
105 sb->s_flags |= SB_RDONLY;
107 @@ -4410,6 +4422,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
109 #endif /* CONFIG_QUOTA */
111 + if (sbi->s_journal)
112 + sbi->s_journal->j_commit_callback =
113 + ext4_journal_commit_callback;
114 EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS;
115 ext4_orphan_cleanup(sb, es);
116 EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS;
117 @@ -4780,15 +4795,6 @@ static int ext4_load_journal(struct super_block *sb,
119 EXT4_SB(sb)->s_journal = journal;
120 ext4_clear_journal_err(sb, es);
122 - if (!really_read_only && journal_devnum &&
123 - journal_devnum != le32_to_cpu(es->s_journal_dev)) {
124 - es->s_journal_dev = cpu_to_le32(journal_devnum);
126 - /* Make sure we flush the recovery flag to disk. */
127 - ext4_commit_super(sb, 1);
133 @@ -5263,7 +5269,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
134 ext4_clear_journal_err(sb, es);
135 sbi->s_mount_state = le16_to_cpu(es->s_state);
137 - err = ext4_setup_super(sb, es, 0);
138 + err = ext4_setup_super(sb, es, 0, 0);