aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/super.c25
-rw-r--r--include/linux/ext4_fs_sb.h2
2 files changed, 17 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));
diff --git a/include/linux/ext4_fs_sb.h b/include/linux/ext4_fs_sb.h
index 691a713139ce..2347557a327a 100644
--- a/include/linux/ext4_fs_sb.h
+++ b/include/linux/ext4_fs_sb.h
@@ -39,6 +39,8 @@ struct ext4_sb_info {
39 unsigned long s_gdb_count; /* Number of group descriptor blocks */ 39 unsigned long s_gdb_count; /* Number of group descriptor blocks */
40 unsigned long s_desc_per_block; /* Number of group descriptors per block */ 40 unsigned long s_desc_per_block; /* Number of group descriptors per block */
41 unsigned long s_groups_count; /* Number of groups in the fs */ 41 unsigned long s_groups_count; /* Number of groups in the fs */
42 unsigned long s_overhead_last; /* Last calculated overhead */
43 unsigned long s_blocks_last; /* Last seen block count */
42 struct buffer_head * s_sbh; /* Buffer containing the super block */ 44 struct buffer_head * s_sbh; /* Buffer containing the super block */
43 struct ext4_super_block * s_es; /* Pointer to the super block in the buffer */ 45 struct ext4_super_block * s_es; /* Pointer to the super block in the buffer */
44 struct buffer_head ** s_group_desc; 46 struct buffer_head ** s_group_desc;