ext4: fix free space estimate in ext4_nonda_switch()
PATCH 1/1 ext4: fix free space estimate in ext4_nonda_switch()
Values stored in s_freeclusters_counter and s_dirtyclusters_counter are both in cluster units. Remove the cluster to block conversion applied to s_freeclusters_counter causing an inflated estimate of free space because s_dirtyclusters_counter is not similarly converted. Rename free_blocks and dirty_blocks to better reflect the units these variables contain to avoid future confusion. This fix corrects ENOSPC failures for xfstests 127 and 231 on bigalloc file systems.
--- fs/ext4/inode.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
fs/ext4/inode.c +8 -7
@@ -2661,7 +2661,7 @@ out_writepages:static int ext4_nonda_switch (struct super_block *sb) { -s64 free_blocks, dirty_blocks; +s64 free_clusters, dirty_clusters;struct ext4_sb_info *sbi =EXT4_SB (sb);/*
@@ -2672,17 +2672,18 @@ static int ext4_nonda_switch(struct super_block *sb)* Delalloc need an accurate free block accounting. So switch * to non delalloc when we are near to error range. */ - free_blocks =EXT4_C2B (sbi, -percpu_counter_read_positive (&sbi->s_freeclusters_counter)); - dirty_blocks =percpu_counter_read_positive (&sbi->s_dirtyclusters_counter); + free_clusters = +percpu_counter_read_positive (&sbi->s_freeclusters_counter); + dirty_clusters = +percpu_counter_read_positive (&sbi->s_dirtyclusters_counter);/* * Start pushing delalloc when 1/2 of free blocks are dirty. */ -if (dirty_blocks && (free_blocks <2 * dirty_blocks)) +if (dirty_clusters && (free_clusters <2 * dirty_clusters))try_to_writeback_inodes_sb (sb,WB_REASON_FS_FREE_SPACE ); -if (2 * free_blocks <3 * dirty_blocks || - free_blocks < (dirty_blocks +EXT4_FREECLUSTERS_WATERMARK )) { +if (2 * free_clusters <3 * dirty_clusters || + free_clusters < (dirty_clusters +EXT4_FREECLUSTERS_WATERMARK )) {/* * free block count is less than 150% of dirty blocks * or free blocks is less than watermark
Signature · 1 line
1.7.10.4
Theodore Ts'o
maintainerQuoted 10 lines · Eric Whitney
Values stored in
s_freeclusters_counterands_dirtyclusters_counterare both in cluster units. Remove the cluster to block conversion applied tos_freeclusters_countercausing an inflated estimate of free space becauses_dirtyclusters_counteris not similarly converted. Renamefree_blocksanddirty_blocksto better reflect the units these variables contain to avoid future confusion. This fix corrects ENOSPC failures for xfstests 127 and 231 on bigalloc file systems.Signed-off-by Eric Whitney <[email protected]>
Hi Eric,
This patch looks good. Thanks for submitting it!!
I've applied it to the dev branch for testing.
- Ted