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