add patch fail-unalloc-root-dir-in-ext4_iget
[ext4-patch-queue.git] / journal-superblock-changes
blob3660e9d449b08105f73bd76079313d36acbe8f7b
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>
12 ---
13  fs/ext4/super.c | 57 ++++++++++++++++++++++++++++++++++-----------------------
14  1 file changed, 34 insertions(+), 23 deletions(-)
16 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
17 index 7c46693a14d7..6783af7ec115 100644
18 --- a/fs/ext4/super.c
19 +++ b/fs/ext4/super.c
20 @@ -2108,9 +2108,10 @@ int ext4_seq_options_show(struct seq_file *seq, void *offset)
21  }
23  static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
24 -                           int read_only)
25 +                           unsigned long journal_devnum, int read_only)
26  {
27         struct ext4_sb_info *sbi = EXT4_SB(sb);
28 +       handle_t *handle;
29         int res = 0;
31         if (le32_to_cpu(es->s_rev_level) > EXT4_MAX_SUPP_REV) {
32 @@ -2118,7 +2119,7 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
33                          "forcing read-only mode");
34                 res = SB_RDONLY;
35         }
36 -       if (read_only)
37 +       if (read_only || res)
38                 goto done;
39         if (!(sbi->s_mount_state & EXT4_VALID_FS))
40                 ext4_msg(sb, KERN_WARNING, "warning: mounting unchecked fs, "
41 @@ -2139,6 +2140,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);
46 +       if (IS_ERR(handle))
47 +               return PTR_ERR(handle);
48 +       res = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
49 +       if (res) {
50 +       stop_journal:
51 +               ext4_journal_stop(handle);
52 +               return res;
53 +       }
54         if (!sbi->s_journal)
55                 es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
56         if (!(__s16) le16_to_cpu(es->s_max_mnt_count))
57 @@ -2148,7 +2158,17 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
58         ext4_update_dynamic_rev(sb);
59         if (sbi->s_journal)
60                 ext4_set_feature_journal_needs_recovery(sb);
62 +       if (journal_devnum)
63 +               es->s_journal_dev = cpu_to_le32(journal_devnum);
64 +       if (DUMMY_ENCRYPTION_ENABLED(sbi))
65 +               ext4_set_feature_encrypt(sb);
66 +       res = ext4_handle_dirty_super(handle, sb);
67 +       if (res)
68 +               goto stop_journal;
69 +       res = ext4_journal_stop(handle);
70 +       if (res)
71 +               return res;
72 +       ext4_journal_force_commit(sbi->s_journal);
73         ext4_commit_super(sb, 1);
74  done:
75         if (test_opt(sb, DEBUG))
76 @@ -4116,8 +4136,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;
82  no_journal:
83         if (!test_opt(sb, NO_MBCACHE)) {
84                 sbi->s_ea_block_cache = ext4_xattr_create_cache();
85 @@ -4144,12 +4162,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
86                 goto failed_mount_wq;
87         }
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);
93 -       }
95         /*
96          * Get the # of file system overhead blocks from the
97          * superblock if present.
98 @@ -4198,7 +4210,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
99                 goto failed_mount4;
100         }
102 -       if (ext4_setup_super(sb, es, sb_rdonly(sb)))
103 +       err = ext4_setup_super(sb, es, journal_devnum, sb_rdonly(sb));
104 +       if (err < 0)
105 +               goto failed_mount4a;
106 +       if (err)
107                 sb->s_flags |= SB_RDONLY;
109         /* determine the minimum size of new large inodes, if present */
110 @@ -4293,6 +4308,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
111         }
112  #endif  /* CONFIG_QUOTA */
114 +       if (sbi->s_journal)
115 +               sbi->s_journal->j_commit_callback =
116 +                       ext4_journal_commit_callback;
117         EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS;
118         ext4_orphan_cleanup(sb, es);
119         EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS;
120 @@ -4663,15 +4681,6 @@ static int ext4_load_journal(struct super_block *sb,
122         EXT4_SB(sb)->s_journal = journal;
123         ext4_clear_journal_err(sb, es);
125 -       if (!really_read_only && journal_devnum &&
126 -           journal_devnum != le32_to_cpu(es->s_journal_dev)) {
127 -               es->s_journal_dev = cpu_to_le32(journal_devnum);
129 -               /* Make sure we flush the recovery flag to disk. */
130 -               ext4_commit_super(sb, 1);
131 -       }
133         return 0;
136 @@ -5139,8 +5148,10 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
137                         if (sbi->s_journal)
138                                 ext4_clear_journal_err(sb, es);
139                         sbi->s_mount_state = le16_to_cpu(es->s_state);
140 -                       if (!ext4_setup_super(sb, es, 0))
141 -                               sb->s_flags &= ~SB_RDONLY;
142 +                       sb->s_flags &= ~SB_RDONLY;
143 +                       err = ext4_setup_super(sb, es, 0, 0);
144 +                       if (err)
145 +                               goto restore_opts;
146                         if (ext4_has_feature_mmp(sb))
147                                 if (ext4_multi_mount_protect(sb,
148                                                 le64_to_cpu(es->s_mmp_block))) {