diff options
author | Eric Whitney <enwlinux@gmail.com> | 2013-04-09 09:27:31 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-04-09 09:27:31 -0400 |
commit | 5c1ff33640293499f9b16450029c9fb4dc06543e (patch) | |
tree | de77ead0c0cefcda6e24f94a8336d65cc4ade2b9 /fs/ext4 | |
parent | bcb1385096caf421363d47e735acda940cb1e12b (diff) |
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.
Signed-off-by: Eric Whitney <enwlinux@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/inode.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index a29bfc2142ef..f9b0b479ff4c 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2609,7 +2609,7 @@ out_writepages: | |||
2609 | 2609 | ||
2610 | static int ext4_nonda_switch(struct super_block *sb) | 2610 | static int ext4_nonda_switch(struct super_block *sb) |
2611 | { | 2611 | { |
2612 | s64 free_blocks, dirty_blocks; | 2612 | s64 free_clusters, dirty_clusters; |
2613 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2613 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
2614 | 2614 | ||
2615 | /* | 2615 | /* |
@@ -2620,17 +2620,18 @@ static int ext4_nonda_switch(struct super_block *sb) | |||
2620 | * Delalloc need an accurate free block accounting. So switch | 2620 | * Delalloc need an accurate free block accounting. So switch |
2621 | * to non delalloc when we are near to error range. | 2621 | * to non delalloc when we are near to error range. |
2622 | */ | 2622 | */ |
2623 | free_blocks = EXT4_C2B(sbi, | 2623 | free_clusters = |
2624 | percpu_counter_read_positive(&sbi->s_freeclusters_counter)); | 2624 | percpu_counter_read_positive(&sbi->s_freeclusters_counter); |
2625 | dirty_blocks = percpu_counter_read_positive(&sbi->s_dirtyclusters_counter); | 2625 | dirty_clusters = |
2626 | percpu_counter_read_positive(&sbi->s_dirtyclusters_counter); | ||
2626 | /* | 2627 | /* |
2627 | * Start pushing delalloc when 1/2 of free blocks are dirty. | 2628 | * Start pushing delalloc when 1/2 of free blocks are dirty. |
2628 | */ | 2629 | */ |
2629 | if (dirty_blocks && (free_blocks < 2 * dirty_blocks)) | 2630 | if (dirty_clusters && (free_clusters < 2 * dirty_clusters)) |
2630 | try_to_writeback_inodes_sb(sb, WB_REASON_FS_FREE_SPACE); | 2631 | try_to_writeback_inodes_sb(sb, WB_REASON_FS_FREE_SPACE); |
2631 | 2632 | ||
2632 | if (2 * free_blocks < 3 * dirty_blocks || | 2633 | if (2 * free_clusters < 3 * dirty_clusters || |
2633 | free_blocks < (dirty_blocks + EXT4_FREECLUSTERS_WATERMARK)) { | 2634 | free_clusters < (dirty_clusters + EXT4_FREECLUSTERS_WATERMARK)) { |
2634 | /* | 2635 | /* |
2635 | * free block count is less than 150% of dirty blocks | 2636 | * free block count is less than 150% of dirty blocks |
2636 | * or free blocks is less than watermark | 2637 | * or free blocks is less than watermark |