Commit 560671a0 authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Theodore Ts'o

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: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent e8134b27
...@@ -102,9 +102,9 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, ...@@ -102,9 +102,9 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
ext4_error(sb, __func__, ext4_error(sb, __func__,
"Checksum bad for group %u", block_group); "Checksum bad for group %u", block_group);
gdp->bg_free_blocks_count = 0; ext4_free_blks_set(sb, gdp, 0);
gdp->bg_free_inodes_count = 0; ext4_free_inodes_set(sb, gdp, 0);
gdp->bg_itable_unused = 0; ext4_itable_unused_set(sb, gdp, 0);
memset(bh->b_data, 0xff, sb->s_blocksize); memset(bh->b_data, 0xff, sb->s_blocksize);
return 0; return 0;
} }
...@@ -372,7 +372,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, ...@@ -372,7 +372,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
struct ext4_group_desc *desc; struct ext4_group_desc *desc;
struct ext4_super_block *es; struct ext4_super_block *es;
struct ext4_sb_info *sbi; struct ext4_sb_info *sbi;
int err = 0, ret; int err = 0, ret, blk_free_count;
ext4_grpblk_t blocks_freed; ext4_grpblk_t blocks_freed;
struct ext4_group_info *grp; struct ext4_group_info *grp;
...@@ -444,7 +444,8 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, ...@@ -444,7 +444,8 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
} }
} }
spin_lock(sb_bgl_lock(sbi, block_group)); spin_lock(sb_bgl_lock(sbi, block_group));
le16_add_cpu(&desc->bg_free_blocks_count, blocks_freed); blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc);
ext4_free_blks_set(sb, desc, blk_free_count);
desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
spin_unlock(sb_bgl_lock(sbi, block_group)); spin_unlock(sb_bgl_lock(sbi, block_group));
percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed); 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,7 +686,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
gdp = ext4_get_group_desc(sb, i, NULL); gdp = ext4_get_group_desc(sb, i, NULL);
if (!gdp) if (!gdp)
continue; continue;
desc_count += le16_to_cpu(gdp->bg_free_blocks_count); desc_count += ext4_free_blks_count(sb, gdp);
} }
return desc_count; return desc_count;
......
...@@ -156,12 +156,12 @@ struct ext4_group_desc ...@@ -156,12 +156,12 @@ struct ext4_group_desc
__le32 bg_block_bitmap_lo; /* Blocks bitmap block */ __le32 bg_block_bitmap_lo; /* Blocks bitmap block */
__le32 bg_inode_bitmap_lo; /* Inodes bitmap block */ __le32 bg_inode_bitmap_lo; /* Inodes bitmap block */
__le32 bg_inode_table_lo; /* Inodes table block */ __le32 bg_inode_table_lo; /* Inodes table block */
__le16 bg_free_blocks_count; /* Free blocks count */ __le16 bg_free_blocks_count_lo;/* Free blocks count */
__le16 bg_free_inodes_count; /* Free inodes count */ __le16 bg_free_inodes_count_lo;/* Free inodes count */
__le16 bg_used_dirs_count; /* Directories count */ __le16 bg_used_dirs_count_lo; /* Directories count */
__le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */ __le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
__u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */ __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */
__le16 bg_itable_unused; /* Unused inodes count */ __le16 bg_itable_unused_lo; /* Unused inodes count */
__le16 bg_checksum; /* crc16(sb_uuid+group+desc) */ __le16 bg_checksum; /* crc16(sb_uuid+group+desc) */
__le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
__le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */ __le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */
...@@ -169,7 +169,7 @@ struct ext4_group_desc ...@@ -169,7 +169,7 @@ struct ext4_group_desc
__le16 bg_free_blocks_count_hi;/* Free blocks count MSB */ __le16 bg_free_blocks_count_hi;/* Free blocks count MSB */
__le16 bg_free_inodes_count_hi;/* Free inodes count MSB */ __le16 bg_free_inodes_count_hi;/* Free inodes count MSB */
__le16 bg_used_dirs_count_hi; /* Directories count MSB */ __le16 bg_used_dirs_count_hi; /* Directories count MSB */
__le16 bg_itable_unused_hi; /* Unused inodes count MSB */ __le16 bg_itable_unused_hi; /* Unused inodes count MSB */
__u32 bg_reserved2[3]; __u32 bg_reserved2[3];
}; };
...@@ -1142,12 +1142,28 @@ extern ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, ...@@ -1142,12 +1142,28 @@ extern ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb,
struct ext4_group_desc *bg); struct ext4_group_desc *bg);
extern ext4_fsblk_t ext4_inode_table(struct super_block *sb, extern ext4_fsblk_t ext4_inode_table(struct super_block *sb,
struct ext4_group_desc *bg); struct ext4_group_desc *bg);
extern __u32 ext4_free_blks_count(struct super_block *sb,
struct ext4_group_desc *bg);
extern __u32 ext4_free_inodes_count(struct super_block *sb,
struct ext4_group_desc *bg);
extern __u32 ext4_used_dirs_count(struct super_block *sb,
struct ext4_group_desc *bg);
extern __u32 ext4_itable_unused_count(struct super_block *sb,
struct ext4_group_desc *bg);
extern void ext4_block_bitmap_set(struct super_block *sb, extern void ext4_block_bitmap_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk); struct ext4_group_desc *bg, ext4_fsblk_t blk);
extern void ext4_inode_bitmap_set(struct super_block *sb, extern void ext4_inode_bitmap_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk); struct ext4_group_desc *bg, ext4_fsblk_t blk);
extern void ext4_inode_table_set(struct super_block *sb, extern void ext4_inode_table_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk); struct ext4_group_desc *bg, ext4_fsblk_t blk);
extern void ext4_free_blks_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count);
extern void ext4_free_inodes_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count);
extern void ext4_used_dirs_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count);
extern void ext4_itable_unused_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count);
static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es)
{ {
......
...@@ -76,9 +76,9 @@ unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh, ...@@ -76,9 +76,9 @@ unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh,
if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
ext4_error(sb, __func__, "Checksum bad for group %u", ext4_error(sb, __func__, "Checksum bad for group %u",
block_group); block_group);
gdp->bg_free_blocks_count = 0; ext4_free_blks_set(sb, gdp, 0);
gdp->bg_free_inodes_count = 0; ext4_free_inodes_set(sb, gdp, 0);
gdp->bg_itable_unused = 0; ext4_itable_unused_set(sb, gdp, 0);
memset(bh->b_data, 0xff, sb->s_blocksize); memset(bh->b_data, 0xff, sb->s_blocksize);
return 0; return 0;
} }
...@@ -168,7 +168,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) ...@@ -168,7 +168,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
struct ext4_group_desc *gdp; struct ext4_group_desc *gdp;
struct ext4_super_block *es; struct ext4_super_block *es;
struct ext4_sb_info *sbi; struct ext4_sb_info *sbi;
int fatal = 0, err; int fatal = 0, err, count;
ext4_group_t flex_group; ext4_group_t flex_group;
if (atomic_read(&inode->i_count) > 1) { if (atomic_read(&inode->i_count) > 1) {
...@@ -236,9 +236,12 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) ...@@ -236,9 +236,12 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
if (gdp) { if (gdp) {
spin_lock(sb_bgl_lock(sbi, block_group)); spin_lock(sb_bgl_lock(sbi, block_group));
le16_add_cpu(&gdp->bg_free_inodes_count, 1); count = ext4_free_inodes_count(sb, gdp) + 1;
if (is_directory) ext4_free_inodes_set(sb, gdp, count);
le16_add_cpu(&gdp->bg_used_dirs_count, -1); if (is_directory) {
count = ext4_used_dirs_count(sb, gdp) - 1;
ext4_used_dirs_set(sb, gdp, count);
}
gdp->bg_checksum = ext4_group_desc_csum(sbi, gdp->bg_checksum = ext4_group_desc_csum(sbi,
block_group, gdp); block_group, gdp);
spin_unlock(sb_bgl_lock(sbi, block_group)); 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,13 +294,13 @@ static int find_group_dir(struct super_block *sb, struct inode *parent,
for (group = 0; group < ngroups; group++) { for (group = 0; group < ngroups; group++) {
desc = ext4_get_group_desc(sb, group, NULL); desc = ext4_get_group_desc(sb, group, NULL);
if (!desc || !desc->bg_free_inodes_count) if (!desc || !ext4_free_inodes_count(sb, desc))
continue; continue;
if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei) if (ext4_free_inodes_count(sb, desc) < avefreei)
continue; continue;
if (!best_desc || if (!best_desc ||
(le16_to_cpu(desc->bg_free_blocks_count) > (ext4_free_blks_count(sb, desc) >
le16_to_cpu(best_desc->bg_free_blocks_count))) { ext4_free_blks_count(sb, best_desc))) {
*best_group = group; *best_group = group;
best_desc = desc; best_desc = desc;
ret = 0; ret = 0;
...@@ -369,7 +372,7 @@ static int find_group_flex(struct super_block *sb, struct inode *parent, ...@@ -369,7 +372,7 @@ static int find_group_flex(struct super_block *sb, struct inode *parent,
for (i = best_flex * flex_size; i < ngroups && for (i = best_flex * flex_size; i < ngroups &&
i < (best_flex + 1) * flex_size; i++) { i < (best_flex + 1) * flex_size; i++) {
desc = ext4_get_group_desc(sb, i, &bh); desc = ext4_get_group_desc(sb, i, &bh);
if (le16_to_cpu(desc->bg_free_inodes_count)) { if (ext4_free_inodes_count(sb, desc)) {
*best_group = i; *best_group = i;
goto out; goto out;
} }
...@@ -443,17 +446,17 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, ...@@ -443,17 +446,17 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
for (i = 0; i < ngroups; i++) { for (i = 0; i < ngroups; i++) {
grp = (parent_group + i) % ngroups; grp = (parent_group + i) % ngroups;
desc = ext4_get_group_desc(sb, grp, NULL); desc = ext4_get_group_desc(sb, grp, NULL);
if (!desc || !desc->bg_free_inodes_count) if (!desc || !ext4_free_inodes_count(sb, desc))
continue; continue;
if (le16_to_cpu(desc->bg_used_dirs_count) >= best_ndir) if (ext4_used_dirs_count(sb, desc) >= best_ndir)
continue; continue;
if (le16_to_cpu(desc->bg_free_inodes_count) < avefreei) if (ext4_free_inodes_count(sb, desc) < avefreei)
continue; continue;
if (le16_to_cpu(desc->bg_free_blocks_count) < avefreeb) if (ext4_free_blks_count(sb, desc) < avefreeb)
continue; continue;
*group = grp; *group = grp;
ret = 0; ret = 0;
best_ndir = le16_to_cpu(desc->bg_used_dirs_count); best_ndir = ext4_used_dirs_count(sb, desc);
} }
if (ret == 0) if (ret == 0)
return ret; return ret;
...@@ -479,13 +482,13 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, ...@@ -479,13 +482,13 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
for (i = 0; i < ngroups; i++) { for (i = 0; i < ngroups; i++) {
*group = (parent_group + i) % ngroups; *group = (parent_group + i) % ngroups;
desc = ext4_get_group_desc(sb, *group, NULL); desc = ext4_get_group_desc(sb, *group, NULL);
if (!desc || !desc->bg_free_inodes_count) if (!desc || !ext4_free_inodes_count(sb, desc))
continue; continue;
if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs) if (ext4_used_dirs_count(sb, desc) >= max_dirs)
continue; continue;
if (le16_to_cpu(desc->bg_free_inodes_count) < min_inodes) if (ext4_free_inodes_count(sb, desc) < min_inodes)
continue; continue;
if (le16_to_cpu(desc->bg_free_blocks_count) < min_blocks) if (ext4_free_blks_count(sb, desc) < min_blocks)
continue; continue;
return 0; return 0;
} }
...@@ -494,8 +497,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, ...@@ -494,8 +497,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
for (i = 0; i < ngroups; i++) { for (i = 0; i < ngroups; i++) {
*group = (parent_group + i) % ngroups; *group = (parent_group + i) % ngroups;
desc = ext4_get_group_desc(sb, *group, NULL); desc = ext4_get_group_desc(sb, *group, NULL);
if (desc && desc->bg_free_inodes_count && if (desc && ext4_free_inodes_count(sb, desc) &&
le16_to_cpu(desc->bg_free_inodes_count) >= avefreei) ext4_free_inodes_count(sb, desc) >= avefreei)
return 0; return 0;
} }
...@@ -524,8 +527,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent, ...@@ -524,8 +527,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
*/ */
*group = parent_group; *group = parent_group;
desc = ext4_get_group_desc(sb, *group, NULL); desc = ext4_get_group_desc(sb, *group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count) && if (desc && ext4_free_inodes_count(sb, desc) &&
le16_to_cpu(desc->bg_free_blocks_count)) ext4_free_blks_count(sb, desc))
return 0; return 0;
/* /*
...@@ -548,8 +551,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent, ...@@ -548,8 +551,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
if (*group >= ngroups) if (*group >= ngroups)
*group -= ngroups; *group -= ngroups;
desc = ext4_get_group_desc(sb, *group, NULL); desc = ext4_get_group_desc(sb, *group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count) && if (desc && ext4_free_inodes_count(sb, desc) &&
le16_to_cpu(desc->bg_free_blocks_count)) ext4_free_blks_count(sb, desc))
return 0; return 0;
} }
...@@ -562,7 +565,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent, ...@@ -562,7 +565,7 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
if (++*group >= ngroups) if (++*group >= ngroups)
*group = 0; *group = 0;
desc = ext4_get_group_desc(sb, *group, NULL); desc = ext4_get_group_desc(sb, *group, NULL);
if (desc && le16_to_cpu(desc->bg_free_inodes_count)) if (desc && ext4_free_inodes_count(sb, desc))
return 0; return 0;
} }
...@@ -591,7 +594,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) ...@@ -591,7 +594,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
struct ext4_super_block *es; struct ext4_super_block *es;
struct ext4_inode_info *ei; struct ext4_inode_info *ei;
struct ext4_sb_info *sbi; struct ext4_sb_info *sbi;
int ret2, err = 0; int ret2, err = 0, count;
struct inode *ret; struct inode *ret;
ext4_group_t i; ext4_group_t i;
int free = 0; int free = 0;
...@@ -718,7 +721,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) ...@@ -718,7 +721,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
free = ext4_free_blocks_after_init(sb, group, gdp); free = ext4_free_blocks_after_init(sb, group, gdp);
gdp->bg_free_blocks_count = cpu_to_le16(free); ext4_free_blks_set(sb, gdp, free);
gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp->bg_checksum = ext4_group_desc_csum(sbi, group,
gdp); gdp);
} }
...@@ -753,7 +756,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) ...@@ -753,7 +756,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
free = 0; free = 0;
} else { } else {
free = EXT4_INODES_PER_GROUP(sb) - free = EXT4_INODES_PER_GROUP(sb) -
le16_to_cpu(gdp->bg_itable_unused); ext4_itable_unused_count(sb, gdp);
} }
/* /*
...@@ -763,13 +766,15 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) ...@@ -763,13 +766,15 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
* *
*/ */
if (ino > free) if (ino > free)
gdp->bg_itable_unused = ext4_itable_unused_set(sb, gdp,
cpu_to_le16(EXT4_INODES_PER_GROUP(sb) - ino); (EXT4_INODES_PER_GROUP(sb) - ino));
} }
le16_add_cpu(&gdp->bg_free_inodes_count, -1); count = ext4_free_inodes_count(sb, gdp) - 1;
ext4_free_inodes_set(sb, gdp, count);
if (S_ISDIR(mode)) { if (S_ISDIR(mode)) {
le16_add_cpu(&gdp->bg_used_dirs_count, 1); count = ext4_used_dirs_count(sb, gdp) + 1;
ext4_used_dirs_set(sb, gdp, count);
} }
gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
spin_unlock(sb_bgl_lock(sbi, group)); spin_unlock(sb_bgl_lock(sbi, group));
...@@ -987,7 +992,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) ...@@ -987,7 +992,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
gdp = ext4_get_group_desc(sb, i, NULL); gdp = ext4_get_group_desc(sb, i, NULL);
if (!gdp) if (!gdp)
continue; continue;
desc_count += le16_to_cpu(gdp->bg_free_inodes_count); desc_count += ext4_free_inodes_count(sb, gdp);
brelse(bitmap_bh); brelse(bitmap_bh);
bitmap_bh = ext4_read_inode_bitmap(sb, i); bitmap_bh = ext4_read_inode_bitmap(sb, i);
if (!bitmap_bh) if (!bitmap_bh)
...@@ -995,7 +1000,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) ...@@ -995,7 +1000,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8); x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8);
printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n", printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n",
i, le16_to_cpu(gdp->bg_free_inodes_count), x); i, ext4_free_inodes_count(sb, gdp), x);
bitmap_count += x; bitmap_count += x;
} }
brelse(bitmap_bh); brelse(bitmap_bh);
...@@ -1009,7 +1014,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) ...@@ -1009,7 +1014,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
gdp = ext4_get_group_desc(sb, i, NULL); gdp = ext4_get_group_desc(sb, i, NULL);
if (!gdp) if (!gdp)
continue; continue;
desc_count += le16_to_cpu(gdp->bg_free_inodes_count); desc_count += ext4_free_inodes_count(sb, gdp);
cond_resched(); cond_resched();
} }
return desc_count; return desc_count;
...@@ -1026,7 +1031,7 @@ unsigned long ext4_count_dirs(struct super_block * sb) ...@@ -1026,7 +1031,7 @@ unsigned long ext4_count_dirs(struct super_block * sb)
struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL); struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL);
if (!gdp) if (!gdp)
continue; continue;
count += le16_to_cpu(gdp->bg_used_dirs_count); count += ext4_used_dirs_count(sb, gdp);
} }
return count; return count;
} }
...@@ -4014,7 +4014,7 @@ static int __ext4_get_inode_loc(struct inode *inode, ...@@ -4014,7 +4014,7 @@ static int __ext4_get_inode_loc(struct inode *inode,
num = EXT4_INODES_PER_GROUP(sb); num = EXT4_INODES_PER_GROUP(sb);
if (EXT4_HAS_RO_COMPAT_FEATURE(sb, if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
num -= le16_to_cpu(gdp->bg_itable_unused); num -= ext4_itable_unused_count(sb, gdp);
table += num / inodes_per_block; table += num / inodes_per_block;
if (end > table) if (end > table)
end = table; end = table;
......
...@@ -2515,7 +2515,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, ...@@ -2515,7 +2515,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
ext4_free_blocks_after_init(sb, group, desc); ext4_free_blocks_after_init(sb, group, desc);
} else { } else {
meta_group_info[i]->bb_free = meta_group_info[i]->bb_free =
le16_to_cpu(desc->bg_free_blocks_count); ext4_free_blks_count(sb, desc);
} }
INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list); 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,12 +3046,12 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len); ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len);
if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
gdp->bg_free_blocks_count = ext4_free_blks_set(sb, gdp,
cpu_to_le16(ext4_free_blocks_after_init(sb, ext4_free_blocks_after_init(sb,
ac->ac_b_ex.fe_group, ac->ac_b_ex.fe_group, gdp));
gdp));
} }
le16_add_cpu(&gdp->bg_free_blocks_count, -ac->ac_b_ex.fe_len); len = ext4_free_blks_count(sb, gdp) - ac->ac_b_ex.fe_len;
ext4_free_blks_set(sb, gdp, len);
gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp); gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group)); spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group));
percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len); percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len);
...@@ -4823,7 +4823,8 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode, ...@@ -4823,7 +4823,8 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode,
} }
spin_lock(sb_bgl_lock(sbi, block_group)); spin_lock(sb_bgl_lock(sbi, block_group));
le16_add_cpu(&gdp->bg_free_blocks_count, count); ret = ext4_free_blks_count(sb, gdp) + count;
ext4_free_blks_set(sb, gdp, ret);
gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp); gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
spin_unlock(sb_bgl_lock(sbi, block_group)); spin_unlock(sb_bgl_lock(sbi, block_group));
percpu_counter_add(&sbi->s_freeblocks_counter, count); percpu_counter_add(&sbi->s_freeblocks_counter, count);
......
...@@ -866,8 +866,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) ...@@ -866,8 +866,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */
ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */
ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */ ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */
gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count); ext4_free_blks_set(sb, gdp, input->free_blocks_count);
gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb)); ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
gdp->bg_flags |= cpu_to_le16(EXT4_BG_INODE_ZEROED); gdp->bg_flags |= cpu_to_le16(EXT4_BG_INODE_ZEROED);
gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp); gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp);
......
...@@ -93,6 +93,38 @@ ext4_fsblk_t ext4_inode_table(struct super_block *sb, ...@@ -93,6 +93,38 @@ ext4_fsblk_t ext4_inode_table(struct super_block *sb,
(ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0); (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0);
} }
__u32 ext4_free_blks_count(struct super_block *sb,
struct ext4_group_desc *bg)
{
return le16_to_cpu(bg->bg_free_blocks_count_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(__u32)le16_to_cpu(bg->bg_free_blocks_count_hi) << 16 : 0);
}
__u32 ext4_free_inodes_count(struct super_block *sb,
struct ext4_group_desc *bg)
{
return le16_to_cpu(bg->bg_free_inodes_count_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(__u32)le16_to_cpu(bg->bg_free_inodes_count_hi) << 16 : 0);
}
__u32 ext4_used_dirs_count(struct super_block *sb,
struct ext4_group_desc *bg)
{
return le16_to_cpu(bg->bg_used_dirs_count_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(__u32)le16_to_cpu(bg->bg_used_dirs_count_hi) << 16 : 0);
}
__u32 ext4_itable_unused_count(struct super_block *sb,
struct ext4_group_desc *bg)
{
return le16_to_cpu(bg->bg_itable_unused_lo) |
(EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ?
(__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0);
}
void ext4_block_bitmap_set(struct super_block *sb, void ext4_block_bitmap_set(struct super_block *sb,
struct ext4_group_desc *bg, ext4_fsblk_t blk) struct ext4_group_desc *bg, ext4_fsblk_t blk)
{ {
...@@ -117,6 +149,38 @@ void ext4_inode_table_set(struct super_block *sb, ...@@ -117,6 +149,38 @@ void ext4_inode_table_set(struct super_block *sb,
bg->bg_inode_table_hi = cpu_to_le32(blk >> 32); bg->bg_inode_table_hi = cpu_to_le32(blk >> 32);
} }
void ext4_free_blks_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count)
{
bg->bg_free_blocks_count_lo = cpu_to_le16((__u16)count);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_free_blocks_count_hi = cpu_to_le16(count >> 16);
}
void ext4_free_inodes_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count)
{
bg->bg_free_inodes_count_lo = cpu_to_le16((__u16)count);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_free_inodes_count_hi = cpu_to_le16(count >> 16);
}
void ext4_used_dirs_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count)
{
bg->bg_used_dirs_count_lo = cpu_to_le16((__u16)count);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_used_dirs_count_hi = cpu_to_le16(count >> 16);
}
void ext4_itable_unused_set(struct super_block *sb,
struct ext4_group_desc *bg, __u32 count)
{
bg->bg_itable_unused_lo = cpu_to_le16((__u16)count);
if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT)
bg->bg_itable_unused_hi = cpu_to_le16(count >> 16);
}
/* /*
* Wrappers for jbd2_journal_start/end. * Wrappers for jbd2_journal_start/end.
* *
...@@ -1561,9 +1625,9 @@ static int ext4_fill_flex_info(struct super_block *sb) ...@@ -1561,9 +1625,9 @@ static int ext4_fill_flex_info(struct super_block *sb)
flex_group = ext4_flex_group(sbi, i); flex_group = ext4_flex_group(sbi, i);
sbi->s_flex_groups[flex_group].free_inodes += sbi->s_flex_groups[flex_group].free_inodes +=
le16_to_cpu(gdp->bg_free_inodes_count); ext4_free_inodes_count(sb, gdp);
sbi->s_flex_groups[flex_group].free_blocks += sbi->s_flex_groups[flex_group].free_blocks +=
le16_to_cpu(gdp->bg_free_blocks_count); ext4_free_blks_count(sb, gdp);
} }
return 1; return 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment