Commit 57042651 authored by Theodore Ts'o's avatar Theodore Ts'o

ext4: convert s_{dirty,free}blocks_counter to s_{dirty,free}clusters_counter

Convert the percpu counters s_dirtyblocks_counter and
s_freeblocks_counter in struct ext4_super_info to be
s_dirtyclusters_counter and s_freeclusters_counter.
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 0aa06000
...@@ -414,16 +414,16 @@ static int ext4_has_free_blocks(struct ext4_sb_info *sbi, ...@@ -414,16 +414,16 @@ static int ext4_has_free_blocks(struct ext4_sb_info *sbi,
s64 nblocks, unsigned int flags) s64 nblocks, unsigned int flags)
{ {
s64 free_blocks, dirty_blocks, root_blocks; s64 free_blocks, dirty_blocks, root_blocks;
struct percpu_counter *fbc = &sbi->s_freeblocks_counter; struct percpu_counter *fcc = &sbi->s_freeclusters_counter;
struct percpu_counter *dbc = &sbi->s_dirtyblocks_counter; struct percpu_counter *dbc = &sbi->s_dirtyclusters_counter;
free_blocks = percpu_counter_read_positive(fbc); free_blocks = percpu_counter_read_positive(fcc);
dirty_blocks = percpu_counter_read_positive(dbc); dirty_blocks = percpu_counter_read_positive(dbc);
root_blocks = ext4_r_blocks_count(sbi->s_es); root_blocks = ext4_r_blocks_count(sbi->s_es);
if (free_blocks - (nblocks + root_blocks + dirty_blocks) < if (free_blocks - (nblocks + root_blocks + dirty_blocks) <
EXT4_FREEBLOCKS_WATERMARK) { EXT4_FREEBLOCKS_WATERMARK) {
free_blocks = percpu_counter_sum_positive(fbc); free_blocks = EXT4_C2B(sbi, percpu_counter_sum_positive(fcc));
dirty_blocks = percpu_counter_sum_positive(dbc); dirty_blocks = percpu_counter_sum_positive(dbc);
} }
/* Check whether we have space after /* Check whether we have space after
...@@ -449,7 +449,7 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi, ...@@ -449,7 +449,7 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi,
s64 nblocks, unsigned int flags) s64 nblocks, unsigned int flags)
{ {
if (ext4_has_free_blocks(sbi, nblocks, flags)) { if (ext4_has_free_blocks(sbi, nblocks, flags)) {
percpu_counter_add(&sbi->s_dirtyblocks_counter, nblocks); percpu_counter_add(&sbi->s_dirtyclusters_counter, nblocks);
return 0; return 0;
} else } else
return -ENOSPC; return -ENOSPC;
......
...@@ -855,6 +855,7 @@ struct ext4_inode_info { ...@@ -855,6 +855,7 @@ struct ext4_inode_info {
ext4_group_t i_last_alloc_group; ext4_group_t i_last_alloc_group;
/* allocation reservation info for delalloc */ /* allocation reservation info for delalloc */
/* In case of bigalloc, these refer to clusters rather than blocks */
unsigned int i_reserved_data_blocks; unsigned int i_reserved_data_blocks;
unsigned int i_reserved_meta_blocks; unsigned int i_reserved_meta_blocks;
unsigned int i_allocated_meta_blocks; unsigned int i_allocated_meta_blocks;
...@@ -1144,10 +1145,10 @@ struct ext4_sb_info { ...@@ -1144,10 +1145,10 @@ struct ext4_sb_info {
u32 s_hash_seed[4]; u32 s_hash_seed[4];
int s_def_hash_version; int s_def_hash_version;
int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */
struct percpu_counter s_freeblocks_counter; struct percpu_counter s_freeclusters_counter;
struct percpu_counter s_freeinodes_counter; struct percpu_counter s_freeinodes_counter;
struct percpu_counter s_dirs_counter; struct percpu_counter s_dirs_counter;
struct percpu_counter s_dirtyblocks_counter; struct percpu_counter s_dirtyclusters_counter;
struct blockgroup_lock *s_blockgroup_lock; struct blockgroup_lock *s_blockgroup_lock;
struct proc_dir_entry *s_proc; struct proc_dir_entry *s_proc;
struct kobject s_kobj; struct kobject s_kobj;
......
...@@ -490,7 +490,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, ...@@ -490,7 +490,8 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter); freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
avefreei = freei / ngroups; avefreei = freei / ngroups;
freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter); freeb = EXT4_C2B(sbi,
percpu_counter_read_positive(&sbi->s_freeclusters_counter));
avefreeb = freeb; avefreeb = freeb;
do_div(avefreeb, ngroups); do_div(avefreeb, ngroups);
ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter); ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
......
...@@ -281,7 +281,7 @@ void ext4_da_update_reserve_space(struct inode *inode, ...@@ -281,7 +281,7 @@ void ext4_da_update_reserve_space(struct inode *inode,
/* Update per-inode reservations */ /* Update per-inode reservations */
ei->i_reserved_data_blocks -= used; ei->i_reserved_data_blocks -= used;
ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks; ei->i_reserved_meta_blocks -= ei->i_allocated_meta_blocks;
percpu_counter_sub(&sbi->s_dirtyblocks_counter, percpu_counter_sub(&sbi->s_dirtyclusters_counter,
used + ei->i_allocated_meta_blocks); used + ei->i_allocated_meta_blocks);
ei->i_allocated_meta_blocks = 0; ei->i_allocated_meta_blocks = 0;
...@@ -291,7 +291,7 @@ void ext4_da_update_reserve_space(struct inode *inode, ...@@ -291,7 +291,7 @@ void ext4_da_update_reserve_space(struct inode *inode,
* only when we have written all of the delayed * only when we have written all of the delayed
* allocation blocks. * allocation blocks.
*/ */
percpu_counter_sub(&sbi->s_dirtyblocks_counter, percpu_counter_sub(&sbi->s_dirtyclusters_counter,
ei->i_reserved_meta_blocks); ei->i_reserved_meta_blocks);
ei->i_reserved_meta_blocks = 0; ei->i_reserved_meta_blocks = 0;
ei->i_da_metadata_calc_len = 0; ei->i_da_metadata_calc_len = 0;
...@@ -1119,14 +1119,14 @@ static void ext4_da_release_space(struct inode *inode, int to_free) ...@@ -1119,14 +1119,14 @@ static void ext4_da_release_space(struct inode *inode, int to_free)
* only when we have written all of the delayed * only when we have written all of the delayed
* allocation blocks. * allocation blocks.
*/ */
percpu_counter_sub(&sbi->s_dirtyblocks_counter, percpu_counter_sub(&sbi->s_dirtyclusters_counter,
ei->i_reserved_meta_blocks); ei->i_reserved_meta_blocks);
ei->i_reserved_meta_blocks = 0; ei->i_reserved_meta_blocks = 0;
ei->i_da_metadata_calc_len = 0; ei->i_da_metadata_calc_len = 0;
} }
/* update fs dirty data blocks counter */ /* update fs dirty data blocks counter */
percpu_counter_sub(&sbi->s_dirtyblocks_counter, to_free); percpu_counter_sub(&sbi->s_dirtyclusters_counter, to_free);
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
...@@ -1349,9 +1349,10 @@ static void ext4_print_free_blocks(struct inode *inode) ...@@ -1349,9 +1349,10 @@ static void ext4_print_free_blocks(struct inode *inode)
ext4_count_free_blocks(inode->i_sb)); ext4_count_free_blocks(inode->i_sb));
printk(KERN_CRIT "Free/Dirty block details\n"); printk(KERN_CRIT "Free/Dirty block details\n");
printk(KERN_CRIT "free_blocks=%lld\n", printk(KERN_CRIT "free_blocks=%lld\n",
(long long) percpu_counter_sum(&sbi->s_freeblocks_counter)); (long long) EXT4_C2B(EXT4_SB(inode->i_sb),
percpu_counter_sum(&sbi->s_freeclusters_counter)));
printk(KERN_CRIT "dirty_blocks=%lld\n", printk(KERN_CRIT "dirty_blocks=%lld\n",
(long long) percpu_counter_sum(&sbi->s_dirtyblocks_counter)); (long long) percpu_counter_sum(&sbi->s_dirtyclusters_counter));
printk(KERN_CRIT "Block reservation details\n"); printk(KERN_CRIT "Block reservation details\n");
printk(KERN_CRIT "i_reserved_data_blocks=%u\n", printk(KERN_CRIT "i_reserved_data_blocks=%u\n",
EXT4_I(inode)->i_reserved_data_blocks); EXT4_I(inode)->i_reserved_data_blocks);
...@@ -2226,8 +2227,9 @@ static int ext4_nonda_switch(struct super_block *sb) ...@@ -2226,8 +2227,9 @@ static int ext4_nonda_switch(struct super_block *sb)
* Delalloc need an accurate free block accounting. So switch * Delalloc need an accurate free block accounting. So switch
* to non delalloc when we are near to error range. * to non delalloc when we are near to error range.
*/ */
free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); free_blocks = EXT4_C2B(sbi,
dirty_blocks = percpu_counter_read_positive(&sbi->s_dirtyblocks_counter); percpu_counter_read_positive(&sbi->s_freeclusters_counter));
dirty_blocks = percpu_counter_read_positive(&sbi->s_dirtyclusters_counter);
if (2 * free_blocks < 3 * dirty_blocks || if (2 * free_blocks < 3 * dirty_blocks ||
free_blocks < (dirty_blocks + EXT4_FREEBLOCKS_WATERMARK)) { free_blocks < (dirty_blocks + EXT4_FREEBLOCKS_WATERMARK)) {
/* /*
......
...@@ -2834,13 +2834,14 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, ...@@ -2834,13 +2834,14 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp); gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp);
ext4_unlock_group(sb, ac->ac_b_ex.fe_group); ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len); percpu_counter_sub(&sbi->s_freeclusters_counter, ac->ac_b_ex.fe_len);
/* /*
* Now reduce the dirty block count also. Should not go negative * Now reduce the dirty block count also. Should not go negative
*/ */
if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED)) if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED))
/* release all the reserved blocks if non delalloc */ /* release all the reserved blocks if non delalloc */
percpu_counter_sub(&sbi->s_dirtyblocks_counter, reserv_clstrs); percpu_counter_sub(&sbi->s_dirtyclusters_counter,
reserv_clstrs);
if (sbi->s_log_groups_per_flex) { if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi, ext4_group_t flex_group = ext4_flex_group(sbi,
...@@ -4384,7 +4385,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, ...@@ -4384,7 +4385,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
if (!ext4_test_inode_state(ar->inode, if (!ext4_test_inode_state(ar->inode,
EXT4_STATE_DELALLOC_RESERVED)) EXT4_STATE_DELALLOC_RESERVED))
/* release all the reserved blocks if non delalloc */ /* release all the reserved blocks if non delalloc */
percpu_counter_sub(&sbi->s_dirtyblocks_counter, percpu_counter_sub(&sbi->s_dirtyclusters_counter,
reserv_clstrs); reserv_clstrs);
} }
...@@ -4691,7 +4692,7 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, ...@@ -4691,7 +4692,7 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
ext4_free_blks_set(sb, gdp, ret); ext4_free_blks_set(sb, gdp, ret);
gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp); gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
ext4_unlock_group(sb, block_group); ext4_unlock_group(sb, block_group);
percpu_counter_add(&sbi->s_freeblocks_counter, count); percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters);
if (sbi->s_log_groups_per_flex) { if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi, block_group); ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
...@@ -4833,7 +4834,8 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, ...@@ -4833,7 +4834,8 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
ext4_free_blks_set(sb, desc, blk_free_count); ext4_free_blks_set(sb, desc, blk_free_count);
desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
ext4_unlock_group(sb, block_group); ext4_unlock_group(sb, block_group);
percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed); percpu_counter_add(&sbi->s_freeclusters_counter,
EXT4_B2C(sbi, blocks_freed));
if (sbi->s_log_groups_per_flex) { if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi, block_group); ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
......
...@@ -937,8 +937,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) ...@@ -937,8 +937,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
input->reserved_blocks); input->reserved_blocks);
/* Update the free space counts */ /* Update the free space counts */
percpu_counter_add(&sbi->s_freeblocks_counter, percpu_counter_add(&sbi->s_freeclusters_counter,
input->free_blocks_count); EXT4_B2C(sbi, input->free_blocks_count));
percpu_counter_add(&sbi->s_freeinodes_counter, percpu_counter_add(&sbi->s_freeinodes_counter,
EXT4_INODES_PER_GROUP(sb)); EXT4_INODES_PER_GROUP(sb));
......
...@@ -837,10 +837,10 @@ static void ext4_put_super(struct super_block *sb) ...@@ -837,10 +837,10 @@ static void ext4_put_super(struct super_block *sb)
brelse(sbi->s_group_desc[i]); brelse(sbi->s_group_desc[i]);
ext4_kvfree(sbi->s_group_desc); ext4_kvfree(sbi->s_group_desc);
ext4_kvfree(sbi->s_flex_groups); ext4_kvfree(sbi->s_flex_groups);
percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeclusters_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter); percpu_counter_destroy(&sbi->s_dirs_counter);
percpu_counter_destroy(&sbi->s_dirtyblocks_counter); percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
brelse(sbi->s_sbh); brelse(sbi->s_sbh);
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
for (i = 0; i < MAXQUOTAS; i++) for (i = 0; i < MAXQUOTAS; i++)
...@@ -2473,7 +2473,7 @@ static ssize_t delayed_allocation_blocks_show(struct ext4_attr *a, ...@@ -2473,7 +2473,7 @@ static ssize_t delayed_allocation_blocks_show(struct ext4_attr *a,
char *buf) char *buf)
{ {
return snprintf(buf, PAGE_SIZE, "%llu\n", return snprintf(buf, PAGE_SIZE, "%llu\n",
(s64) percpu_counter_sum(&sbi->s_dirtyblocks_counter)); (s64) percpu_counter_sum(&sbi->s_dirtyclusters_counter));
} }
static ssize_t session_write_kbytes_show(struct ext4_attr *a, static ssize_t session_write_kbytes_show(struct ext4_attr *a,
...@@ -3575,7 +3575,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -3575,7 +3575,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_err_report.function = print_daily_error_info; sbi->s_err_report.function = print_daily_error_info;
sbi->s_err_report.data = (unsigned long) sb; sbi->s_err_report.data = (unsigned long) sb;
err = percpu_counter_init(&sbi->s_freeblocks_counter, err = percpu_counter_init(&sbi->s_freeclusters_counter,
ext4_count_free_blocks(sb)); ext4_count_free_blocks(sb));
if (!err) { if (!err) {
err = percpu_counter_init(&sbi->s_freeinodes_counter, err = percpu_counter_init(&sbi->s_freeinodes_counter,
...@@ -3586,7 +3586,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -3586,7 +3586,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
ext4_count_dirs(sb)); ext4_count_dirs(sb));
} }
if (!err) { if (!err) {
err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0);
} }
if (err) { if (err) {
ext4_msg(sb, KERN_ERR, "insufficient memory"); ext4_msg(sb, KERN_ERR, "insufficient memory");
...@@ -3701,13 +3701,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -3701,13 +3701,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
* The journal may have updated the bg summary counts, so we * The journal may have updated the bg summary counts, so we
* need to update the global counters. * need to update the global counters.
*/ */
percpu_counter_set(&sbi->s_freeblocks_counter, percpu_counter_set(&sbi->s_freeclusters_counter,
ext4_count_free_blocks(sb)); ext4_count_free_blocks(sb));
percpu_counter_set(&sbi->s_freeinodes_counter, percpu_counter_set(&sbi->s_freeinodes_counter,
ext4_count_free_inodes(sb)); ext4_count_free_inodes(sb));
percpu_counter_set(&sbi->s_dirs_counter, percpu_counter_set(&sbi->s_dirs_counter,
ext4_count_dirs(sb)); ext4_count_dirs(sb));
percpu_counter_set(&sbi->s_dirtyblocks_counter, 0); percpu_counter_set(&sbi->s_dirtyclusters_counter, 0);
no_journal: no_journal:
/* /*
...@@ -3847,10 +3847,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -3847,10 +3847,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
del_timer(&sbi->s_err_report); del_timer(&sbi->s_err_report);
if (sbi->s_flex_groups) if (sbi->s_flex_groups)
ext4_kvfree(sbi->s_flex_groups); ext4_kvfree(sbi->s_flex_groups);
percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeclusters_counter);
percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter); percpu_counter_destroy(&sbi->s_dirs_counter);
percpu_counter_destroy(&sbi->s_dirtyblocks_counter); percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
if (sbi->s_mmp_tsk) if (sbi->s_mmp_tsk)
kthread_stop(sbi->s_mmp_tsk); kthread_stop(sbi->s_mmp_tsk);
failed_mount2: failed_mount2:
...@@ -4173,8 +4173,9 @@ static int ext4_commit_super(struct super_block *sb, int sync) ...@@ -4173,8 +4173,9 @@ static int ext4_commit_super(struct super_block *sb, int sync)
else else
es->s_kbytes_written = es->s_kbytes_written =
cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); cpu_to_le64(EXT4_SB(sb)->s_kbytes_written);
ext4_free_blocks_count_set(es, percpu_counter_sum_positive( ext4_free_blocks_count_set(es,
&EXT4_SB(sb)->s_freeblocks_counter)); EXT4_C2B(EXT4_SB(sb), percpu_counter_sum_positive(
&EXT4_SB(sb)->s_freeclusters_counter)));
es->s_free_inodes_count = es->s_free_inodes_count =
cpu_to_le32(percpu_counter_sum_positive( cpu_to_le32(percpu_counter_sum_positive(
&EXT4_SB(sb)->s_freeinodes_counter)); &EXT4_SB(sb)->s_freeinodes_counter));
...@@ -4629,10 +4630,10 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -4629,10 +4630,10 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_type = EXT4_SUPER_MAGIC; buf->f_type = EXT4_SUPER_MAGIC;
buf->f_bsize = sb->s_blocksize; buf->f_bsize = sb->s_blocksize;
buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last;
bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) - bfree = percpu_counter_sum_positive(&sbi->s_freeclusters_counter) -
percpu_counter_sum_positive(&sbi->s_dirtyblocks_counter); percpu_counter_sum_positive(&sbi->s_dirtyclusters_counter);
/* prevent underflow in case that few free space is available */ /* prevent underflow in case that few free space is available */
buf->f_bfree = max_t(s64, bfree, 0); buf->f_bfree = EXT4_C2B(sbi, max_t(s64, bfree, 0));
buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es);
if (buf->f_bfree < ext4_r_blocks_count(es)) if (buf->f_bfree < ext4_r_blocks_count(es))
buf->f_bavail = 0; buf->f_bavail = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment