diff options
author | Theodore Ts'o <tytso@mit.edu> | 2009-03-04 19:31:53 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-03-04 19:31:53 -0500 |
commit | 7d39db14a42cbd719c7515b9da8f85a2eb6a0633 (patch) | |
tree | 5c93b9f76c9895183d1e973ed296cd9b7a1d9a0e /fs/ext4/ialloc.c | |
parent | 9f24e4208f7ee2748f157368b63287dc903fcf60 (diff) |
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>
Diffstat (limited to 'fs/ext4/ialloc.c')
-rw-r--r-- | fs/ext4/ialloc.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 5f393927fd2..47b84e8df56 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -267,6 +267,13 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) if (is_directory) { count = ext4_used_dirs_count(sb, gdp) - 1; 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, 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) { struct ext4_group_desc *desc; - ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; - int i; - - stats->free_inodes = 0; - stats->free_blocks = 0; - stats->used_dirs = 0; + struct flex_groups *flex_group = EXT4_SB(sb)->s_flex_groups; - 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; + 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; + } - 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); + 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_blocks = 0; + stats->used_dirs = 0; } } @@ -765,6 +771,11 @@ static int ext4_claim_inode(struct super_block *sb, if (S_ISDIR(mode)) { count = ext4_used_dirs_count(sb, gdp) + 1; 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); err_ret: |