aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorEric Whitney <enwlinux@gmail.com>2013-04-09 09:27:31 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-04-09 09:27:31 -0400
commit5c1ff33640293499f9b16450029c9fb4dc06543e (patch)
treede77ead0c0cefcda6e24f94a8336d65cc4ade2b9 /fs/ext4
parentbcb1385096caf421363d47e735acda940cb1e12b (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.c15
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
2610static int ext4_nonda_switch(struct super_block *sb) 2610static 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