diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/bitmap.c | 4 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 4 | ||||
-rw-r--r-- | fs/ext4/resize.c | 7 | ||||
-rw-r--r-- | fs/ext4/super.c | 174 |
4 files changed, 132 insertions, 57 deletions
diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c index 7e86a6d28c6..a94b9c63ee5 100644 --- a/fs/ext4/bitmap.c +++ b/fs/ext4/bitmap.c | |||
@@ -11,8 +11,6 @@ | |||
11 | #include <linux/jbd2.h> | 11 | #include <linux/jbd2.h> |
12 | #include "ext4.h" | 12 | #include "ext4.h" |
13 | 13 | ||
14 | #ifdef EXT4FS_DEBUG | ||
15 | |||
16 | static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; | 14 | static const int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; |
17 | 15 | ||
18 | unsigned int ext4_count_free(char *bitmap, unsigned int numchars) | 16 | unsigned int ext4_count_free(char *bitmap, unsigned int numchars) |
@@ -25,8 +23,6 @@ unsigned int ext4_count_free(char *bitmap, unsigned int numchars) | |||
25 | return sum; | 23 | return sum; |
26 | } | 24 | } |
27 | 25 | ||
28 | #endif /* EXT4FS_DEBUG */ | ||
29 | |||
30 | int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, | 26 | int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, |
31 | struct ext4_group_desc *gdp, | 27 | struct ext4_group_desc *gdp, |
32 | struct buffer_head *bh, int sz) | 28 | struct buffer_head *bh, int sz) |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 293fa1ced21..01434f25917 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1161,8 +1161,7 @@ struct ext4_sb_info { | |||
1161 | unsigned long s_desc_per_block; /* Number of group descriptors per block */ | 1161 | unsigned long s_desc_per_block; /* Number of group descriptors per block */ |
1162 | ext4_group_t s_groups_count; /* Number of groups in the fs */ | 1162 | ext4_group_t s_groups_count; /* Number of groups in the fs */ |
1163 | ext4_group_t s_blockfile_groups;/* Groups acceptable for non-extent files */ | 1163 | ext4_group_t s_blockfile_groups;/* Groups acceptable for non-extent files */ |
1164 | unsigned long s_overhead_last; /* Last calculated overhead */ | 1164 | unsigned long s_overhead; /* # of fs overhead clusters */ |
1165 | unsigned long s_blocks_last; /* Last seen block count */ | ||
1166 | unsigned int s_cluster_ratio; /* Number of blocks per cluster */ | 1165 | unsigned int s_cluster_ratio; /* Number of blocks per cluster */ |
1167 | unsigned int s_cluster_bits; /* log2 of s_cluster_ratio */ | 1166 | unsigned int s_cluster_bits; /* log2 of s_cluster_ratio */ |
1168 | loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */ | 1167 | loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */ |
@@ -2037,6 +2036,7 @@ extern int ext4_group_extend(struct super_block *sb, | |||
2037 | extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count); | 2036 | extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count); |
2038 | 2037 | ||
2039 | /* super.c */ | 2038 | /* super.c */ |
2039 | extern int ext4_calculate_overhead(struct super_block *sb); | ||
2040 | extern int ext4_superblock_csum_verify(struct super_block *sb, | 2040 | extern int ext4_superblock_csum_verify(struct super_block *sb, |
2041 | struct ext4_super_block *es); | 2041 | struct ext4_super_block *es); |
2042 | extern void ext4_superblock_csum_set(struct super_block *sb, | 2042 | extern void ext4_superblock_csum_set(struct super_block *sb, |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 7ea6cbb4412..17d38de4068 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -1197,7 +1197,7 @@ static void ext4_update_super(struct super_block *sb, | |||
1197 | struct ext4_new_group_data *group_data = flex_gd->groups; | 1197 | struct ext4_new_group_data *group_data = flex_gd->groups; |
1198 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 1198 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
1199 | struct ext4_super_block *es = sbi->s_es; | 1199 | struct ext4_super_block *es = sbi->s_es; |
1200 | int i; | 1200 | int i, ret; |
1201 | 1201 | ||
1202 | BUG_ON(flex_gd->count == 0 || group_data == NULL); | 1202 | BUG_ON(flex_gd->count == 0 || group_data == NULL); |
1203 | /* | 1203 | /* |
@@ -1272,6 +1272,11 @@ static void ext4_update_super(struct super_block *sb, | |||
1272 | &sbi->s_flex_groups[flex_group].free_inodes); | 1272 | &sbi->s_flex_groups[flex_group].free_inodes); |
1273 | } | 1273 | } |
1274 | 1274 | ||
1275 | /* | ||
1276 | * Update the fs overhead information | ||
1277 | */ | ||
1278 | ext4_calculate_overhead(sb); | ||
1279 | |||
1275 | if (test_opt(sb, DEBUG)) | 1280 | if (test_opt(sb, DEBUG)) |
1276 | printk(KERN_DEBUG "EXT4-fs: added group %u:" | 1281 | printk(KERN_DEBUG "EXT4-fs: added group %u:" |
1277 | "%llu blocks(%llu free %llu reserved)\n", flex_gd->count, | 1282 | "%llu blocks(%llu free %llu reserved)\n", flex_gd->count, |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index eb7aa3e4ef0..78b7ede2efa 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -3085,6 +3085,114 @@ static int set_journal_csum_feature_set(struct super_block *sb) | |||
3085 | return ret; | 3085 | return ret; |
3086 | } | 3086 | } |
3087 | 3087 | ||
3088 | /* | ||
3089 | * Note: calculating the overhead so we can be compatible with | ||
3090 | * historical BSD practice is quite difficult in the face of | ||
3091 | * clusters/bigalloc. This is because multiple metadata blocks from | ||
3092 | * different block group can end up in the same allocation cluster. | ||
3093 | * Calculating the exact overhead in the face of clustered allocation | ||
3094 | * requires either O(all block bitmaps) in memory or O(number of block | ||
3095 | * groups**2) in time. We will still calculate the superblock for | ||
3096 | * older file systems --- and if we come across with a bigalloc file | ||
3097 | * system with zero in s_overhead_clusters the estimate will be close to | ||
3098 | * correct especially for very large cluster sizes --- but for newer | ||
3099 | * file systems, it's better to calculate this figure once at mkfs | ||
3100 | * time, and store it in the superblock. If the superblock value is | ||
3101 | * present (even for non-bigalloc file systems), we will use it. | ||
3102 | */ | ||
3103 | static int count_overhead(struct super_block *sb, ext4_group_t grp, | ||
3104 | char *buf) | ||
3105 | { | ||
3106 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
3107 | struct ext4_group_desc *gdp; | ||
3108 | ext4_fsblk_t first_block, last_block, b; | ||
3109 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); | ||
3110 | int s, j, count = 0; | ||
3111 | |||
3112 | first_block = le32_to_cpu(sbi->s_es->s_first_data_block) + | ||
3113 | (grp * EXT4_BLOCKS_PER_GROUP(sb)); | ||
3114 | last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1; | ||
3115 | for (i = 0; i < ngroups; i++) { | ||
3116 | gdp = ext4_get_group_desc(sb, i, NULL); | ||
3117 | b = ext4_block_bitmap(sb, gdp); | ||
3118 | if (b >= first_block && b <= last_block) { | ||
3119 | ext4_set_bit(EXT4_B2C(sbi, b - first_block), buf); | ||
3120 | count++; | ||
3121 | } | ||
3122 | b = ext4_inode_bitmap(sb, gdp); | ||
3123 | if (b >= first_block && b <= last_block) { | ||
3124 | ext4_set_bit(EXT4_B2C(sbi, b - first_block), buf); | ||
3125 | count++; | ||
3126 | } | ||
3127 | b = ext4_inode_table(sb, gdp); | ||
3128 | if (b >= first_block && b + sbi->s_itb_per_group <= last_block) | ||
3129 | for (j = 0; j < sbi->s_itb_per_group; j++, b++) { | ||
3130 | int c = EXT4_B2C(sbi, b - first_block); | ||
3131 | ext4_set_bit(c, buf); | ||
3132 | count++; | ||
3133 | } | ||
3134 | if (i != grp) | ||
3135 | continue; | ||
3136 | s = 0; | ||
3137 | if (ext4_bg_has_super(sb, grp)) { | ||
3138 | ext4_set_bit(s++, buf); | ||
3139 | count++; | ||
3140 | } | ||
3141 | for (j = ext4_bg_num_gdb(sb, grp); j > 0; j--) { | ||
3142 | ext4_set_bit(EXT4_B2C(sbi, s++), buf); | ||
3143 | count++; | ||
3144 | } | ||
3145 | } | ||
3146 | if (!count) | ||
3147 | return 0; | ||
3148 | return EXT4_CLUSTERS_PER_GROUP(sb) - | ||
3149 | ext4_count_free(buf, EXT4_CLUSTERS_PER_GROUP(sb) / 8); | ||
3150 | } | ||
3151 | |||
3152 | /* | ||
3153 | * Compute the overhead and stash it in sbi->s_overhead | ||
3154 | */ | ||
3155 | int ext4_calculate_overhead(struct super_block *sb) | ||
3156 | { | ||
3157 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
3158 | struct ext4_super_block *es = sbi->s_es; | ||
3159 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); | ||
3160 | ext4_fsblk_t overhead = 0; | ||
3161 | char *buf = (char *) get_zeroed_page(GFP_KERNEL); | ||
3162 | |||
3163 | memset(buf, 0, PAGE_SIZE); | ||
3164 | if (!buf) | ||
3165 | return -ENOMEM; | ||
3166 | |||
3167 | /* | ||
3168 | * Compute the overhead (FS structures). This is constant | ||
3169 | * for a given filesystem unless the number of block groups | ||
3170 | * changes so we cache the previous value until it does. | ||
3171 | */ | ||
3172 | |||
3173 | /* | ||
3174 | * All of the blocks before first_data_block are overhead | ||
3175 | */ | ||
3176 | overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block)); | ||
3177 | |||
3178 | /* | ||
3179 | * Add the overhead found in each block group | ||
3180 | */ | ||
3181 | for (i = 0; i < ngroups; i++) { | ||
3182 | int blks; | ||
3183 | |||
3184 | blks = count_overhead(sb, i, buf); | ||
3185 | overhead += blks; | ||
3186 | if (blks) | ||
3187 | memset(buf, 0, PAGE_SIZE); | ||
3188 | cond_resched(); | ||
3189 | } | ||
3190 | sbi->s_overhead = overhead; | ||
3191 | smp_wmb(); | ||
3192 | free_page((unsigned long) buf); | ||
3193 | return 0; | ||
3194 | } | ||
3195 | |||
3088 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) | 3196 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) |
3089 | { | 3197 | { |
3090 | char *orig_data = kstrdup(data, GFP_KERNEL); | 3198 | char *orig_data = kstrdup(data, GFP_KERNEL); |
@@ -3735,6 +3843,18 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3735 | 3843 | ||
3736 | no_journal: | 3844 | no_journal: |
3737 | /* | 3845 | /* |
3846 | * Get the # of file system overhead blocks from the | ||
3847 | * superblock if present. | ||
3848 | */ | ||
3849 | if (es->s_overhead_clusters) | ||
3850 | sbi->s_overhead = le32_to_cpu(es->s_overhead_clusters); | ||
3851 | else { | ||
3852 | ret = ext4_calculate_overhead(sb); | ||
3853 | if (ret) | ||
3854 | goto failed_mount_wq; | ||
3855 | } | ||
3856 | |||
3857 | /* | ||
3738 | * The maximum number of concurrent works can be high and | 3858 | * The maximum number of concurrent works can be high and |
3739 | * concurrency isn't really necessary. Limit it to 1. | 3859 | * concurrency isn't really necessary. Limit it to 1. |
3740 | */ | 3860 | */ |
@@ -4600,67 +4720,21 @@ restore_opts: | |||
4600 | return err; | 4720 | return err; |
4601 | } | 4721 | } |
4602 | 4722 | ||
4603 | /* | ||
4604 | * Note: calculating the overhead so we can be compatible with | ||
4605 | * historical BSD practice is quite difficult in the face of | ||
4606 | * clusters/bigalloc. This is because multiple metadata blocks from | ||
4607 | * different block group can end up in the same allocation cluster. | ||
4608 | * Calculating the exact overhead in the face of clustered allocation | ||
4609 | * requires either O(all block bitmaps) in memory or O(number of block | ||
4610 | * groups**2) in time. We will still calculate the superblock for | ||
4611 | * older file systems --- and if we come across with a bigalloc file | ||
4612 | * system with zero in s_overhead_clusters the estimate will be close to | ||
4613 | * correct especially for very large cluster sizes --- but for newer | ||
4614 | * file systems, it's better to calculate this figure once at mkfs | ||
4615 | * time, and store it in the superblock. If the superblock value is | ||
4616 | * present (even for non-bigalloc file systems), we will use it. | ||
4617 | */ | ||
4618 | static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) | 4723 | static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) |
4619 | { | 4724 | { |
4620 | struct super_block *sb = dentry->d_sb; | 4725 | struct super_block *sb = dentry->d_sb; |
4621 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 4726 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
4622 | struct ext4_super_block *es = sbi->s_es; | 4727 | struct ext4_super_block *es = sbi->s_es; |
4623 | struct ext4_group_desc *gdp; | 4728 | ext4_fsblk_t overhead = 0; |
4624 | u64 fsid; | 4729 | u64 fsid; |
4625 | s64 bfree; | 4730 | s64 bfree; |
4626 | 4731 | ||
4627 | if (test_opt(sb, MINIX_DF)) { | 4732 | if (!test_opt(sb, MINIX_DF)) |
4628 | sbi->s_overhead_last = 0; | 4733 | overhead = sbi->s_overhead; |
4629 | } else if (es->s_overhead_clusters) { | ||
4630 | sbi->s_overhead_last = le32_to_cpu(es->s_overhead_clusters); | ||
4631 | } else if (sbi->s_blocks_last != ext4_blocks_count(es)) { | ||
4632 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); | ||
4633 | ext4_fsblk_t overhead = 0; | ||
4634 | |||
4635 | /* | ||
4636 | * Compute the overhead (FS structures). This is constant | ||
4637 | * for a given filesystem unless the number of block groups | ||
4638 | * changes so we cache the previous value until it does. | ||
4639 | */ | ||
4640 | |||
4641 | /* | ||
4642 | * All of the blocks before first_data_block are | ||
4643 | * overhead | ||
4644 | */ | ||
4645 | overhead = EXT4_B2C(sbi, le32_to_cpu(es->s_first_data_block)); | ||
4646 | |||
4647 | /* | ||
4648 | * Add the overhead found in each block group | ||
4649 | */ | ||
4650 | for (i = 0; i < ngroups; i++) { | ||
4651 | gdp = ext4_get_group_desc(sb, i, NULL); | ||
4652 | overhead += ext4_num_overhead_clusters(sb, i, gdp); | ||
4653 | cond_resched(); | ||
4654 | } | ||
4655 | sbi->s_overhead_last = overhead; | ||
4656 | smp_wmb(); | ||
4657 | sbi->s_blocks_last = ext4_blocks_count(es); | ||
4658 | } | ||
4659 | 4734 | ||
4660 | buf->f_type = EXT4_SUPER_MAGIC; | 4735 | buf->f_type = EXT4_SUPER_MAGIC; |
4661 | buf->f_bsize = sb->s_blocksize; | 4736 | buf->f_bsize = sb->s_blocksize; |
4662 | buf->f_blocks = (ext4_blocks_count(es) - | 4737 | buf->f_blocks = ext4_blocks_count(es) - EXT4_C2B(sbi, sbi->s_overhead); |
4663 | EXT4_C2B(sbi, sbi->s_overhead_last)); | ||
4664 | bfree = percpu_counter_sum_positive(&sbi->s_freeclusters_counter) - | 4738 | bfree = percpu_counter_sum_positive(&sbi->s_freeclusters_counter) - |
4665 | percpu_counter_sum_positive(&sbi->s_dirtyclusters_counter); | 4739 | percpu_counter_sum_positive(&sbi->s_dirtyclusters_counter); |
4666 | /* prevent underflow in case that few free space is available */ | 4740 | /* prevent underflow in case that few free space is available */ |