diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext2/super.c | 20 |
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)); |