Skip to content

Commit 4a2d984

Browse files
LiBaokun96tytso
authored andcommitted
ext4: using nofail preallocation in ext4_es_insert_delayed_block()
Similar to in ext4_es_remove_extent(), we use a no-fail preallocation to avoid inconsistencies, except that here we may have to preallocate two extent_status. Suggested-by: Jan Kara <jack@suse.cz> Signed-off-by: Baokun Li <libaokun1@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/20230424033846.4732-8-libaokun1@huawei.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent e9fe2b8 commit 4a2d984

1 file changed

Lines changed: 22 additions & 11 deletions

File tree

fs/ext4/extents_status.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,7 +2009,10 @@ int ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
20092009
bool allocated)
20102010
{
20112011
struct extent_status newes;
2012-
int err = 0;
2012+
int err1 = 0;
2013+
int err2 = 0;
2014+
struct extent_status *es1 = NULL;
2015+
struct extent_status *es2 = NULL;
20132016

20142017
if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
20152018
return 0;
@@ -2024,29 +2027,37 @@ int ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
20242027

20252028
ext4_es_insert_extent_check(inode, &newes);
20262029

2030+
retry:
2031+
if (err1 && !es1)
2032+
es1 = __es_alloc_extent(true);
2033+
if ((err1 || err2) && !es2)
2034+
es2 = __es_alloc_extent(true);
20272035
write_lock(&EXT4_I(inode)->i_es_lock);
20282036

2029-
err = __es_remove_extent(inode, lblk, lblk, NULL, NULL);
2030-
if (err != 0)
2037+
err1 = __es_remove_extent(inode, lblk, lblk, NULL, es1);
2038+
if (err1 != 0)
20312039
goto error;
2032-
retry:
2033-
err = __es_insert_extent(inode, &newes, NULL);
2034-
if (err == -ENOMEM && __es_shrink(EXT4_SB(inode->i_sb),
2035-
128, EXT4_I(inode)))
2036-
goto retry;
2037-
if (err != 0)
2040+
2041+
err2 = __es_insert_extent(inode, &newes, es2);
2042+
if (err2 != 0)
20382043
goto error;
20392044

20402045
if (allocated)
20412046
__insert_pending(inode, lblk);
20422047

2048+
/* es is pre-allocated but not used, free it. */
2049+
if (es1 && !es1->es_len)
2050+
__es_free_extent(es1);
2051+
if (es2 && !es2->es_len)
2052+
__es_free_extent(es2);
20432053
error:
20442054
write_unlock(&EXT4_I(inode)->i_es_lock);
2055+
if (err1 || err2)
2056+
goto retry;
20452057

20462058
ext4_es_print_tree(inode);
20472059
ext4_print_pending_tree(inode);
2048-
2049-
return err;
2060+
return 0;
20502061
}
20512062

20522063
/*

0 commit comments

Comments
 (0)