diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index adcbfadfcb4c..d0d8c76c7edb 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -2500,19 +2500,19 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2500 | struct super_block *sb = dentry->d_sb; | 2500 | struct super_block *sb = dentry->d_sb; |
2501 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2501 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
2502 | struct ext4_super_block *es = sbi->s_es; | 2502 | struct ext4_super_block *es = sbi->s_es; |
2503 | ext4_fsblk_t overhead; | ||
2504 | int i; | ||
2505 | u64 fsid; | 2503 | u64 fsid; |
2506 | 2504 | ||
2507 | if (test_opt (sb, MINIX_DF)) | 2505 | if (test_opt(sb, MINIX_DF)) { |
2508 | overhead = 0; | 2506 | sbi->s_overhead_last = 0; |
2509 | else { | 2507 | } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) { |
2510 | unsigned long ngroups; | 2508 | unsigned long ngroups = sbi->s_groups_count, i; |
2511 | ngroups = EXT4_SB(sb)->s_groups_count; | 2509 | ext4_fsblk_t overhead = 0; |
2512 | smp_rmb(); | 2510 | smp_rmb(); |
2513 | 2511 | ||
2514 | /* | 2512 | /* |
2515 | * Compute the overhead (FS structures) | 2513 | * Compute the overhead (FS structures). This is constant |
2514 | * for a given filesystem unless the number of block groups | ||
2515 | * changes so we cache the previous value until it does. | ||
2516 | */ | 2516 | */ |
2517 | 2517 | ||
2518 | /* | 2518 | /* |
@@ -2536,18 +2536,23 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2536 | * Every block group has an inode bitmap, a block | 2536 | * Every block group has an inode bitmap, a block |
2537 | * bitmap, and an inode table. | 2537 | * bitmap, and an inode table. |
2538 | */ | 2538 | */ |
2539 | overhead += (ngroups * (2 + EXT4_SB(sb)->s_itb_per_group)); | 2539 | overhead += ngroups * (2 + sbi->s_itb_per_group); |
2540 | sbi->s_overhead_last = overhead; | ||
2541 | smp_wmb(); | ||
2542 | sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count); | ||
2540 | } | 2543 | } |
2541 | 2544 | ||
2542 | buf->f_type = EXT4_SUPER_MAGIC; | 2545 | buf->f_type = EXT4_SUPER_MAGIC; |
2543 | buf->f_bsize = sb->s_blocksize; | 2546 | buf->f_bsize = sb->s_blocksize; |
2544 | buf->f_blocks = ext4_blocks_count(es) - overhead; | 2547 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; |
2545 | buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); | 2548 | buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); |
2549 | es->s_free_blocks_count = cpu_to_le32(buf->f_bfree); | ||
2546 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); | 2550 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); |
2547 | if (buf->f_bfree < ext4_r_blocks_count(es)) | 2551 | if (buf->f_bfree < ext4_r_blocks_count(es)) |
2548 | buf->f_bavail = 0; | 2552 | buf->f_bavail = 0; |
2549 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 2553 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
2550 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); | 2554 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); |
2555 | es->s_free_inodes_count = cpu_to_le32(buf->f_ffree); | ||
2551 | buf->f_namelen = EXT4_NAME_LEN; | 2556 | buf->f_namelen = EXT4_NAME_LEN; |
2552 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | 2557 | fsid = le64_to_cpup((void *)es->s_uuid) ^ |
2553 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | 2558 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); |