This is a note to let you know that I've just added the patch titled ext4: improve write performance with disabled delalloc to the 5.4-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: ext4-improve-write-performance-with-disabled-delallo.patch and it can be found in the queue-5.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit b761964a221739a6175a704f4e3304bd8b809f3f Author: Jan Kara <jack@xxxxxxx> Date: Fri May 20 13:14:02 2022 +0200 ext4: improve write performance with disabled delalloc [ Upstream commit 8d5459c11f548131ce48b2fbf45cccc5c382558f ] When delayed allocation is disabled (either through mount option or because we are running low on free space), ext4_write_begin() allocates blocks with EXT4_GET_BLOCKS_IO_CREATE_EXT flag. With this flag extent merging is disabled and since ext4_write_begin() is called for each page separately, we end up with a *lot* of 1 block extents in the extent tree and following writeback is writing 1 block at a time which results in very poor write throughput (4 MB/s instead of 200 MB/s). These days when ext4_get_block_unwritten() is used only by ext4_write_begin(), ext4_page_mkwrite() and inline data conversion, we can safely allow extent merging to happen from these paths since following writeback will happen on different boundaries anyway. So use EXT4_GET_BLOCKS_CREATE_UNRIT_EXT instead which restores the performance. Signed-off-by: Jan Kara <jack@xxxxxxx> Link: https://lore.kernel.org/r/20220520111402.4252-1-jack@xxxxxxx Signed-off-by: Theodore Ts'o <tytso@xxxxxxx> Stable-dep-of: 2cd8bdb5efc1 ("ext4: mark buffer new if it is unwritten to avoid stale data exposure") Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8a0bca3b653bc..9ca7db0c4039a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -830,7 +830,7 @@ int ext4_get_block_unwritten(struct inode *inode, sector_t iblock, ext4_debug("ext4_get_block_unwritten: inode %lu, create flag %d\n", inode->i_ino, create); return _ext4_get_block(inode, iblock, bh_result, - EXT4_GET_BLOCKS_IO_CREATE_EXT); + EXT4_GET_BLOCKS_CREATE_UNWRIT_EXT); } /* Maximum number of blocks we map for direct IO at once. */