Commit 7d39db14a42cbd719c7515b9da8f85a2eb6a0633
1 parent
9f24e4208f
Exists in
master
and in
7 other branches
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>
Showing 3 changed files with 31 additions and 17 deletions Side-by-side Diff
fs/ext4/ext4.h
fs/ext4/ialloc.c
| ... | ... | @@ -267,6 +267,13 @@ |
| 267 | 267 | if (is_directory) { |
| 268 | 268 | count = ext4_used_dirs_count(sb, gdp) - 1; |
| 269 | 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 | 278 | gdp->bg_checksum = ext4_group_desc_csum(sbi, |
| 272 | 279 | block_group, gdp); |
| 273 | 280 | |
| 274 | 281 | |
| ... | ... | @@ -424,25 +431,24 @@ |
| 424 | 431 | int flex_size, struct orlov_stats *stats) |
| 425 | 432 | { |
| 426 | 433 | struct ext4_group_desc *desc; |
| 427 | - ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | |
| 428 | - int i; | |
| 434 | + struct flex_groups *flex_group = EXT4_SB(sb)->s_flex_groups; | |
| 429 | 435 | |
| 430 | - stats->free_inodes = 0; | |
| 431 | - stats->free_blocks = 0; | |
| 432 | - stats->used_dirs = 0; | |
| 436 | + if (flex_size > 1) { | |
| 437 | + stats->free_inodes = atomic_read(&flex_group[g].free_inodes); | |
| 438 | + stats->free_blocks = atomic_read(&flex_group[g].free_blocks); | |
| 439 | + stats->used_dirs = atomic_read(&flex_group[g].used_dirs); | |
| 440 | + return; | |
| 441 | + } | |
| 433 | 442 | |
| 434 | - g *= flex_size; | |
| 435 | - | |
| 436 | - for (i = 0; i < flex_size; i++) { | |
| 437 | - if (g >= ngroups) | |
| 438 | - break; | |
| 439 | - desc = ext4_get_group_desc(sb, g++, NULL); | |
| 440 | - if (!desc) | |
| 441 | - continue; | |
| 442 | - | |
| 443 | - stats->free_inodes += ext4_free_inodes_count(sb, desc); | |
| 444 | - stats->free_blocks += ext4_free_blks_count(sb, desc); | |
| 445 | - stats->used_dirs += ext4_used_dirs_count(sb, desc); | |
| 443 | + desc = ext4_get_group_desc(sb, g, NULL); | |
| 444 | + if (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 @@ |
| 765 | 771 | if (S_ISDIR(mode)) { |
| 766 | 772 | count = ext4_used_dirs_count(sb, gdp) + 1; |
| 767 | 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 | 780 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); |
| 770 | 781 | err_ret: |
fs/ext4/super.c
| ... | ... | @@ -1634,6 +1634,8 @@ |
| 1634 | 1634 | ext4_free_inodes_count(sb, gdp)); |
| 1635 | 1635 | atomic_set(&sbi->s_flex_groups[flex_group].free_blocks, |
| 1636 | 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 | 1641 | return 1; |