diff options
-rw-r--r-- | fs/ext4/balloc.c | 15 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 12 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 40 | ||||
-rw-r--r-- | fs/ext4/inode.c | 7 | ||||
-rw-r--r-- | fs/ext4/mballoc.c | 45 | ||||
-rw-r--r-- | fs/ext4/super.c | 3 |
6 files changed, 67 insertions, 55 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 53c72ad85877..a5ba039850c5 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -88,6 +88,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
88 | ext4_group_t block_group, struct ext4_group_desc *gdp) | 88 | ext4_group_t block_group, struct ext4_group_desc *gdp) |
89 | { | 89 | { |
90 | int bit, bit_max; | 90 | int bit, bit_max; |
91 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
91 | unsigned free_blocks, group_blocks; | 92 | unsigned free_blocks, group_blocks; |
92 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 93 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
93 | 94 | ||
@@ -123,7 +124,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
123 | bit_max += ext4_bg_num_gdb(sb, block_group); | 124 | bit_max += ext4_bg_num_gdb(sb, block_group); |
124 | } | 125 | } |
125 | 126 | ||
126 | if (block_group == sbi->s_groups_count - 1) { | 127 | if (block_group == ngroups - 1) { |
127 | /* | 128 | /* |
128 | * Even though mke2fs always initialize first and last group | 129 | * Even though mke2fs always initialize first and last group |
129 | * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need | 130 | * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need |
@@ -131,7 +132,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
131 | */ | 132 | */ |
132 | group_blocks = ext4_blocks_count(sbi->s_es) - | 133 | group_blocks = ext4_blocks_count(sbi->s_es) - |
133 | le32_to_cpu(sbi->s_es->s_first_data_block) - | 134 | le32_to_cpu(sbi->s_es->s_first_data_block) - |
134 | (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count - 1)); | 135 | (EXT4_BLOCKS_PER_GROUP(sb) * (ngroups - 1)); |
135 | } else { | 136 | } else { |
136 | group_blocks = EXT4_BLOCKS_PER_GROUP(sb); | 137 | group_blocks = EXT4_BLOCKS_PER_GROUP(sb); |
137 | } | 138 | } |
@@ -205,18 +206,18 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, | |||
205 | { | 206 | { |
206 | unsigned int group_desc; | 207 | unsigned int group_desc; |
207 | unsigned int offset; | 208 | unsigned int offset; |
209 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
208 | struct ext4_group_desc *desc; | 210 | struct ext4_group_desc *desc; |
209 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 211 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
210 | 212 | ||
211 | if (block_group >= sbi->s_groups_count) { | 213 | if (block_group >= ngroups) { |
212 | ext4_error(sb, "ext4_get_group_desc", | 214 | ext4_error(sb, "ext4_get_group_desc", |
213 | "block_group >= groups_count - " | 215 | "block_group >= groups_count - " |
214 | "block_group = %u, groups_count = %u", | 216 | "block_group = %u, groups_count = %u", |
215 | block_group, sbi->s_groups_count); | 217 | block_group, ngroups); |
216 | 218 | ||
217 | return NULL; | 219 | return NULL; |
218 | } | 220 | } |
219 | smp_rmb(); | ||
220 | 221 | ||
221 | group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); | 222 | group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); |
222 | offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); | 223 | offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); |
@@ -665,7 +666,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
665 | ext4_fsblk_t desc_count; | 666 | ext4_fsblk_t desc_count; |
666 | struct ext4_group_desc *gdp; | 667 | struct ext4_group_desc *gdp; |
667 | ext4_group_t i; | 668 | ext4_group_t i; |
668 | ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | 669 | ext4_group_t ngroups = ext4_get_groups_count(sb); |
669 | #ifdef EXT4FS_DEBUG | 670 | #ifdef EXT4FS_DEBUG |
670 | struct ext4_super_block *es; | 671 | struct ext4_super_block *es; |
671 | ext4_fsblk_t bitmap_count; | 672 | ext4_fsblk_t bitmap_count; |
@@ -677,7 +678,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
677 | bitmap_count = 0; | 678 | bitmap_count = 0; |
678 | gdp = NULL; | 679 | gdp = NULL; |
679 | 680 | ||
680 | smp_rmb(); | ||
681 | for (i = 0; i < ngroups; i++) { | 681 | for (i = 0; i < ngroups; i++) { |
682 | gdp = ext4_get_group_desc(sb, i, NULL); | 682 | gdp = ext4_get_group_desc(sb, i, NULL); |
683 | if (!gdp) | 683 | if (!gdp) |
@@ -700,7 +700,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
700 | return bitmap_count; | 700 | return bitmap_count; |
701 | #else | 701 | #else |
702 | desc_count = 0; | 702 | desc_count = 0; |
703 | smp_rmb(); | ||
704 | for (i = 0; i < ngroups; i++) { | 703 | for (i = 0; i < ngroups; i++) { |
705 | gdp = ext4_get_group_desc(sb, i, NULL); | 704 | gdp = ext4_get_group_desc(sb, i, NULL); |
706 | if (!gdp) | 705 | if (!gdp) |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index d0f15ef56de1..02ec44bf38e6 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1228,6 +1228,18 @@ struct ext4_group_info *ext4_get_group_info(struct super_block *sb, | |||
1228 | return grp_info[indexv][indexh]; | 1228 | return grp_info[indexv][indexh]; |
1229 | } | 1229 | } |
1230 | 1230 | ||
1231 | /* | ||
1232 | * Reading s_groups_count requires using smp_rmb() afterwards. See | ||
1233 | * the locking protocol documented in the comments of ext4_group_add() | ||
1234 | * in resize.c | ||
1235 | */ | ||
1236 | static inline ext4_group_t ext4_get_groups_count(struct super_block *sb) | ||
1237 | { | ||
1238 | ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | ||
1239 | |||
1240 | smp_rmb(); | ||
1241 | return ngroups; | ||
1242 | } | ||
1231 | 1243 | ||
1232 | static inline ext4_group_t ext4_flex_group(struct ext4_sb_info *sbi, | 1244 | static inline ext4_group_t ext4_flex_group(struct ext4_sb_info *sbi, |
1233 | ext4_group_t block_group) | 1245 | ext4_group_t block_group) |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index f18e0a08a6b5..55ba419ca00b 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -316,7 +316,7 @@ error_return: | |||
316 | static int find_group_dir(struct super_block *sb, struct inode *parent, | 316 | static int find_group_dir(struct super_block *sb, struct inode *parent, |
317 | ext4_group_t *best_group) | 317 | ext4_group_t *best_group) |
318 | { | 318 | { |
319 | ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | 319 | ext4_group_t ngroups = ext4_get_groups_count(sb); |
320 | unsigned int freei, avefreei; | 320 | unsigned int freei, avefreei; |
321 | struct ext4_group_desc *desc, *best_desc = NULL; | 321 | struct ext4_group_desc *desc, *best_desc = NULL; |
322 | ext4_group_t group; | 322 | ext4_group_t group; |
@@ -353,7 +353,7 @@ static int find_group_flex(struct super_block *sb, struct inode *parent, | |||
353 | struct flex_groups *flex_group = sbi->s_flex_groups; | 353 | struct flex_groups *flex_group = sbi->s_flex_groups; |
354 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; | 354 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; |
355 | ext4_group_t parent_fbg_group = ext4_flex_group(sbi, parent_group); | 355 | ext4_group_t parent_fbg_group = ext4_flex_group(sbi, parent_group); |
356 | ext4_group_t ngroups = sbi->s_groups_count; | 356 | ext4_group_t ngroups = ext4_get_groups_count(sb); |
357 | int flex_size = ext4_flex_bg_size(sbi); | 357 | int flex_size = ext4_flex_bg_size(sbi); |
358 | ext4_group_t best_flex = parent_fbg_group; | 358 | ext4_group_t best_flex = parent_fbg_group; |
359 | int blocks_per_flex = sbi->s_blocks_per_group * flex_size; | 359 | int blocks_per_flex = sbi->s_blocks_per_group * flex_size; |
@@ -362,7 +362,7 @@ static int find_group_flex(struct super_block *sb, struct inode *parent, | |||
362 | ext4_group_t n_fbg_groups; | 362 | ext4_group_t n_fbg_groups; |
363 | ext4_group_t i; | 363 | ext4_group_t i; |
364 | 364 | ||
365 | n_fbg_groups = (sbi->s_groups_count + flex_size - 1) >> | 365 | n_fbg_groups = (ngroups + flex_size - 1) >> |
366 | sbi->s_log_groups_per_flex; | 366 | sbi->s_log_groups_per_flex; |
367 | 367 | ||
368 | find_close_to_parent: | 368 | find_close_to_parent: |
@@ -478,20 +478,21 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, | |||
478 | { | 478 | { |
479 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; | 479 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; |
480 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 480 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
481 | ext4_group_t ngroups = sbi->s_groups_count; | 481 | ext4_group_t real_ngroups = ext4_get_groups_count(sb); |
482 | int inodes_per_group = EXT4_INODES_PER_GROUP(sb); | 482 | int inodes_per_group = EXT4_INODES_PER_GROUP(sb); |
483 | unsigned int freei, avefreei; | 483 | unsigned int freei, avefreei; |
484 | ext4_fsblk_t freeb, avefreeb; | 484 | ext4_fsblk_t freeb, avefreeb; |
485 | unsigned int ndirs; | 485 | unsigned int ndirs; |
486 | int max_dirs, min_inodes; | 486 | int max_dirs, min_inodes; |
487 | ext4_grpblk_t min_blocks; | 487 | ext4_grpblk_t min_blocks; |
488 | ext4_group_t i, grp, g; | 488 | ext4_group_t i, grp, g, ngroups; |
489 | struct ext4_group_desc *desc; | 489 | struct ext4_group_desc *desc; |
490 | struct orlov_stats stats; | 490 | struct orlov_stats stats; |
491 | int flex_size = ext4_flex_bg_size(sbi); | 491 | int flex_size = ext4_flex_bg_size(sbi); |
492 | 492 | ||
493 | ngroups = real_ngroups; | ||
493 | if (flex_size > 1) { | 494 | if (flex_size > 1) { |
494 | ngroups = (ngroups + flex_size - 1) >> | 495 | ngroups = (real_ngroups + flex_size - 1) >> |
495 | sbi->s_log_groups_per_flex; | 496 | sbi->s_log_groups_per_flex; |
496 | parent_group >>= sbi->s_log_groups_per_flex; | 497 | parent_group >>= sbi->s_log_groups_per_flex; |
497 | } | 498 | } |
@@ -543,7 +544,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, | |||
543 | */ | 544 | */ |
544 | grp *= flex_size; | 545 | grp *= flex_size; |
545 | for (i = 0; i < flex_size; i++) { | 546 | for (i = 0; i < flex_size; i++) { |
546 | if (grp+i >= sbi->s_groups_count) | 547 | if (grp+i >= real_ngroups) |
547 | break; | 548 | break; |
548 | desc = ext4_get_group_desc(sb, grp+i, NULL); | 549 | desc = ext4_get_group_desc(sb, grp+i, NULL); |
549 | if (desc && ext4_free_inodes_count(sb, desc)) { | 550 | if (desc && ext4_free_inodes_count(sb, desc)) { |
@@ -583,7 +584,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, | |||
583 | } | 584 | } |
584 | 585 | ||
585 | fallback: | 586 | fallback: |
586 | ngroups = sbi->s_groups_count; | 587 | ngroups = real_ngroups; |
587 | avefreei = freei / ngroups; | 588 | avefreei = freei / ngroups; |
588 | fallback_retry: | 589 | fallback_retry: |
589 | parent_group = EXT4_I(parent)->i_block_group; | 590 | parent_group = EXT4_I(parent)->i_block_group; |
@@ -613,9 +614,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent, | |||
613 | ext4_group_t *group, int mode) | 614 | ext4_group_t *group, int mode) |
614 | { | 615 | { |
615 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; | 616 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; |
616 | ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | 617 | ext4_group_t i, last, ngroups = ext4_get_groups_count(sb); |
617 | struct ext4_group_desc *desc; | 618 | struct ext4_group_desc *desc; |
618 | ext4_group_t i, last; | ||
619 | int flex_size = ext4_flex_bg_size(EXT4_SB(sb)); | 619 | int flex_size = ext4_flex_bg_size(EXT4_SB(sb)); |
620 | 620 | ||
621 | /* | 621 | /* |
@@ -799,11 +799,10 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) | |||
799 | struct super_block *sb; | 799 | struct super_block *sb; |
800 | struct buffer_head *inode_bitmap_bh = NULL; | 800 | struct buffer_head *inode_bitmap_bh = NULL; |
801 | struct buffer_head *group_desc_bh; | 801 | struct buffer_head *group_desc_bh; |
802 | ext4_group_t group = 0; | 802 | ext4_group_t ngroups, group = 0; |
803 | unsigned long ino = 0; | 803 | unsigned long ino = 0; |
804 | struct inode *inode; | 804 | struct inode *inode; |
805 | struct ext4_group_desc *gdp = NULL; | 805 | struct ext4_group_desc *gdp = NULL; |
806 | struct ext4_super_block *es; | ||
807 | struct ext4_inode_info *ei; | 806 | struct ext4_inode_info *ei; |
808 | struct ext4_sb_info *sbi; | 807 | struct ext4_sb_info *sbi; |
809 | int ret2, err = 0; | 808 | int ret2, err = 0; |
@@ -818,15 +817,14 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) | |||
818 | return ERR_PTR(-EPERM); | 817 | return ERR_PTR(-EPERM); |
819 | 818 | ||
820 | sb = dir->i_sb; | 819 | sb = dir->i_sb; |
820 | ngroups = ext4_get_groups_count(sb); | ||
821 | trace_mark(ext4_request_inode, "dev %s dir %lu mode %d", sb->s_id, | 821 | trace_mark(ext4_request_inode, "dev %s dir %lu mode %d", sb->s_id, |
822 | dir->i_ino, mode); | 822 | dir->i_ino, mode); |
823 | inode = new_inode(sb); | 823 | inode = new_inode(sb); |
824 | if (!inode) | 824 | if (!inode) |
825 | return ERR_PTR(-ENOMEM); | 825 | return ERR_PTR(-ENOMEM); |
826 | ei = EXT4_I(inode); | 826 | ei = EXT4_I(inode); |
827 | |||
828 | sbi = EXT4_SB(sb); | 827 | sbi = EXT4_SB(sb); |
829 | es = sbi->s_es; | ||
830 | 828 | ||
831 | if (sbi->s_log_groups_per_flex && test_opt(sb, OLDALLOC)) { | 829 | if (sbi->s_log_groups_per_flex && test_opt(sb, OLDALLOC)) { |
832 | ret2 = find_group_flex(sb, dir, &group); | 830 | ret2 = find_group_flex(sb, dir, &group); |
@@ -856,7 +854,7 @@ got_group: | |||
856 | if (ret2 == -1) | 854 | if (ret2 == -1) |
857 | goto out; | 855 | goto out; |
858 | 856 | ||
859 | for (i = 0; i < sbi->s_groups_count; i++) { | 857 | for (i = 0; i < ngroups; i++) { |
860 | err = -EIO; | 858 | err = -EIO; |
861 | 859 | ||
862 | gdp = ext4_get_group_desc(sb, group, &group_desc_bh); | 860 | gdp = ext4_get_group_desc(sb, group, &group_desc_bh); |
@@ -917,7 +915,7 @@ repeat_in_this_group: | |||
917 | * group descriptor metadata has not yet been updated. | 915 | * group descriptor metadata has not yet been updated. |
918 | * So we just go onto the next blockgroup. | 916 | * So we just go onto the next blockgroup. |
919 | */ | 917 | */ |
920 | if (++group == sbi->s_groups_count) | 918 | if (++group == ngroups) |
921 | group = 0; | 919 | group = 0; |
922 | } | 920 | } |
923 | err = -ENOSPC; | 921 | err = -ENOSPC; |
@@ -1158,7 +1156,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) | |||
1158 | { | 1156 | { |
1159 | unsigned long desc_count; | 1157 | unsigned long desc_count; |
1160 | struct ext4_group_desc *gdp; | 1158 | struct ext4_group_desc *gdp; |
1161 | ext4_group_t i; | 1159 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
1162 | #ifdef EXT4FS_DEBUG | 1160 | #ifdef EXT4FS_DEBUG |
1163 | struct ext4_super_block *es; | 1161 | struct ext4_super_block *es; |
1164 | unsigned long bitmap_count, x; | 1162 | unsigned long bitmap_count, x; |
@@ -1168,7 +1166,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) | |||
1168 | desc_count = 0; | 1166 | desc_count = 0; |
1169 | bitmap_count = 0; | 1167 | bitmap_count = 0; |
1170 | gdp = NULL; | 1168 | gdp = NULL; |
1171 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { | 1169 | for (i = 0; i < ngroups; i++) { |
1172 | gdp = ext4_get_group_desc(sb, i, NULL); | 1170 | gdp = ext4_get_group_desc(sb, i, NULL); |
1173 | if (!gdp) | 1171 | if (!gdp) |
1174 | continue; | 1172 | continue; |
@@ -1190,7 +1188,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) | |||
1190 | return desc_count; | 1188 | return desc_count; |
1191 | #else | 1189 | #else |
1192 | desc_count = 0; | 1190 | desc_count = 0; |
1193 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { | 1191 | for (i = 0; i < ngroups; i++) { |
1194 | gdp = ext4_get_group_desc(sb, i, NULL); | 1192 | gdp = ext4_get_group_desc(sb, i, NULL); |
1195 | if (!gdp) | 1193 | if (!gdp) |
1196 | continue; | 1194 | continue; |
@@ -1205,9 +1203,9 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) | |||
1205 | unsigned long ext4_count_dirs(struct super_block * sb) | 1203 | unsigned long ext4_count_dirs(struct super_block * sb) |
1206 | { | 1204 | { |
1207 | unsigned long count = 0; | 1205 | unsigned long count = 0; |
1208 | ext4_group_t i; | 1206 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
1209 | 1207 | ||
1210 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { | 1208 | for (i = 0; i < ngroups; i++) { |
1211 | struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL); | 1209 | struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL); |
1212 | if (!gdp) | 1210 | if (!gdp) |
1213 | continue; | 1211 | continue; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 96f3366f59f6..4e7f363e3030 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -4965,7 +4965,8 @@ static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) | |||
4965 | */ | 4965 | */ |
4966 | int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) | 4966 | int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) |
4967 | { | 4967 | { |
4968 | int groups, gdpblocks; | 4968 | ext4_group_t groups, ngroups = ext4_get_groups_count(inode->i_sb); |
4969 | int gdpblocks; | ||
4969 | int idxblocks; | 4970 | int idxblocks; |
4970 | int ret = 0; | 4971 | int ret = 0; |
4971 | 4972 | ||
@@ -4992,8 +4993,8 @@ int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) | |||
4992 | groups += nrblocks; | 4993 | groups += nrblocks; |
4993 | 4994 | ||
4994 | gdpblocks = groups; | 4995 | gdpblocks = groups; |
4995 | if (groups > EXT4_SB(inode->i_sb)->s_groups_count) | 4996 | if (groups > ngroups) |
4996 | groups = EXT4_SB(inode->i_sb)->s_groups_count; | 4997 | groups = ngroups; |
4997 | if (groups > EXT4_SB(inode->i_sb)->s_gdb_count) | 4998 | if (groups > EXT4_SB(inode->i_sb)->s_gdb_count) |
4998 | gdpblocks = EXT4_SB(inode->i_sb)->s_gdb_count; | 4999 | gdpblocks = EXT4_SB(inode->i_sb)->s_gdb_count; |
4999 | 5000 | ||
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index f871677a7984..c3af9e6b6668 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -739,6 +739,7 @@ static void ext4_mb_generate_buddy(struct super_block *sb, | |||
739 | 739 | ||
740 | static int ext4_mb_init_cache(struct page *page, char *incore) | 740 | static int ext4_mb_init_cache(struct page *page, char *incore) |
741 | { | 741 | { |
742 | ext4_group_t ngroups; | ||
742 | int blocksize; | 743 | int blocksize; |
743 | int blocks_per_page; | 744 | int blocks_per_page; |
744 | int groups_per_page; | 745 | int groups_per_page; |
@@ -757,6 +758,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore) | |||
757 | 758 | ||
758 | inode = page->mapping->host; | 759 | inode = page->mapping->host; |
759 | sb = inode->i_sb; | 760 | sb = inode->i_sb; |
761 | ngroups = ext4_get_groups_count(sb); | ||
760 | blocksize = 1 << inode->i_blkbits; | 762 | blocksize = 1 << inode->i_blkbits; |
761 | blocks_per_page = PAGE_CACHE_SIZE / blocksize; | 763 | blocks_per_page = PAGE_CACHE_SIZE / blocksize; |
762 | 764 | ||
@@ -780,7 +782,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore) | |||
780 | for (i = 0; i < groups_per_page; i++) { | 782 | for (i = 0; i < groups_per_page; i++) { |
781 | struct ext4_group_desc *desc; | 783 | struct ext4_group_desc *desc; |
782 | 784 | ||
783 | if (first_group + i >= EXT4_SB(sb)->s_groups_count) | 785 | if (first_group + i >= ngroups) |
784 | break; | 786 | break; |
785 | 787 | ||
786 | err = -EIO; | 788 | err = -EIO; |
@@ -852,7 +854,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore) | |||
852 | struct ext4_group_info *grinfo; | 854 | struct ext4_group_info *grinfo; |
853 | 855 | ||
854 | group = (first_block + i) >> 1; | 856 | group = (first_block + i) >> 1; |
855 | if (group >= EXT4_SB(sb)->s_groups_count) | 857 | if (group >= ngroups) |
856 | break; | 858 | break; |
857 | 859 | ||
858 | /* | 860 | /* |
@@ -1788,6 +1790,7 @@ int ext4_mb_get_buddy_cache_lock(struct super_block *sb, ext4_group_t group) | |||
1788 | int block, pnum; | 1790 | int block, pnum; |
1789 | int blocks_per_page; | 1791 | int blocks_per_page; |
1790 | int groups_per_page; | 1792 | int groups_per_page; |
1793 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
1791 | ext4_group_t first_group; | 1794 | ext4_group_t first_group; |
1792 | struct ext4_group_info *grp; | 1795 | struct ext4_group_info *grp; |
1793 | 1796 | ||
@@ -1807,7 +1810,7 @@ int ext4_mb_get_buddy_cache_lock(struct super_block *sb, ext4_group_t group) | |||
1807 | /* read all groups the page covers into the cache */ | 1810 | /* read all groups the page covers into the cache */ |
1808 | for (i = 0; i < groups_per_page; i++) { | 1811 | for (i = 0; i < groups_per_page; i++) { |
1809 | 1812 | ||
1810 | if ((first_group + i) >= EXT4_SB(sb)->s_groups_count) | 1813 | if ((first_group + i) >= ngroups) |
1811 | break; | 1814 | break; |
1812 | grp = ext4_get_group_info(sb, first_group + i); | 1815 | grp = ext4_get_group_info(sb, first_group + i); |
1813 | /* take all groups write allocation | 1816 | /* take all groups write allocation |
@@ -1945,8 +1948,7 @@ err: | |||
1945 | static noinline_for_stack int | 1948 | static noinline_for_stack int |
1946 | ext4_mb_regular_allocator(struct ext4_allocation_context *ac) | 1949 | ext4_mb_regular_allocator(struct ext4_allocation_context *ac) |
1947 | { | 1950 | { |
1948 | ext4_group_t group; | 1951 | ext4_group_t ngroups, group, i; |
1949 | ext4_group_t i; | ||
1950 | int cr; | 1952 | int cr; |
1951 | int err = 0; | 1953 | int err = 0; |
1952 | int bsbits; | 1954 | int bsbits; |
@@ -1957,6 +1959,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) | |||
1957 | 1959 | ||
1958 | sb = ac->ac_sb; | 1960 | sb = ac->ac_sb; |
1959 | sbi = EXT4_SB(sb); | 1961 | sbi = EXT4_SB(sb); |
1962 | ngroups = ext4_get_groups_count(sb); | ||
1960 | BUG_ON(ac->ac_status == AC_STATUS_FOUND); | 1963 | BUG_ON(ac->ac_status == AC_STATUS_FOUND); |
1961 | 1964 | ||
1962 | /* first, try the goal */ | 1965 | /* first, try the goal */ |
@@ -2017,11 +2020,11 @@ repeat: | |||
2017 | */ | 2020 | */ |
2018 | group = ac->ac_g_ex.fe_group; | 2021 | group = ac->ac_g_ex.fe_group; |
2019 | 2022 | ||
2020 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; group++, i++) { | 2023 | for (i = 0; i < ngroups; group++, i++) { |
2021 | struct ext4_group_info *grp; | 2024 | struct ext4_group_info *grp; |
2022 | struct ext4_group_desc *desc; | 2025 | struct ext4_group_desc *desc; |
2023 | 2026 | ||
2024 | if (group == EXT4_SB(sb)->s_groups_count) | 2027 | if (group == ngroups) |
2025 | group = 0; | 2028 | group = 0; |
2026 | 2029 | ||
2027 | /* quick check to skip empty groups */ | 2030 | /* quick check to skip empty groups */ |
@@ -2315,12 +2318,10 @@ static struct file_operations ext4_mb_seq_history_fops = { | |||
2315 | static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos) | 2318 | static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos) |
2316 | { | 2319 | { |
2317 | struct super_block *sb = seq->private; | 2320 | struct super_block *sb = seq->private; |
2318 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
2319 | ext4_group_t group; | 2321 | ext4_group_t group; |
2320 | 2322 | ||
2321 | if (*pos < 0 || *pos >= sbi->s_groups_count) | 2323 | if (*pos < 0 || *pos >= ext4_get_groups_count(sb)) |
2322 | return NULL; | 2324 | return NULL; |
2323 | |||
2324 | group = *pos + 1; | 2325 | group = *pos + 1; |
2325 | return (void *) ((unsigned long) group); | 2326 | return (void *) ((unsigned long) group); |
2326 | } | 2327 | } |
@@ -2328,11 +2329,10 @@ static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos) | |||
2328 | static void *ext4_mb_seq_groups_next(struct seq_file *seq, void *v, loff_t *pos) | 2329 | static void *ext4_mb_seq_groups_next(struct seq_file *seq, void *v, loff_t *pos) |
2329 | { | 2330 | { |
2330 | struct super_block *sb = seq->private; | 2331 | struct super_block *sb = seq->private; |
2331 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
2332 | ext4_group_t group; | 2332 | ext4_group_t group; |
2333 | 2333 | ||
2334 | ++*pos; | 2334 | ++*pos; |
2335 | if (*pos < 0 || *pos >= sbi->s_groups_count) | 2335 | if (*pos < 0 || *pos >= ext4_get_groups_count(sb)) |
2336 | return NULL; | 2336 | return NULL; |
2337 | group = *pos + 1; | 2337 | group = *pos + 1; |
2338 | return (void *) ((unsigned long) group); | 2338 | return (void *) ((unsigned long) group); |
@@ -2587,6 +2587,7 @@ void ext4_mb_update_group_info(struct ext4_group_info *grp, ext4_grpblk_t add) | |||
2587 | 2587 | ||
2588 | static int ext4_mb_init_backend(struct super_block *sb) | 2588 | static int ext4_mb_init_backend(struct super_block *sb) |
2589 | { | 2589 | { |
2590 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
2590 | ext4_group_t i; | 2591 | ext4_group_t i; |
2591 | int metalen; | 2592 | int metalen; |
2592 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2593 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
@@ -2598,7 +2599,7 @@ static int ext4_mb_init_backend(struct super_block *sb) | |||
2598 | struct ext4_group_desc *desc; | 2599 | struct ext4_group_desc *desc; |
2599 | 2600 | ||
2600 | /* This is the number of blocks used by GDT */ | 2601 | /* This is the number of blocks used by GDT */ |
2601 | num_meta_group_infos = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - | 2602 | num_meta_group_infos = (ngroups + EXT4_DESC_PER_BLOCK(sb) - |
2602 | 1) >> EXT4_DESC_PER_BLOCK_BITS(sb); | 2603 | 1) >> EXT4_DESC_PER_BLOCK_BITS(sb); |
2603 | 2604 | ||
2604 | /* | 2605 | /* |
@@ -2644,7 +2645,7 @@ static int ext4_mb_init_backend(struct super_block *sb) | |||
2644 | for (i = 0; i < num_meta_group_infos; i++) { | 2645 | for (i = 0; i < num_meta_group_infos; i++) { |
2645 | if ((i + 1) == num_meta_group_infos) | 2646 | if ((i + 1) == num_meta_group_infos) |
2646 | metalen = sizeof(*meta_group_info) * | 2647 | metalen = sizeof(*meta_group_info) * |
2647 | (sbi->s_groups_count - | 2648 | (ngroups - |
2648 | (i << EXT4_DESC_PER_BLOCK_BITS(sb))); | 2649 | (i << EXT4_DESC_PER_BLOCK_BITS(sb))); |
2649 | meta_group_info = kmalloc(metalen, GFP_KERNEL); | 2650 | meta_group_info = kmalloc(metalen, GFP_KERNEL); |
2650 | if (meta_group_info == NULL) { | 2651 | if (meta_group_info == NULL) { |
@@ -2655,7 +2656,7 @@ static int ext4_mb_init_backend(struct super_block *sb) | |||
2655 | sbi->s_group_info[i] = meta_group_info; | 2656 | sbi->s_group_info[i] = meta_group_info; |
2656 | } | 2657 | } |
2657 | 2658 | ||
2658 | for (i = 0; i < sbi->s_groups_count; i++) { | 2659 | for (i = 0; i < ngroups; i++) { |
2659 | desc = ext4_get_group_desc(sb, i, NULL); | 2660 | desc = ext4_get_group_desc(sb, i, NULL); |
2660 | if (desc == NULL) { | 2661 | if (desc == NULL) { |
2661 | printk(KERN_ERR | 2662 | printk(KERN_ERR |
@@ -2781,13 +2782,14 @@ static void ext4_mb_cleanup_pa(struct ext4_group_info *grp) | |||
2781 | 2782 | ||
2782 | int ext4_mb_release(struct super_block *sb) | 2783 | int ext4_mb_release(struct super_block *sb) |
2783 | { | 2784 | { |
2785 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
2784 | ext4_group_t i; | 2786 | ext4_group_t i; |
2785 | int num_meta_group_infos; | 2787 | int num_meta_group_infos; |
2786 | struct ext4_group_info *grinfo; | 2788 | struct ext4_group_info *grinfo; |
2787 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2789 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
2788 | 2790 | ||
2789 | if (sbi->s_group_info) { | 2791 | if (sbi->s_group_info) { |
2790 | for (i = 0; i < sbi->s_groups_count; i++) { | 2792 | for (i = 0; i < ngroups; i++) { |
2791 | grinfo = ext4_get_group_info(sb, i); | 2793 | grinfo = ext4_get_group_info(sb, i); |
2792 | #ifdef DOUBLE_CHECK | 2794 | #ifdef DOUBLE_CHECK |
2793 | kfree(grinfo->bb_bitmap); | 2795 | kfree(grinfo->bb_bitmap); |
@@ -2797,7 +2799,7 @@ int ext4_mb_release(struct super_block *sb) | |||
2797 | ext4_unlock_group(sb, i); | 2799 | ext4_unlock_group(sb, i); |
2798 | kfree(grinfo); | 2800 | kfree(grinfo); |
2799 | } | 2801 | } |
2800 | num_meta_group_infos = (sbi->s_groups_count + | 2802 | num_meta_group_infos = (ngroups + |
2801 | EXT4_DESC_PER_BLOCK(sb) - 1) >> | 2803 | EXT4_DESC_PER_BLOCK(sb) - 1) >> |
2802 | EXT4_DESC_PER_BLOCK_BITS(sb); | 2804 | EXT4_DESC_PER_BLOCK_BITS(sb); |
2803 | for (i = 0; i < num_meta_group_infos; i++) | 2805 | for (i = 0; i < num_meta_group_infos; i++) |
@@ -4121,7 +4123,7 @@ static void ext4_mb_return_to_preallocation(struct inode *inode, | |||
4121 | static void ext4_mb_show_ac(struct ext4_allocation_context *ac) | 4123 | static void ext4_mb_show_ac(struct ext4_allocation_context *ac) |
4122 | { | 4124 | { |
4123 | struct super_block *sb = ac->ac_sb; | 4125 | struct super_block *sb = ac->ac_sb; |
4124 | ext4_group_t i; | 4126 | ext4_group_t ngroups, i; |
4125 | 4127 | ||
4126 | printk(KERN_ERR "EXT4-fs: Can't allocate:" | 4128 | printk(KERN_ERR "EXT4-fs: Can't allocate:" |
4127 | " Allocation context details:\n"); | 4129 | " Allocation context details:\n"); |
@@ -4145,7 +4147,8 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac) | |||
4145 | printk(KERN_ERR "EXT4-fs: %lu scanned, %d found\n", ac->ac_ex_scanned, | 4147 | printk(KERN_ERR "EXT4-fs: %lu scanned, %d found\n", ac->ac_ex_scanned, |
4146 | ac->ac_found); | 4148 | ac->ac_found); |
4147 | printk(KERN_ERR "EXT4-fs: groups: \n"); | 4149 | printk(KERN_ERR "EXT4-fs: groups: \n"); |
4148 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { | 4150 | ngroups = ext4_get_groups_count(sb); |
4151 | for (i = 0; i < ngroups; i++) { | ||
4149 | struct ext4_group_info *grp = ext4_get_group_info(sb, i); | 4152 | struct ext4_group_info *grp = ext4_get_group_info(sb, i); |
4150 | struct ext4_prealloc_space *pa; | 4153 | struct ext4_prealloc_space *pa; |
4151 | ext4_grpblk_t start; | 4154 | ext4_grpblk_t start; |
@@ -4469,13 +4472,13 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac) | |||
4469 | 4472 | ||
4470 | static int ext4_mb_discard_preallocations(struct super_block *sb, int needed) | 4473 | static int ext4_mb_discard_preallocations(struct super_block *sb, int needed) |
4471 | { | 4474 | { |
4472 | ext4_group_t i; | 4475 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
4473 | int ret; | 4476 | int ret; |
4474 | int freed = 0; | 4477 | int freed = 0; |
4475 | 4478 | ||
4476 | trace_mark(ext4_mb_discard_preallocations, "dev %s needed %d", | 4479 | trace_mark(ext4_mb_discard_preallocations, "dev %s needed %d", |
4477 | sb->s_id, needed); | 4480 | sb->s_id, needed); |
4478 | for (i = 0; i < EXT4_SB(sb)->s_groups_count && needed > 0; i++) { | 4481 | for (i = 0; i < ngroups && needed > 0; i++) { |
4479 | ret = ext4_mb_discard_group_preallocations(sb, i, needed); | 4482 | ret = ext4_mb_discard_group_preallocations(sb, i, needed); |
4480 | freed += ret; | 4483 | freed += ret; |
4481 | needed -= ret; | 4484 | needed -= ret; |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 68c3a44c4a97..fcd7b24c6df3 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -3557,9 +3557,8 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
3557 | if (test_opt(sb, MINIX_DF)) { | 3557 | if (test_opt(sb, MINIX_DF)) { |
3558 | sbi->s_overhead_last = 0; | 3558 | sbi->s_overhead_last = 0; |
3559 | } else if (sbi->s_blocks_last != ext4_blocks_count(es)) { | 3559 | } else if (sbi->s_blocks_last != ext4_blocks_count(es)) { |
3560 | ext4_group_t ngroups = sbi->s_groups_count, i; | 3560 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
3561 | ext4_fsblk_t overhead = 0; | 3561 | ext4_fsblk_t overhead = 0; |
3562 | smp_rmb(); | ||
3563 | 3562 | ||
3564 | /* | 3563 | /* |
3565 | * Compute the overhead (FS structures). This is constant | 3564 | * Compute the overhead (FS structures). This is constant |