Skip to content

Commit 2a69c45

Browse files
LiBaokun96tytso
authored andcommitted
ext4: using nofail preallocation in ext4_es_insert_extent()
Similar to in ext4_es_insert_delayed_block(), we use preallocations that do not fail to avoid inconsistencies, but we do not care about es that are not must be kept, and we return 0 even if such es memory allocation fails. Suggested-by: Jan Kara <[email protected]> Signed-off-by: Baokun Li <[email protected]> Reviewed-by: Jan Kara <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 4a2d984 commit 2a69c45

File tree

1 file changed

+26
-12
lines changed

1 file changed

+26
-12
lines changed

fs/ext4/extents_status.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -838,8 +838,11 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
838838
{
839839
struct extent_status newes;
840840
ext4_lblk_t end = lblk + len - 1;
841-
int err = 0;
841+
int err1 = 0;
842+
int err2 = 0;
842843
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
844+
struct extent_status *es1 = NULL;
845+
struct extent_status *es2 = NULL;
843846

844847
if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
845848
return 0;
@@ -867,29 +870,40 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk,
867870

868871
ext4_es_insert_extent_check(inode, &newes);
869872

873+
retry:
874+
if (err1 && !es1)
875+
es1 = __es_alloc_extent(true);
876+
if ((err1 || err2) && !es2)
877+
es2 = __es_alloc_extent(true);
870878
write_lock(&EXT4_I(inode)->i_es_lock);
871-
err = __es_remove_extent(inode, lblk, end, NULL, NULL);
872-
if (err != 0)
879+
880+
err1 = __es_remove_extent(inode, lblk, end, NULL, es1);
881+
if (err1 != 0)
882+
goto error;
883+
884+
err2 = __es_insert_extent(inode, &newes, es2);
885+
if (err2 == -ENOMEM && !ext4_es_must_keep(&newes))
886+
err2 = 0;
887+
if (err2 != 0)
873888
goto error;
874-
retry:
875-
err = __es_insert_extent(inode, &newes, NULL);
876-
if (err == -ENOMEM && __es_shrink(EXT4_SB(inode->i_sb),
877-
128, EXT4_I(inode)))
878-
goto retry;
879-
if (err == -ENOMEM && !ext4_es_must_keep(&newes))
880-
err = 0;
881889

882890
if (sbi->s_cluster_ratio > 1 && test_opt(inode->i_sb, DELALLOC) &&
883891
(status & EXTENT_STATUS_WRITTEN ||
884892
status & EXTENT_STATUS_UNWRITTEN))
885893
__revise_pending(inode, lblk, len);
886894

895+
/* es is pre-allocated but not used, free it. */
896+
if (es1 && !es1->es_len)
897+
__es_free_extent(es1);
898+
if (es2 && !es2->es_len)
899+
__es_free_extent(es2);
887900
error:
888901
write_unlock(&EXT4_I(inode)->i_es_lock);
902+
if (err1 || err2)
903+
goto retry;
889904

890905
ext4_es_print_tree(inode);
891-
892-
return err;
906+
return 0;
893907
}
894908

895909
/*

0 commit comments

Comments
 (0)