ext4: Use struct flex_groups to calculate get_orlov_stats()
Instead of looping over all of the block groups in a flex group summing their summary statistics, start tracking used_dirs in struct flex_groups, and use struct flex_groups instead. This should save a bit of CPU for mkdir-heavy workloads. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
parent
9f24e4208f
commit
7d39db14a4
@ -172,6 +172,7 @@ struct ext4_group_desc
|
|||||||
struct flex_groups {
|
struct flex_groups {
|
||||||
atomic_t free_inodes;
|
atomic_t free_inodes;
|
||||||
atomic_t free_blocks;
|
atomic_t free_blocks;
|
||||||
|
atomic_t used_dirs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */
|
#define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */
|
||||||
|
@ -267,6 +267,13 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
|
|||||||
if (is_directory) {
|
if (is_directory) {
|
||||||
count = ext4_used_dirs_count(sb, gdp) - 1;
|
count = ext4_used_dirs_count(sb, gdp) - 1;
|
||||||
ext4_used_dirs_set(sb, gdp, count);
|
ext4_used_dirs_set(sb, gdp, count);
|
||||||
|
if (sbi->s_log_groups_per_flex) {
|
||||||
|
ext4_group_t f;
|
||||||
|
|
||||||
|
f = ext4_flex_group(sbi, block_group);
|
||||||
|
atomic_dec(&sbi->s_flex_groups[f].free_inodes);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
gdp->bg_checksum = ext4_group_desc_csum(sbi,
|
gdp->bg_checksum = ext4_group_desc_csum(sbi,
|
||||||
block_group, gdp);
|
block_group, gdp);
|
||||||
@ -424,25 +431,24 @@ void get_orlov_stats(struct super_block *sb, ext4_group_t g,
|
|||||||
int flex_size, struct orlov_stats *stats)
|
int flex_size, struct orlov_stats *stats)
|
||||||
{
|
{
|
||||||
struct ext4_group_desc *desc;
|
struct ext4_group_desc *desc;
|
||||||
ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
|
struct flex_groups *flex_group = EXT4_SB(sb)->s_flex_groups;
|
||||||
int i;
|
|
||||||
|
|
||||||
|
if (flex_size > 1) {
|
||||||
|
stats->free_inodes = atomic_read(&flex_group[g].free_inodes);
|
||||||
|
stats->free_blocks = atomic_read(&flex_group[g].free_blocks);
|
||||||
|
stats->used_dirs = atomic_read(&flex_group[g].used_dirs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc = ext4_get_group_desc(sb, g, NULL);
|
||||||
|
if (desc) {
|
||||||
|
stats->free_inodes = ext4_free_inodes_count(sb, desc);
|
||||||
|
stats->free_blocks = ext4_free_blks_count(sb, desc);
|
||||||
|
stats->used_dirs = ext4_used_dirs_count(sb, desc);
|
||||||
|
} else {
|
||||||
stats->free_inodes = 0;
|
stats->free_inodes = 0;
|
||||||
stats->free_blocks = 0;
|
stats->free_blocks = 0;
|
||||||
stats->used_dirs = 0;
|
stats->used_dirs = 0;
|
||||||
|
|
||||||
g *= flex_size;
|
|
||||||
|
|
||||||
for (i = 0; i < flex_size; i++) {
|
|
||||||
if (g >= ngroups)
|
|
||||||
break;
|
|
||||||
desc = ext4_get_group_desc(sb, g++, NULL);
|
|
||||||
if (!desc)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
stats->free_inodes += ext4_free_inodes_count(sb, desc);
|
|
||||||
stats->free_blocks += ext4_free_blks_count(sb, desc);
|
|
||||||
stats->used_dirs += ext4_used_dirs_count(sb, desc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -765,6 +771,11 @@ static int ext4_claim_inode(struct super_block *sb,
|
|||||||
if (S_ISDIR(mode)) {
|
if (S_ISDIR(mode)) {
|
||||||
count = ext4_used_dirs_count(sb, gdp) + 1;
|
count = ext4_used_dirs_count(sb, gdp) + 1;
|
||||||
ext4_used_dirs_set(sb, gdp, count);
|
ext4_used_dirs_set(sb, gdp, count);
|
||||||
|
if (sbi->s_log_groups_per_flex) {
|
||||||
|
ext4_group_t f = ext4_flex_group(sbi, group);
|
||||||
|
|
||||||
|
atomic_inc(&sbi->s_flex_groups[f].free_inodes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
|
gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
|
||||||
err_ret:
|
err_ret:
|
||||||
|
@ -1634,6 +1634,8 @@ static int ext4_fill_flex_info(struct super_block *sb)
|
|||||||
ext4_free_inodes_count(sb, gdp));
|
ext4_free_inodes_count(sb, gdp));
|
||||||
atomic_set(&sbi->s_flex_groups[flex_group].free_blocks,
|
atomic_set(&sbi->s_flex_groups[flex_group].free_blocks,
|
||||||
ext4_free_blks_count(sb, gdp));
|
ext4_free_blks_count(sb, gdp));
|
||||||
|
atomic_set(&sbi->s_flex_groups[flex_group].used_dirs,
|
||||||
|
ext4_used_dirs_count(sb, gdp));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user