aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2009-01-05 22:20:24 -0500
committerTheodore Ts'o <tytso@mit.edu>2009-01-05 22:20:24 -0500
commit560671a0d3c9ad2d647fa6d09375a262e1f19c4f (patch)
treea52673326726062d53b35643d51a16739cd804fc
parente8134b27e351e813414da3b95aa8eac6d3908088 (diff)
ext4: Use high 16 bits of the block group descriptor's free counts fields
Rename the lower bits with suffix _lo and add helper to access the values. Also rename bg_itable_unused_hi to bg_pad as in e2fsprogs. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/ext4/balloc.c13
-rw-r--r--fs/ext4/ext4.h26
-rw-r--r--fs/ext4/ialloc.c83
-rw-r--r--fs/ext4/inode.c2
-rw-r--r--fs/ext4/mballoc.c15
-rw-r--r--fs/ext4/resize.c4
-rw-r--r--fs/ext4/super.c68
7 files changed, 149 insertions, 62 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 404d81cc9157..902bf66c8dfb 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -102,9 +102,9 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
102 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { 102 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
103 ext4_error(sb, __func__, 103 ext4_error(sb, __func__,
104 "Checksum bad for group %u", block_group); 104 "Checksum bad for group %u", block_group);
105 gdp->bg_free_blocks_count = 0; 105 ext4_free_blks_set(sb, gdp, 0);
106 gdp->bg_free_inodes_count = 0; 106 ext4_free_inodes_set(sb, gdp, 0);
107 gdp->bg_itable_unused = 0; 107 ext4_itable_unused_set(sb, gdp, 0);
108 memset(bh->b_data, 0xff, sb->s_blocksize); 108 memset(bh->b_data, 0xff, sb->s_blocksize);
109 return 0; 109 return 0;
110 } 110 }
@@ -372,7 +372,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
372 struct ext4_group_desc *desc; 372 struct ext4_group_desc *desc;
373 struct ext4_super_block *es; 373 struct ext4_super_block *es;
374 struct ext4_sb_info *sbi; 374 struct ext4_sb_info *sbi;
375 int err = 0, ret; 375 int err = 0, ret, blk_free_count;
376 ext4_grpblk_t blocks_freed; 376 ext4_grpblk_t blocks_freed;
377 struct ext4_group_info *grp; 377 struct ext4_group_info *grp;
378 378
@@ -444,7 +444,8 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
444 } 444 }
445 } 445 }
446 spin_lock(sb_bgl_lock(sbi, block_group)); 446 spin_lock(sb_bgl_lock(sbi, block_group));
447 le16_add_cpu(&desc->bg_free_blocks_count, blocks_freed); 447 blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc);
448 ext4_free_blks_set(sb, desc, blk_free_count);
448 desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); 449 desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
449 spin_unlock(sb_bgl_lock(sbi, block_group)); 450 spin_unlock(sb_bgl_lock(sbi, block_group));
450 percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed); 451 percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed);
@@ -685,7 +686,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
685 gdp = ext4_get_group_desc(sb, i, NULL); 686 gdp = ext4_get_group_desc(sb, i, NULL);
686 if (!gdp) 687 if (!gdp)
687 continue; 688 continue;
688 desc_count += le16_to_cpu(gdp->bg_free_blocks_count); 689 desc_count += ext4_free_blks_count(sb, gdp);
689 } 690 }
690 691
691 return desc_count; 692 return desc_count;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index f0b1db6acf85..ec862f4ca89f 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -156,12 +156,12 @@ struct ext4_group_desc
156 __le32 bg_block_bitmap_lo; /* Blocks bitmap block */ 156 __le32 bg_block_bitmap_lo; /* Blocks bitmap block */
157 __le32 bg_inode_bitmap_lo; /* Inodes bitmap block */ 157 __le32 bg_inode_bitmap_lo; /* Inodes bitmap block */
158 __le32 bg_inode_table_lo; /* Inodes table block */ 158 __le32 bg_inode_table_lo; /* Inodes table block */
159 __le16 bg_free_blocks_count; /* Free blocks count */ 159 __le16 bg_free_blocks_count_lo;/* Free blocks count */
160 __le16 bg_free_inodes_count; /* Free inodes count */ 160 __le16 bg_free_inodes_count_lo;/* Free inodes count */
161 __le16 bg_used_dirs_count; /* Directories count */ 161 __le16 bg_used_dirs_count_lo; /* Directories count */
162 __le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */ 162 __le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
163 __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */ 163 __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */
164 __le16 bg_itable_unused; /* Unused inodes count */ 164 __le16 bg_itable_unused_lo; /* Unused inodes count */
165 __le16 bg_checksum; /* crc16(sb_uuid+group+desc) */ 165 __le16 bg_checksum; /* crc16(sb_uuid+group+desc) */
166 __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ 166 __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
167 __le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */ 167 __le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */
@@ -169,7 +169,7 @@ struct ext4_group_desc
169 __le16 bg_free_blocks_count_hi;/* Free blocks count MSB */ 169 __le16 bg_free_blocks_count_hi;/* Free blocks count MSB */
170 __le16 bg_free_inodes_count_hi;/* Free inodes count MSB */ 170 __le16 bg_free_inodes_count_hi;/* Free inodes count MSB */
171 __le16 bg_used_dirs_count_hi; /* Directories count MSB */ 171 __le16 bg_used_dirs_count_hi; /* Directories count MSB */
172 __le16 bg_itable_unused_hi; /* Unused inodes count MSB */ 172 __le16 bg_itable_unused_hi; /* Unused inodes count MSB */
173 __u32 bg_reserved2[3]; 173 __u32 bg_reserved2[3];
174}; 174};
175 175
@@ -1142,12 +1142,28 @@ extern ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb,
1142 struct ext4_group_desc *bg); 1142 struct ext4_group_desc *bg);
1143extern ext4_fsblk_t ext4_inode_table(struct super_block *sb, 1143extern ext4_fsblk_t ext4_inode_table(struct super_block *sb,
1144 struct ext4_group_desc *bg); 1144 struct ext4_group_desc *bg);
1145extern __u32 ext4_free_blks_count(struct super_block *sb,
1146 struct ext4_group_desc *bg);
1147extern __u32 ext4_free_inodes_count(struct super_block *sb,
1148 struct ext4_group_desc *bg);
1149extern __u32 ext4_used_dirs_count(struct super_block *sb,
1150 struct ext4_group_desc *bg);
1151extern __u32 ext4_itable_unused_count(struct super_block *sb,
1152 struct ext4_group_desc *bg);
1145extern void ext4_block_bitmap_set(struct super_block *sb, 1153extern void ext4_block_bitmap_set(struct super_block *sb,
1146 struct ext4_group_desc *bg, ext4_fsblk_t blk); 1154 struct ext4_group_desc *bg, ext4_fsblk_t blk);
1147extern void ext4_inode_bitmap_set(struct super_block *sb, 1155extern void ext4_inode_bitmap_set(struct super_block *sb,
1148 struct ext4_group_desc *bg, ext4_fsblk_t blk); 1156 struct ext4_group_desc *bg, ext4_fsblk_t blk);
1149extern void ext4_inode_table_set(struct super_block *sb, 1157extern void ext4_inode_table_set(struct super_block *sb,
1150 struct ext4_group_desc *bg, ext4_fsblk_t blk); 1158 struct ext4_group_desc *bg, ext4_fsblk_t blk);
1159extern void ext4_free_blks_set(struct super_block *sb,
1160 struct ext4_group_desc *bg, __u32 count);
1161extern void ext4_free_inodes_set(struct super_block *sb,
1162 struct ext4_group_desc *bg, __u32 count);
1163extern void ext4_used_dirs_set(struct super_block *sb,
1164 struct ext4_group_desc *bg, __u32 count);
1165extern void ext4_itable_unused_set(struct super_block *sb,
1166 struct ext4_group_desc *bg, __u32 count);
1151 1167
1152static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) 1168static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
1153{ 1169{
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index cac3617ec780..11c4f6f5bd61 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -76,9 +76,9 @@ unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh,
76 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { 76 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
77 ext4_error(sb, __func__, "Checksum bad for group %u", 77 ext4_error(sb, __func__, "Checksum bad for group %u",
78 block_group); 78 block_group);
79 gdp->bg_free_blocks_count = 0; 79 ext4_free_blks_set(sb, gdp, 0);
80 gdp->bg_free_inodes_count = 0; 80 ext4_free_inodes_set(sb, gdp, 0);
81 gdp->bg_itable_unused = 0; 81 ext4_itable_unused_set(sb, gdp, 0);
82 memset(bh->b_data, 0xff, sb->s_blocksize); 82 memset(bh->b_data, 0xff, sb->s_blocksize);
83 return 0; 83 return 0;
84 } 84 }
@@ -168,7 +168,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
168 struct ext4_group_desc *gdp; 168 struct ext4_group_desc *gdp;
169 struct ext4_super_block *es; 169 struct ext4_super_block *es;
170 struct ext4_sb_info *sbi; 170 struct ext4_sb_info *sbi;
171 int fatal = 0, err; 171 int fatal = 0, err, count;
172 ext4_group_t flex_group; 172 ext4_group_t flex_group;
173 173
174 if (atomic_read(&inode->i_count) > 1) { 174 if (atomic_read(&inode->i_count) > 1) {
@@ -236,9 +236,12 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
236 236
237 if (gdp) { 237 if (gdp) {
238 spin_lock(sb_bgl_lock(sbi, block_group)); 238 spin_lock(sb_bgl_lock(sbi, block_group));
239 le16_add_cpu(&gdp->bg_free_inodes_count, 1); 239 count = ext4_free_inodes_count(sb, gdp) + 1;
240 if (is_directory) 240 ext4_free_inodes_set(sb, gdp, count);
241 le16_add_cpu(&gdp->bg_used_dirs_count, -1); 241 if (is_directory) {
242 count = ext4_used_dirs_count(sb, gdp) - 1;
243 ext4_used_dirs_set(sb, gdp, count);
244 }
242 gdp->bg_checksum = ext4_group_desc_csum(sbi, 245 gdp->bg_checksum = ext4_group_desc_csum(sbi,
243 block_group, gdp); 246 block_group, gdp);
244 spin_unlock(sb_bgl_lock(sbi, block_group)); 247 spin_unlock(sb_bgl_lock(sbi, block_group));
@@ -291,13 +294,13 @@ static int find_group_dir(struct super_block *sb, struct inode *parent,
291 294
292 for (group = 0; group < ngroups; group++) { 295 for (group = 0; group < ngroups; group++) {
293 desc = ext4_get_group_desc(sb, group, NULL); 296 desc = ext4_get_group_desc(sb, group, NULL);
294 if (!desc || !desc->bg_free_inodes_count) 297 if (!desc || !ext4_free_inodes_count(sb, desc))
295 continue; 298 continue;
296 if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei) 299 if (ext4_free_inodes_count(sb, desc) < avefreei)
297 continue; 300 continue;
298 if (!best_desc || 301 if (!best_desc ||
299 (le16_to_cpu(desc->bg_free_blocks_count) > 302 (ext4_free_blks_count(sb, desc) >
300 le16_to_cpu(best_desc->bg_free_blocks_count))) { 303 ext4_free_blks_count(sb, best_desc))) {
301 *best_group = group; 304 *best_group = group;
302 best_desc = desc; 305 best_desc = desc;
303 ret = 0; 306 ret = 0;
@@ -369,7 +372,7 @@ found_flexbg:
369 for (i = best_flex * flex_size; i < ngroups && 372 for (i = best_flex * flex_size; i < ngroups &&
370 i < (best_flex + 1) * flex_size; i++) { 373 i < (best_flex + 1) * flex_size; i++) {
371 desc = ext4_get_group_desc(sb, i, &bh); 374 desc = ext4_get_group_desc(sb, i, &bh);
372 if (le16_to_cpu(desc->bg_free_inodes_count)) { 375 if (ext4_free_inodes_count(sb, desc)) {
373 *best_group = i; 376 *best_group = i;
374 goto out; 377 goto out;
375 } 378 }
@@ -443,17 +446,17 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
443 for (i = 0; i < ngroups; i++) { 446 for (i = 0; i < ngroups; i++) {
444 grp = (parent_group + i) % ngroups; 447 grp = (parent_group + i) % ngroups;
445 desc = ext4_get_group_desc(sb, grp, NULL); 448 desc = ext4_get_group_desc(sb, grp, NULL);
446 if (!desc || !desc->bg_free_inodes_count) 449 if (!desc || !ext4_free_inodes_count(sb, desc))
447 continue; 450 continue;
448 if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir) 451 if (ext4_used_dirs_count(sb, desc) >= best_ndir)
449 continue; 452 continue;
450 if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei) 453 if (ext4_free_inodes_count(sb, desc) < avefreei)
451 continue; 454 continue;
452 if (le16_to_cpu(desc->bg_free_blocks_count) < avefreeb) 455 if (ext4_free_blks_count(sb, desc) < avefreeb)
453 continue; 456 continue;
454 *group = grp; 457 *group = grp;
455 ret = 0; 458 ret = 0;
456 best_ndir = le16_to_cpu(desc->bg_used_dirs_count); 459 best_ndir = ext4_used_dirs_count(sb, desc);
457 } 460 }
458 if (ret == 0) 461 if (ret == 0)
459 return ret; 462 return ret;
@@ -479,13 +482,13 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
479 for (i = 0; i < ngroups; i++) { 482 for (i = 0; i < ngroups; i++) {
480 *group = (parent_group + i) % ngroups; 483 *group = (parent_group + i) % ngroups;
481 desc = ext4_get_group_desc(sb, *group, NULL); 484 desc = ext4_get_group_desc(sb, *group, NULL);
482 if (!desc || !desc->bg_free_inodes_count) 485 if (!desc || !ext4_free_inodes_count(sb, desc))
483 continue; 486 continue;
484 if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs) 487 if (ext4_used_dirs_count(sb, desc) >= max_dirs)
485 continue; 488 continue;
486 if (le16_to_cpu(desc->bg_free_inodes_count) < min_inodes) 489 if (ext4_free_inodes_count(sb, desc) < min_inodes)
487 continue; 490 continue;
488 if (le16_to_cpu(desc->bg_free_blocks_count) < min_blocks) 491 if (ext4_free_blks_count(sb, desc) < min_blocks)
489 continue; 492 continue;
490 return 0; 493 return 0;
491 } 494 }
@@ -494,8 +497,8 @@ fallback:
494 for (i = 0; i < ngroups; i++) { 497 for (i = 0; i < ngroups; i++) {
495 *group = (parent_group + i) % ngroups; 498 *group = (parent_group + i) % ngroups;
496 desc = ext4_get_group_desc(sb, *group, NULL); 499 desc = ext4_get_group_desc(sb, *group, NULL);
497 if (desc && desc->bg_free_inodes_count && 500 if (desc && ext4_free_inodes_count(sb, desc) &&
498 le16_to_cpu(desc->bg_free_inodes_count) >= avefreei) 501 ext4_free_inodes_count(sb, desc) >= avefreei)
499 return 0; 502 return 0;
500 } 503 }
501 504
@@ -524,8 +527,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
524 */ 527 */
525 *group = parent_group; 528 *group = parent_group;
526 desc = ext4_get_group_desc(sb, *group, NULL); 529 desc = ext4_get_group_desc(sb, *group, NULL);
527 if (desc && le16_to_cpu(desc->bg_free_inodes_count) && 530 if (desc && ext4_free_inodes_count(sb, desc) &&
528 le16_to_cpu(desc->bg_free_blocks_count)) 531 ext4_free_blks_count(sb, desc))
529 return 0; 532 return 0;
530 533
531 /* 534 /*
@@ -548,8 +551,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
548 if (*group >= ngroups) 551 if (*group >= ngroups)
549 *group -= ngroups; 552 *group -= ngroups;
550 desc = ext4_get_group_desc(sb, *group, NULL); 553 desc = ext4_get_group_desc(sb, *group, NULL);
551 if (desc && le16_to_cpu(desc->bg_free_inodes_count) && 554 if (desc && ext4_free_inodes_count(sb, desc) &&
552 le16_to_cpu(desc->bg_free_blocks_count)) 555 ext4_free_blks_count(sb, desc))
553 return 0; 556 return 0;
554 } 557 }
555 558
@@ -562,7 +565,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
562 if (++*group >= ngroups) 565 if (++*group >= ngroups)
563 *group = 0; 566 *group = 0;
564 desc = ext4_get_group_desc(sb, *group, NULL); 567 desc = ext4_get_group_desc(sb, *group, NULL);
565 if (desc && le16_to_cpu(desc->bg_free_inodes_count)) 568 if (desc && ext4_free_inodes_count(sb, desc))
566 return 0; 569 return 0;
567 } 570 }
568 571
@@ -591,7 +594,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
591 struct ext4_super_block *es; 594 struct ext4_super_block *es;
592 struct ext4_inode_info *ei; 595 struct ext4_inode_info *ei;
593 struct ext4_sb_info *sbi; 596 struct ext4_sb_info *sbi;
594 int ret2, err = 0; 597 int ret2, err = 0, count;
595 struct inode *ret; 598 struct inode *ret;
596 ext4_group_t i; 599 ext4_group_t i;
597 int free = 0; 600 int free = 0;
@@ -718,7 +721,7 @@ got:
718 if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 721 if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
719 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); 722 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
720 free = ext4_free_blocks_after_init(sb, group, gdp); 723 free = ext4_free_blocks_after_init(sb, group, gdp);
721 gdp->bg_free_blocks_count = cpu_to_le16(free); 724 ext4_free_blks_set(sb, gdp, free);
722 gdp->bg_checksum = ext4_group_desc_csum(sbi, group, 725 gdp->bg_checksum = ext4_group_desc_csum(sbi, group,
723 gdp); 726 gdp);
724 } 727 }
@@ -753,7 +756,7 @@ got:
753 free = 0; 756 free = 0;
754 } else { 757 } else {
755 free = EXT4_INODES_PER_GROUP(sb) - 758 free = EXT4_INODES_PER_GROUP(sb) -
756 le16_to_cpu(gdp->bg_itable_unused); 759 ext4_itable_unused_count(sb, gdp);
757 } 760 }
758 761
759 /* 762 /*
@@ -763,13 +766,15 @@ got:
763 * 766 *
764 */ 767 */
765 if (ino > free) 768 if (ino > free)
766 gdp->bg_itable_unused = 769 ext4_itable_unused_set(sb, gdp,
767 cpu_to_le16(EXT4_INODES_PER_GROUP(sb) - ino); 770 (EXT4_INODES_PER_GROUP(sb) - ino));
768 } 771 }
769 772
770 le16_add_cpu(&gdp->bg_free_inodes_count, -1); 773 count = ext4_free_inodes_count(sb, gdp) - 1;
774 ext4_free_inodes_set(sb, gdp, count);
771 if (S_ISDIR(mode)) { 775 if (S_ISDIR(mode)) {
772 le16_add_cpu(&gdp->bg_used_dirs_count, 1); 776 count = ext4_used_dirs_count(sb, gdp) + 1;
777 ext4_used_dirs_set(sb, gdp, count);
773 } 778 }
774 gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); 779 gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
775 spin_unlock(sb_bgl_lock(sbi, group)); 780 spin_unlock(sb_bgl_lock(sbi, group));
@@ -987,7 +992,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
987 gdp = ext4_get_group_desc(sb, i, NULL); 992 gdp = ext4_get_group_desc(sb, i, NULL);
988 if (!gdp) 993 if (!gdp)
989 continue; 994 continue;
990 desc_count += le16_to_cpu(gdp->bg_free_inodes_count); 995 desc_count += ext4_free_inodes_count(sb, gdp);
991 brelse(bitmap_bh); 996 brelse(bitmap_bh);
992 bitmap_bh = ext4_read_inode_bitmap(sb, i); 997 bitmap_bh = ext4_read_inode_bitmap(sb, i);
993 if (!bitmap_bh) 998 if (!bitmap_bh)
@@ -995,7 +1000,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
995 1000
996 x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8); 1001 x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8);
997 printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n", 1002 printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n",
998 i, le16_to_cpu(gdp->bg_free_inodes_count), x); 1003 i, ext4_free_inodes_count(sb, gdp), x);
999 bitmap_count += x; 1004 bitmap_count += x;
1000 } 1005 }
1001 brelse(bitmap_bh); 1006 brelse(bitmap_bh);
@@ -1009,7 +1014,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
1009 gdp = ext4_get_group_desc(sb, i, NULL); 1014 gdp = ext4_get_group_desc(sb, i, NULL);
1010 if (!gdp) 1015 if (!gdp)
1011 continue; 1016 continue;
1012 desc_count += le16_to_cpu(gdp->bg_free_inodes_count); 1017 desc_count += ext4_free_inodes_count(sb, gdp);
1013 cond_resched(); 1018 cond_resched();
1014 } 1019 }
1015 return desc_count; 1020 return desc_count;
@@ -1026,7 +1031,7 @@ unsigned long ext4_count_dirs(struct super_block * sb)
1026 struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL); 1031 struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL);
1027 if (!gdp) 1032 if (!gdp)
1028 continue; 1033 continue;
1029 count += le16_to_cpu(gdp->bg_used_dirs_count); 1034 count += ext4_used_dirs_count(sb, gdp);
1030 } 1035 }
1031 return count; 1036 return count;
1032} 1037}
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index bcd5ffa76c0b..56142accf5cd 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4014,7 +4014,7 @@ make_io:
4014 num = EXT4_INODES_PER_GROUP(sb); 4014 num = EXT4_INODES_PER_GROUP(sb);
4015 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 4015 if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
4016 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) 4016 EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
4017 num -= le16_to_cpu(gdp->bg_itable_unused); 4017 num -= ext4_itable_unused_count(sb, gdp);
4018 table += num / inodes_per_block; 4018 table += num / inodes_per_block;
4019 if (end > table) 4019 if (end > table)
4020 end = table; 4020 end = table;
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index d559a03f3eb2..3809a9348f29 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2515,7 +2515,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
2515 ext4_free_blocks_after_init(sb, group, desc); 2515 ext4_free_blocks_after_init(sb, group, desc);
2516 } else { 2516 } else {
2517 meta_group_info[i]->bb_free = 2517 meta_group_info[i]->bb_free =
2518 le16_to_cpu(desc->bg_free_blocks_count); 2518 ext4_free_blks_count(sb, desc);
2519 } 2519 }
2520 2520
2521 INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list); 2521 INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list);
@@ -3046,12 +3046,12 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
3046 ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len); 3046 ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len);
3047 if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 3047 if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
3048 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); 3048 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
3049 gdp->bg_free_blocks_count = 3049 ext4_free_blks_set(sb, gdp,
3050 cpu_to_le16(ext4_free_blocks_after_init(sb, 3050 ext4_free_blocks_after_init(sb,
3051 ac->ac_b_ex.fe_group, 3051 ac->ac_b_ex.fe_group, gdp));
3052 gdp));
3053 } 3052 }
3054 le16_add_cpu(&gdp->bg_free_blocks_count, -ac->ac_b_ex.fe_len); 3053 len = ext4_free_blks_count(sb, gdp) - ac->ac_b_ex.fe_len;
3054 ext4_free_blks_set(sb, gdp, len);
3055 gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp); 3055 gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
3056 spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group)); 3056 spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
3057 percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len); 3057 percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len);
@@ -4823,7 +4823,8 @@ do_more:
4823 } 4823 }
4824 4824
4825 spin_lock(sb_bgl_lock(sbi, block_group)); 4825 spin_lock(sb_bgl_lock(sbi, block_group));
4826 le16_add_cpu(&gdp->bg_free_blocks_count, count); 4826 ret = ext4_free_blks_count(sb, gdp) + count;
4827 ext4_free_blks_set(sb, gdp, ret);
4827 gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp); 4828 gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
4828 spin_unlock(sb_bgl_lock(sbi, block_group)); 4829 spin_unlock(sb_bgl_lock(sbi, block_group));
4829 percpu_counter_add(&sbi->s_freeblocks_counter, count); 4830 percpu_counter_add(&sbi->s_freeblocks_counter, count);
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 92034d2c8a73..2d24f423fd83 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -866,8 +866,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
866 ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ 866 ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */
867 ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ 867 ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */
868 ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */ 868 ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */
869 gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count); 869 ext4_free_blks_set(sb, gdp, input->free_blocks_count);
870 gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb)); 870 ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
871 gdp->bg_flags |= cpu_to_le16(EXT4_BG_INODE_ZEROED); 871 gdp->bg_flags |= cpu_to_le16(EXT4_BG_INODE_ZEROED);
872 gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp); 872 gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp);
873 873
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 2415e2b09707..a3321bf22311 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -93,6 +93,38 @@ ext4_fsblk_t ext4_inode_table(struct super_block *sb,
93 (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0); 93 (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
94} 94}
95 95
96__u32 ext4_free_blks_count(struct super_block *sb,
97 struct ext4_group_desc *bg)
98{
99 return le16_to_cpu(bg->bg_free_blocks_count_lo) |
100 (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
101 (__u32)le16_to_cpu(bg->bg_free_blocks_count_hi) << 16 : 0);
102}
103
104__u32 ext4_free_inodes_count(struct super_block *sb,
105 struct ext4_group_desc *bg)
106{
107 return le16_to_cpu(bg->bg_free_inodes_count_lo) |
108 (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
109 (__u32)le16_to_cpu(bg->bg_free_inodes_count_hi) << 16 : 0);
110}
111
112__u32 ext4_used_dirs_count(struct super_block *sb,
113 struct ext4_group_desc *bg)
114{
115 return le16_to_cpu(bg->bg_used_dirs_count_lo) |
116 (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
117 (__u32)le16_to_cpu(bg->bg_used_dirs_count_hi) << 16 : 0);
118}
119
120__u32 ext4_itable_unused_count(struct super_block *sb,
121 struct ext4_group_desc *bg)
122{
123 return le16_to_cpu(bg->bg_itable_unused_lo) |
124 (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
125 (__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0);
126}
127
96void ext4_block_bitmap_set(struct super_block *sb, 128void ext4_block_bitmap_set(struct super_block *sb,
97 struct ext4_group_desc *bg, ext4_fsblk_t blk) 129 struct ext4_group_desc *bg, ext4_fsblk_t blk)
98{ 130{
@@ -117,6 +149,38 @@ void ext4_inode_table_set(struct super_block *sb,
117 bg->bg_inode_table_hi = cpu_to_le32(blk >> 32); 149 bg->bg_inode_table_hi = cpu_to_le32(blk >> 32);
118} 150}
119 151
152void ext4_free_blks_set(struct super_block *sb,
153 struct ext4_group_desc *bg, __u32 count)
154{
155 bg->bg_free_blocks_count_lo = cpu_to_le16((__u16)count);
156 if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
157 bg->bg_free_blocks_count_hi = cpu_to_le16(count >> 16);
158}
159
160void ext4_free_inodes_set(struct super_block *sb,
161 struct ext4_group_desc *bg, __u32 count)
162{
163 bg->bg_free_inodes_count_lo = cpu_to_le16((__u16)count);
164 if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
165 bg->bg_free_inodes_count_hi = cpu_to_le16(count >> 16);
166}
167
168void ext4_used_dirs_set(struct super_block *sb,
169 struct ext4_group_desc *bg, __u32 count)
170{
171 bg->bg_used_dirs_count_lo = cpu_to_le16((__u16)count);
172 if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
173 bg->bg_used_dirs_count_hi = cpu_to_le16(count >> 16);
174}
175
176void ext4_itable_unused_set(struct super_block *sb,
177 struct ext4_group_desc *bg, __u32 count)
178{
179 bg->bg_itable_unused_lo = cpu_to_le16((__u16)count);
180 if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
181 bg->bg_itable_unused_hi = cpu_to_le16(count >> 16);
182}
183
120/* 184/*
121 * Wrappers for jbd2_journal_start/end. 185 * Wrappers for jbd2_journal_start/end.
122 * 186 *
@@ -1561,9 +1625,9 @@ static int ext4_fill_flex_info(struct super_block *sb)
1561 1625
1562 flex_group = ext4_flex_group(sbi, i); 1626 flex_group = ext4_flex_group(sbi, i);
1563 sbi->s_flex_groups[flex_group].free_inodes += 1627 sbi->s_flex_groups[flex_group].free_inodes +=
1564 le16_to_cpu(gdp->bg_free_inodes_count); 1628 ext4_free_inodes_count(sb, gdp);
1565 sbi->s_flex_groups[flex_group].free_blocks += 1629 sbi->s_flex_groups[flex_group].free_blocks +=
1566 le16_to_cpu(gdp->bg_free_blocks_count); 1630 ext4_free_blks_count(sb, gdp);
1567 } 1631 }
1568 1632
1569 return 1; 1633 return 1;