diff options
Diffstat (limited to 'fs/ext3')
-rw-r--r-- | fs/ext3/super.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 8b75f73ba3b4..51d1c456cdab 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -2426,19 +2426,19 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2426 | struct super_block *sb = dentry->d_sb; | 2426 | struct super_block *sb = dentry->d_sb; |
2427 | struct ext3_sb_info *sbi = EXT3_SB(sb); | 2427 | struct ext3_sb_info *sbi = EXT3_SB(sb); |
2428 | struct ext3_super_block *es = sbi->s_es; | 2428 | struct ext3_super_block *es = sbi->s_es; |
2429 | ext3_fsblk_t overhead; | ||
2430 | int i; | ||
2431 | u64 fsid; | 2429 | u64 fsid; |
2432 | 2430 | ||
2433 | if (test_opt (sb, MINIX_DF)) | 2431 | if (test_opt(sb, MINIX_DF)) { |
2434 | overhead = 0; | 2432 | sbi->s_overhead_last = 0; |
2435 | else { | 2433 | } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) { |
2436 | unsigned long ngroups; | 2434 | unsigned long ngroups = sbi->s_groups_count, i; |
2437 | ngroups = EXT3_SB(sb)->s_groups_count; | 2435 | ext3_fsblk_t overhead = 0; |
2438 | smp_rmb(); | 2436 | smp_rmb(); |
2439 | 2437 | ||
2440 | /* | 2438 | /* |
2441 | * Compute the overhead (FS structures) | 2439 | * Compute the overhead (FS structures). This is constant |
2440 | * for a given filesystem unless the number of block groups | ||
2441 | * changes so we cache the previous value until it does. | ||
2442 | */ | 2442 | */ |
2443 | 2443 | ||
2444 | /* | 2444 | /* |
@@ -2462,18 +2462,23 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2462 | * Every block group has an inode bitmap, a block | 2462 | * Every block group has an inode bitmap, a block |
2463 | * bitmap, and an inode table. | 2463 | * bitmap, and an inode table. |
2464 | */ | 2464 | */ |
2465 | overhead += (ngroups * (2 + EXT3_SB(sb)->s_itb_per_group)); | 2465 | overhead += ngroups * (2 + sbi->s_itb_per_group); |
2466 | sbi->s_overhead_last = overhead; | ||
2467 | smp_wmb(); | ||
2468 | sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count); | ||
2466 | } | 2469 | } |
2467 | 2470 | ||
2468 | buf->f_type = EXT3_SUPER_MAGIC; | 2471 | buf->f_type = EXT3_SUPER_MAGIC; |
2469 | buf->f_bsize = sb->s_blocksize; | 2472 | buf->f_bsize = sb->s_blocksize; |
2470 | buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead; | 2473 | buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last; |
2471 | buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); | 2474 | buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter); |
2475 | es->s_free_blocks_count = cpu_to_le32(buf->f_bfree); | ||
2472 | buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); | 2476 | buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); |
2473 | if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) | 2477 | if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) |
2474 | buf->f_bavail = 0; | 2478 | buf->f_bavail = 0; |
2475 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 2479 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
2476 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); | 2480 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); |
2481 | es->s_free_inodes_count = cpu_to_le32(buf->f_ffree); | ||
2477 | buf->f_namelen = EXT3_NAME_LEN; | 2482 | buf->f_namelen = EXT3_NAME_LEN; |
2478 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | 2483 | fsid = le64_to_cpup((void *)es->s_uuid) ^ |
2479 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | 2484 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); |