aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2014-07-11 13:55:40 -0400
committerTheodore Ts'o <tytso@mit.edu>2014-07-11 13:55:40 -0400
commitf9ae9cf5d72b3926ca48ea60e15bdbb840f42372 (patch)
treec80eaf6959f3c8cea964782a5262a71a1d6bd92f /fs/ext4/super.c
parent5dd214248f94d430d70e9230bda72f2654ac88a8 (diff)
ext4: revert commit which was causing fs corruption after journal replays
Commit 007649375f6af2 ("ext4: initialize multi-block allocator before checking block descriptors") causes the block group descriptor's count of the number of free blocks to become inconsistent with the number of free blocks in the allocation bitmap. This is a harmless form of fs corruption, but it causes the kernel to potentially remount the file system read-only, or to panic, depending on the file systems's error behavior. Thanks to Eric Whitney for his tireless work to reproduce and to find the guilty commit. Fixes: 007649375f6af2 ("ext4: initialize multi-block allocator before checking block descriptors" Cc: stable@vger.kernel.org # 3.15 Reported-by: David Jander <david@protonic.nl> Reported-by: Matteo Croce <technoboy85@gmail.com> Tested-by: Eric Whitney <enwlinux@gmail.com> Suggested-by: Eric Whitney <enwlinux@gmail.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c51
1 files changed, 24 insertions, 27 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 6297c07c937f..6df7bc611dbd 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3879,38 +3879,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3879 goto failed_mount2; 3879 goto failed_mount2;
3880 } 3880 }
3881 } 3881 }
3882
3883 /*
3884 * set up enough so that it can read an inode,
3885 * and create new inode for buddy allocator
3886 */
3887 sbi->s_gdb_count = db_count;
3888 if (!test_opt(sb, NOLOAD) &&
3889 EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
3890 sb->s_op = &ext4_sops;
3891 else
3892 sb->s_op = &ext4_nojournal_sops;
3893
3894 ext4_ext_init(sb);
3895 err = ext4_mb_init(sb);
3896 if (err) {
3897 ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
3898 err);
3899 goto failed_mount2;
3900 }
3901
3902 if (!ext4_check_descriptors(sb, &first_not_zeroed)) { 3882 if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
3903 ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); 3883 ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
3904 goto failed_mount2a; 3884 goto failed_mount2;
3905 } 3885 }
3906 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) 3886 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
3907 if (!ext4_fill_flex_info(sb)) { 3887 if (!ext4_fill_flex_info(sb)) {
3908 ext4_msg(sb, KERN_ERR, 3888 ext4_msg(sb, KERN_ERR,
3909 "unable to initialize " 3889 "unable to initialize "
3910 "flex_bg meta info!"); 3890 "flex_bg meta info!");
3911 goto failed_mount2a; 3891 goto failed_mount2;
3912 } 3892 }
3913 3893
3894 sbi->s_gdb_count = db_count;
3914 get_random_bytes(&sbi->s_next_generation, sizeof(u32)); 3895 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
3915 spin_lock_init(&sbi->s_next_gen_lock); 3896 spin_lock_init(&sbi->s_next_gen_lock);
3916 3897
@@ -3945,6 +3926,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3945 sbi->s_stripe = ext4_get_stripe_size(sbi); 3926 sbi->s_stripe = ext4_get_stripe_size(sbi);
3946 sbi->s_extent_max_zeroout_kb = 32; 3927 sbi->s_extent_max_zeroout_kb = 32;
3947 3928
3929 /*
3930 * set up enough so that it can read an inode
3931 */
3932 if (!test_opt(sb, NOLOAD) &&
3933 EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
3934 sb->s_op = &ext4_sops;
3935 else
3936 sb->s_op = &ext4_nojournal_sops;
3948 sb->s_export_op = &ext4_export_ops; 3937 sb->s_export_op = &ext4_export_ops;
3949 sb->s_xattr = ext4_xattr_handlers; 3938 sb->s_xattr = ext4_xattr_handlers;
3950#ifdef CONFIG_QUOTA 3939#ifdef CONFIG_QUOTA
@@ -4134,13 +4123,21 @@ no_journal:
4134 if (err) { 4123 if (err) {
4135 ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for " 4124 ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
4136 "reserved pool", ext4_calculate_resv_clusters(sb)); 4125 "reserved pool", ext4_calculate_resv_clusters(sb));
4137 goto failed_mount5; 4126 goto failed_mount4a;
4138 } 4127 }
4139 4128
4140 err = ext4_setup_system_zone(sb); 4129 err = ext4_setup_system_zone(sb);
4141 if (err) { 4130 if (err) {
4142 ext4_msg(sb, KERN_ERR, "failed to initialize system " 4131 ext4_msg(sb, KERN_ERR, "failed to initialize system "
4143 "zone (%d)", err); 4132 "zone (%d)", err);
4133 goto failed_mount4a;
4134 }
4135
4136 ext4_ext_init(sb);
4137 err = ext4_mb_init(sb);
4138 if (err) {
4139 ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
4140 err);
4144 goto failed_mount5; 4141 goto failed_mount5;
4145 } 4142 }
4146 4143
@@ -4217,8 +4214,11 @@ failed_mount8:
4217failed_mount7: 4214failed_mount7:
4218 ext4_unregister_li_request(sb); 4215 ext4_unregister_li_request(sb);
4219failed_mount6: 4216failed_mount6:
4220 ext4_release_system_zone(sb); 4217 ext4_mb_release(sb);
4221failed_mount5: 4218failed_mount5:
4219 ext4_ext_release(sb);
4220 ext4_release_system_zone(sb);
4221failed_mount4a:
4222 dput(sb->s_root); 4222 dput(sb->s_root);
4223 sb->s_root = NULL; 4223 sb->s_root = NULL;
4224failed_mount4: 4224failed_mount4:
@@ -4242,14 +4242,11 @@ failed_mount3:
4242 percpu_counter_destroy(&sbi->s_extent_cache_cnt); 4242 percpu_counter_destroy(&sbi->s_extent_cache_cnt);
4243 if (sbi->s_mmp_tsk) 4243 if (sbi->s_mmp_tsk)
4244 kthread_stop(sbi->s_mmp_tsk); 4244 kthread_stop(sbi->s_mmp_tsk);
4245failed_mount2a:
4246 ext4_mb_release(sb);
4247failed_mount2: 4245failed_mount2:
4248 for (i = 0; i < db_count; i++) 4246 for (i = 0; i < db_count; i++)
4249 brelse(sbi->s_group_desc[i]); 4247 brelse(sbi->s_group_desc[i]);
4250 ext4_kvfree(sbi->s_group_desc); 4248 ext4_kvfree(sbi->s_group_desc);
4251failed_mount: 4249failed_mount:
4252 ext4_ext_release(sb);
4253 if (sbi->s_chksum_driver) 4250 if (sbi->s_chksum_driver)
4254 crypto_free_shash(sbi->s_chksum_driver); 4251 crypto_free_shash(sbi->s_chksum_driver);
4255 if (sbi->s_proc) { 4252 if (sbi->s_proc) {