aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext2/super.c')
-rw-r--r--fs/ext2/super.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 5de5061eb331..b2efd9083b9b 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1099,15 +1099,18 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
1099 struct super_block *sb = dentry->d_sb; 1099 struct super_block *sb = dentry->d_sb;
1100 struct ext2_sb_info *sbi = EXT2_SB(sb); 1100 struct ext2_sb_info *sbi = EXT2_SB(sb);
1101 struct ext2_super_block *es = sbi->s_es; 1101 struct ext2_super_block *es = sbi->s_es;
1102 unsigned long overhead;
1103 int i;
1104 u64 fsid; 1102 u64 fsid;
1105 1103
1106 if (test_opt (sb, MINIX_DF)) 1104 if (test_opt (sb, MINIX_DF))
1107 overhead = 0; 1105 sbi->s_overhead_last = 0;
1108 else { 1106 else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) {
1107 unsigned long i, overhead = 0;
1108 smp_rmb();
1109
1109 /* 1110 /*
1110 * Compute the overhead (FS structures) 1111 * Compute the overhead (FS structures). This is constant
1112 * for a given filesystem unless the number of block groups
1113 * changes so we cache the previous value until it does.
1111 */ 1114 */
1112 1115
1113 /* 1116 /*
@@ -1131,17 +1134,22 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
1131 */ 1134 */
1132 overhead += (sbi->s_groups_count * 1135 overhead += (sbi->s_groups_count *
1133 (2 + sbi->s_itb_per_group)); 1136 (2 + sbi->s_itb_per_group));
1137 sbi->s_overhead_last = overhead;
1138 smp_wmb();
1139 sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
1134 } 1140 }
1135 1141
1136 buf->f_type = EXT2_SUPER_MAGIC; 1142 buf->f_type = EXT2_SUPER_MAGIC;
1137 buf->f_bsize = sb->s_blocksize; 1143 buf->f_bsize = sb->s_blocksize;
1138 buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead; 1144 buf->f_blocks = le32_to_cpu(es->s_blocks_count) - sbi->s_overhead_last;
1139 buf->f_bfree = ext2_count_free_blocks(sb); 1145 buf->f_bfree = ext2_count_free_blocks(sb);
1146 es->s_free_blocks_count = cpu_to_le32(buf->f_bfree);
1140 buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); 1147 buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
1141 if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) 1148 if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
1142 buf->f_bavail = 0; 1149 buf->f_bavail = 0;
1143 buf->f_files = le32_to_cpu(es->s_inodes_count); 1150 buf->f_files = le32_to_cpu(es->s_inodes_count);
1144 buf->f_ffree = ext2_count_free_inodes(sb); 1151 buf->f_ffree = ext2_count_free_inodes(sb);
1152 es->s_free_inodes_count = cpu_to_le32(buf->f_ffree);
1145 buf->f_namelen = EXT2_NAME_LEN; 1153 buf->f_namelen = EXT2_NAME_LEN;
1146 fsid = le64_to_cpup((void *)es->s_uuid) ^ 1154 fsid = le64_to_cpup((void *)es->s_uuid) ^
1147 le64_to_cpup((void *)es->s_uuid + sizeof(u64)); 1155 le64_to_cpup((void *)es->s_uuid + sizeof(u64));