diff options
author | Theodore Ts'o <tytso@mit.edu> | 2014-07-15 06:01:38 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2014-07-15 06:01:38 -0400 |
commit | d5e03cbb0c88cd1be39f2adc37d602230045964b (patch) | |
tree | f784ac7fe19b69b1c26bab64e0b6dd345305a7dd /fs/ext4 | |
parent | 1795cd9b3a91d4b5473c97f491d63892442212ab (diff) |
ext4: rearrange initialization to fix EXT4FS_DEBUG
The EXT4FS_DEBUG is a *very* developer specific #ifdef designed for
ext4 developers only. (You have to modify fs/ext4/ext4.h to enable
it.)
Rearrange how we initialize data structures to avoid calling
ext4_count_free_clusters() until the multiblock allocator has been
initialized.
This also allows us to only call ext4_count_free_clusters() once, and
simplifies the code somewhat.
(Thanks to Chen Gang <gang.chen.5i5j@gmail.com> for pointing out a
!CONFIG_SMP compile breakage in the original patch.)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Lukas Czerner <lczerner@redhat.com>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/super.c | 88 |
1 files changed, 39 insertions, 49 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 6df7bc611dbd..32b43ad154b9 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -2142,10 +2142,6 @@ static int ext4_check_descriptors(struct super_block *sb, | |||
2142 | } | 2142 | } |
2143 | if (NULL != first_not_zeroed) | 2143 | if (NULL != first_not_zeroed) |
2144 | *first_not_zeroed = grp; | 2144 | *first_not_zeroed = grp; |
2145 | |||
2146 | ext4_free_blocks_count_set(sbi->s_es, | ||
2147 | EXT4_C2B(sbi, ext4_count_free_clusters(sb))); | ||
2148 | sbi->s_es->s_free_inodes_count =cpu_to_le32(ext4_count_free_inodes(sb)); | ||
2149 | return 1; | 2145 | return 1; |
2150 | } | 2146 | } |
2151 | 2147 | ||
@@ -3883,13 +3879,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3883 | ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); | 3879 | ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); |
3884 | goto failed_mount2; | 3880 | goto failed_mount2; |
3885 | } | 3881 | } |
3886 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) | ||
3887 | if (!ext4_fill_flex_info(sb)) { | ||
3888 | ext4_msg(sb, KERN_ERR, | ||
3889 | "unable to initialize " | ||
3890 | "flex_bg meta info!"); | ||
3891 | goto failed_mount2; | ||
3892 | } | ||
3893 | 3882 | ||
3894 | sbi->s_gdb_count = db_count; | 3883 | sbi->s_gdb_count = db_count; |
3895 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 3884 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |
@@ -3902,23 +3891,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3902 | /* Register extent status tree shrinker */ | 3891 | /* Register extent status tree shrinker */ |
3903 | ext4_es_register_shrinker(sbi); | 3892 | ext4_es_register_shrinker(sbi); |
3904 | 3893 | ||
3905 | err = percpu_counter_init(&sbi->s_freeclusters_counter, | 3894 | if ((err = percpu_counter_init(&sbi->s_extent_cache_cnt, 0)) != 0) { |
3906 | ext4_count_free_clusters(sb)); | ||
3907 | if (!err) { | ||
3908 | err = percpu_counter_init(&sbi->s_freeinodes_counter, | ||
3909 | ext4_count_free_inodes(sb)); | ||
3910 | } | ||
3911 | if (!err) { | ||
3912 | err = percpu_counter_init(&sbi->s_dirs_counter, | ||
3913 | ext4_count_dirs(sb)); | ||
3914 | } | ||
3915 | if (!err) { | ||
3916 | err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0); | ||
3917 | } | ||
3918 | if (!err) { | ||
3919 | err = percpu_counter_init(&sbi->s_extent_cache_cnt, 0); | ||
3920 | } | ||
3921 | if (err) { | ||
3922 | ext4_msg(sb, KERN_ERR, "insufficient memory"); | 3895 | ext4_msg(sb, KERN_ERR, "insufficient memory"); |
3923 | goto failed_mount3; | 3896 | goto failed_mount3; |
3924 | } | 3897 | } |
@@ -4022,18 +3995,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
4022 | 3995 | ||
4023 | sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; | 3996 | sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; |
4024 | 3997 | ||
4025 | /* | ||
4026 | * The journal may have updated the bg summary counts, so we | ||
4027 | * need to update the global counters. | ||
4028 | */ | ||
4029 | percpu_counter_set(&sbi->s_freeclusters_counter, | ||
4030 | ext4_count_free_clusters(sb)); | ||
4031 | percpu_counter_set(&sbi->s_freeinodes_counter, | ||
4032 | ext4_count_free_inodes(sb)); | ||
4033 | percpu_counter_set(&sbi->s_dirs_counter, | ||
4034 | ext4_count_dirs(sb)); | ||
4035 | percpu_counter_set(&sbi->s_dirtyclusters_counter, 0); | ||
4036 | |||
4037 | no_journal: | 3998 | no_journal: |
4038 | if (ext4_mballoc_ready) { | 3999 | if (ext4_mballoc_ready) { |
4039 | sbi->s_mb_cache = ext4_xattr_create_cache(sb->s_id); | 4000 | sbi->s_mb_cache = ext4_xattr_create_cache(sb->s_id); |
@@ -4141,6 +4102,33 @@ no_journal: | |||
4141 | goto failed_mount5; | 4102 | goto failed_mount5; |
4142 | } | 4103 | } |
4143 | 4104 | ||
4105 | block = ext4_count_free_clusters(sb); | ||
4106 | ext4_free_blocks_count_set(sbi->s_es, | ||
4107 | EXT4_C2B(sbi, block)); | ||
4108 | err = percpu_counter_init(&sbi->s_freeclusters_counter, block); | ||
4109 | if (!err) { | ||
4110 | unsigned long freei = ext4_count_free_inodes(sb); | ||
4111 | sbi->s_es->s_free_inodes_count = cpu_to_le32(freei); | ||
4112 | err = percpu_counter_init(&sbi->s_freeinodes_counter, freei); | ||
4113 | } | ||
4114 | if (!err) | ||
4115 | err = percpu_counter_init(&sbi->s_dirs_counter, | ||
4116 | ext4_count_dirs(sb)); | ||
4117 | if (!err) | ||
4118 | err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0); | ||
4119 | if (err) { | ||
4120 | ext4_msg(sb, KERN_ERR, "insufficient memory"); | ||
4121 | goto failed_mount6; | ||
4122 | } | ||
4123 | |||
4124 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) | ||
4125 | if (!ext4_fill_flex_info(sb)) { | ||
4126 | ext4_msg(sb, KERN_ERR, | ||
4127 | "unable to initialize " | ||
4128 | "flex_bg meta info!"); | ||
4129 | goto failed_mount6; | ||
4130 | } | ||
4131 | |||
4144 | err = ext4_register_li_request(sb, first_not_zeroed); | 4132 | err = ext4_register_li_request(sb, first_not_zeroed); |
4145 | if (err) | 4133 | if (err) |
4146 | goto failed_mount6; | 4134 | goto failed_mount6; |
@@ -4215,6 +4203,12 @@ failed_mount7: | |||
4215 | ext4_unregister_li_request(sb); | 4203 | ext4_unregister_li_request(sb); |
4216 | failed_mount6: | 4204 | failed_mount6: |
4217 | ext4_mb_release(sb); | 4205 | ext4_mb_release(sb); |
4206 | if (sbi->s_flex_groups) | ||
4207 | ext4_kvfree(sbi->s_flex_groups); | ||
4208 | percpu_counter_destroy(&sbi->s_freeclusters_counter); | ||
4209 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | ||
4210 | percpu_counter_destroy(&sbi->s_dirs_counter); | ||
4211 | percpu_counter_destroy(&sbi->s_dirtyclusters_counter); | ||
4218 | failed_mount5: | 4212 | failed_mount5: |
4219 | ext4_ext_release(sb); | 4213 | ext4_ext_release(sb); |
4220 | ext4_release_system_zone(sb); | 4214 | ext4_release_system_zone(sb); |
@@ -4233,12 +4227,6 @@ failed_mount_wq: | |||
4233 | failed_mount3: | 4227 | failed_mount3: |
4234 | ext4_es_unregister_shrinker(sbi); | 4228 | ext4_es_unregister_shrinker(sbi); |
4235 | del_timer_sync(&sbi->s_err_report); | 4229 | del_timer_sync(&sbi->s_err_report); |
4236 | if (sbi->s_flex_groups) | ||
4237 | ext4_kvfree(sbi->s_flex_groups); | ||
4238 | percpu_counter_destroy(&sbi->s_freeclusters_counter); | ||
4239 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | ||
4240 | percpu_counter_destroy(&sbi->s_dirs_counter); | ||
4241 | percpu_counter_destroy(&sbi->s_dirtyclusters_counter); | ||
4242 | percpu_counter_destroy(&sbi->s_extent_cache_cnt); | 4230 | percpu_counter_destroy(&sbi->s_extent_cache_cnt); |
4243 | if (sbi->s_mmp_tsk) | 4231 | if (sbi->s_mmp_tsk) |
4244 | kthread_stop(sbi->s_mmp_tsk); | 4232 | kthread_stop(sbi->s_mmp_tsk); |
@@ -4556,11 +4544,13 @@ static int ext4_commit_super(struct super_block *sb, int sync) | |||
4556 | else | 4544 | else |
4557 | es->s_kbytes_written = | 4545 | es->s_kbytes_written = |
4558 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); | 4546 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); |
4559 | ext4_free_blocks_count_set(es, | 4547 | if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeclusters_counter)) |
4548 | ext4_free_blocks_count_set(es, | ||
4560 | EXT4_C2B(EXT4_SB(sb), percpu_counter_sum_positive( | 4549 | EXT4_C2B(EXT4_SB(sb), percpu_counter_sum_positive( |
4561 | &EXT4_SB(sb)->s_freeclusters_counter))); | 4550 | &EXT4_SB(sb)->s_freeclusters_counter))); |
4562 | es->s_free_inodes_count = | 4551 | if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeinodes_counter)) |
4563 | cpu_to_le32(percpu_counter_sum_positive( | 4552 | es->s_free_inodes_count = |
4553 | cpu_to_le32(percpu_counter_sum_positive( | ||
4564 | &EXT4_SB(sb)->s_freeinodes_counter)); | 4554 | &EXT4_SB(sb)->s_freeinodes_counter)); |
4565 | BUFFER_TRACE(sbh, "marking dirty"); | 4555 | BUFFER_TRACE(sbh, "marking dirty"); |
4566 | ext4_superblock_csum_set(sb); | 4556 | ext4_superblock_csum_set(sb); |