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 | |
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')
-rw-r--r-- | fs/ext4/ext4.h | 1 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 45 | ||||
-rw-r--r-- | fs/ext4/super.c | 2 |
3 files changed, 31 insertions, 17 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index e52b48f86ed4..46aaaa2ed4c5 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -172,6 +172,7 @@ struct ext4_group_desc | |||
172 | struct flex_groups { | 172 | struct flex_groups { |
173 | atomic_t free_inodes; | 173 | atomic_t free_inodes; |
174 | atomic_t free_blocks; | 174 | atomic_t free_blocks; |
175 | atomic_t used_dirs; | ||
175 | }; | 176 | }; |
176 | 177 | ||
177 | #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ | 178 | #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 5f393927fd25..47b84e8df568 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) | |||
267 | if (is_directory) { | 267 | if (is_directory) { |
268 | count = ext4_used_dirs_count(sb, gdp) - 1; | 268 | count = ext4_used_dirs_count(sb, gdp) - 1; |
269 | ext4_used_dirs_set(sb, gdp, count); | 269 | ext4_used_dirs_set(sb, gdp, count); |
270 | if (sbi->s_log_groups_per_flex) { | ||
271 | ext4_group_t f; | ||
272 | |||
273 | f = ext4_flex_group(sbi, block_group); | ||
274 | atomic_dec(&sbi->s_flex_groups[f].free_inodes); | ||
275 | } | ||
276 | |||
270 | } | 277 | } |
271 | gdp->bg_checksum = ext4_group_desc_csum(sbi, | 278 | gdp->bg_checksum = ext4_group_desc_csum(sbi, |
272 | block_group, gdp); | 279 | block_group, gdp); |
@@ -424,25 +431,24 @@ void get_orlov_stats(struct super_block *sb, ext4_group_t g, | |||
424 | int flex_size, struct orlov_stats *stats) | 431 | int flex_size, struct orlov_stats *stats) |
425 | { | 432 | { |
426 | struct ext4_group_desc *desc; | 433 | struct ext4_group_desc *desc; |
427 | ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | 434 | struct flex_groups *flex_group = EXT4_SB(sb)->s_flex_groups; |
428 | int i; | ||
429 | |||
430 | stats->free_inodes = 0; | ||
431 | stats->free_blocks = 0; | ||
432 | stats->used_dirs = 0; | ||
433 | 435 | ||
434 | g *= flex_size; | 436 | if (flex_size > 1) { |
435 | 437 | stats->free_inodes = atomic_read(&flex_group[g].free_inodes); | |
436 | for (i = 0; i < flex_size; i++) { | 438 | stats->free_blocks = atomic_read(&flex_group[g].free_blocks); |
437 | if (g >= ngroups) | 439 | stats->used_dirs = atomic_read(&flex_group[g].used_dirs); |
438 | break; | 440 | return; |
439 | desc = ext4_get_group_desc(sb, g++, NULL); | 441 | } |
440 | if (!desc) | ||
441 | continue; | ||
442 | 442 | ||
443 | stats->free_inodes += ext4_free_inodes_count(sb, desc); | 443 | desc = ext4_get_group_desc(sb, g, NULL); |
444 | stats->free_blocks += ext4_free_blks_count(sb, desc); | 444 | if (desc) { |
445 | stats->used_dirs += ext4_used_dirs_count(sb, desc); | 445 | stats->free_inodes = ext4_free_inodes_count(sb, desc); |
446 | stats->free_blocks = ext4_free_blks_count(sb, desc); | ||
447 | stats->used_dirs = ext4_used_dirs_count(sb, desc); | ||
448 | } else { | ||
449 | stats->free_inodes = 0; | ||
450 | stats->free_blocks = 0; | ||
451 | stats->used_dirs = 0; | ||
446 | } | 452 | } |
447 | } | 453 | } |
448 | 454 | ||
@@ -765,6 +771,11 @@ static int ext4_claim_inode(struct super_block *sb, | |||
765 | if (S_ISDIR(mode)) { | 771 | if (S_ISDIR(mode)) { |
766 | count = ext4_used_dirs_count(sb, gdp) + 1; | 772 | count = ext4_used_dirs_count(sb, gdp) + 1; |
767 | ext4_used_dirs_set(sb, gdp, count); | 773 | ext4_used_dirs_set(sb, gdp, count); |
774 | if (sbi->s_log_groups_per_flex) { | ||
775 | ext4_group_t f = ext4_flex_group(sbi, group); | ||
776 | |||
777 | atomic_inc(&sbi->s_flex_groups[f].free_inodes); | ||
778 | } | ||
768 | } | 779 | } |
769 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); | 780 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); |
770 | err_ret: | 781 | err_ret: |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 6b5d5c6399fa..b9aefceb41e7 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1634,6 +1634,8 @@ static int ext4_fill_flex_info(struct super_block *sb) | |||
1634 | ext4_free_inodes_count(sb, gdp)); | 1634 | ext4_free_inodes_count(sb, gdp)); |
1635 | atomic_set(&sbi->s_flex_groups[flex_group].free_blocks, | 1635 | atomic_set(&sbi->s_flex_groups[flex_group].free_blocks, |
1636 | ext4_free_blks_count(sb, gdp)); | 1636 | ext4_free_blks_count(sb, gdp)); |
1637 | atomic_set(&sbi->s_flex_groups[flex_group].used_dirs, | ||
1638 | ext4_used_dirs_count(sb, gdp)); | ||
1637 | } | 1639 | } |
1638 | 1640 | ||
1639 | return 1; | 1641 | return 1; |