diff options
| -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; |
