Commit 7d39db14 authored by Theodore Ts'o's avatar Theodore Ts'o

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: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 9f24e420
...@@ -172,6 +172,7 @@ struct ext4_group_desc ...@@ -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) ...@@ -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, ...@@ -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;
stats->free_inodes = 0;
stats->free_blocks = 0;
stats->used_dirs = 0;
g *= flex_size; if (flex_size > 1) {
stats->free_inodes = atomic_read(&flex_group[g].free_inodes);
for (i = 0; i < flex_size; i++) { stats->free_blocks = atomic_read(&flex_group[g].free_blocks);
if (g >= ngroups) stats->used_dirs = atomic_read(&flex_group[g].used_dirs);
break; return;
desc = ext4_get_group_desc(sb, g++, NULL); }
if (!desc)
continue;
stats->free_inodes += ext4_free_inodes_count(sb, desc); desc = ext4_get_group_desc(sb, g, NULL);
stats->free_blocks += ext4_free_blks_count(sb, desc); if (desc) {
stats->used_dirs += ext4_used_dirs_count(sb, 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_blocks = 0;
stats->used_dirs = 0;
} }
} }
...@@ -765,6 +771,11 @@ static int ext4_claim_inode(struct super_block *sb, ...@@ -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) ...@@ -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;
......
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