aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2017-10-01 17:59:54 -0400
committerTheodore Ts'o <tytso@mit.edu>2017-10-01 17:59:54 -0400
commit68fd97504ad2f70850c47ce45caa110a0ca843d2 (patch)
tree7cee951697a59a7c4f3dfe939de6339e3869d772 /fs/ext4
parent545052e9e35a34af95d2e870ac3fe2894376e6e9 (diff)
ext4: retry allocations conservatively
Now that we no longer try to reserve metadata blocks for delayed allocations (which tended to overestimate the required number of blocks significantly), we really don't need retry allocations when the disk is very full as aggressively any more. The only time when it makes sense to retry an allocation is if we have freshly deleted blocks that will only become available after a transaction commit. And if we lose that race, it's not worth it to try more than once. Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/balloc.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index e04ec868e37e..a3798b25a8dc 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -600,22 +600,21 @@ int ext4_claim_free_clusters(struct ext4_sb_info *sbi,
600 * ext4_should_retry_alloc() is called when ENOSPC is returned, and if 600 * ext4_should_retry_alloc() is called when ENOSPC is returned, and if
601 * it is profitable to retry the operation, this function will wait 601 * it is profitable to retry the operation, this function will wait
602 * for the current or committing transaction to complete, and then 602 * for the current or committing transaction to complete, and then
603 * return TRUE. 603 * return TRUE. We will only retry once.
604 *
605 * if the total number of retries exceed three times, return FALSE.
606 */ 604 */
607int ext4_should_retry_alloc(struct super_block *sb, int *retries) 605int ext4_should_retry_alloc(struct super_block *sb, int *retries)
608{ 606{
609 if (!ext4_has_free_clusters(EXT4_SB(sb), 1, 0) || 607 if (!ext4_has_free_clusters(EXT4_SB(sb), 1, 0) ||
610 (*retries)++ > 3 || 608 (*retries)++ > 1 ||
611 !EXT4_SB(sb)->s_journal) 609 !EXT4_SB(sb)->s_journal)
612 return 0; 610 return 0;
613 611
614 jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
615
616 smp_mb(); 612 smp_mb();
617 if (EXT4_SB(sb)->s_mb_free_pending) 613 if (EXT4_SB(sb)->s_mb_free_pending == 0)
618 jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal); 614 return 0;
615
616 jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
617 jbd2_journal_force_commit_nested(EXT4_SB(sb)->s_journal);
619 return 1; 618 return 1;
620} 619}
621 620