Skip to content
/ linux Public

Commit 7443147

Browse files
zhangyi089Sasha Levin
authored andcommitted
ext4: use reserved metadata blocks when splitting extent on endio
[ Upstream commit 01942af ] When performing buffered writes, we may need to split and convert an unwritten extent into a written one during the end I/O process. However, we do not reserve space specifically for these metadata changes, we only reserve 2% of space or 4096 blocks. To address this, we use EXT4_GET_BLOCKS_PRE_IO to potentially split extents in advance and EXT4_GET_BLOCKS_METADATA_NOFAIL to utilize reserved space if necessary. These two approaches can reduce the likelihood of running out of space and losing data. However, these methods are merely best efforts, we could still run out of space, and there is not much difference between converting an extent during the writeback process and the end I/O process, it won't increase the risk of losing data if we postpone the conversion. Therefore, also use EXT4_GET_BLOCKS_METADATA_NOFAIL in ext4_convert_unwritten_extents_endio() to prepare for the buffered I/O iomap conversion, which may perform extent conversion during the end I/O process. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Baokun Li <libaokun1@huawei.com> Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com> Link: https://patch.msgid.link/20260105014522.1937690-2-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 3b3c11f commit 7443147

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

fs/ext4/extents.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3805,14 +3805,16 @@ ext4_convert_unwritten_extents_endio(handle_t *handle, struct inode *inode,
38053805
* illegal.
38063806
*/
38073807
if (ee_block != map->m_lblk || ee_len > map->m_len) {
3808+
int flags = EXT4_GET_BLOCKS_CONVERT |
3809+
EXT4_GET_BLOCKS_METADATA_NOFAIL;
38083810
#ifdef CONFIG_EXT4_DEBUG
38093811
ext4_warning(inode->i_sb, "Inode (%ld) finished: extent logical block %llu,"
38103812
" len %u; IO logical block %llu, len %u",
38113813
inode->i_ino, (unsigned long long)ee_block, ee_len,
38123814
(unsigned long long)map->m_lblk, map->m_len);
38133815
#endif
38143816
path = ext4_split_convert_extents(handle, inode, map, path,
3815-
EXT4_GET_BLOCKS_CONVERT, NULL);
3817+
flags, NULL);
38163818
if (IS_ERR(path))
38173819
return path;
38183820

0 commit comments

Comments
 (0)