From: Greg Kroah-Hartman Date: Mon, 14 Oct 2024 14:03:30 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v5.10.227~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5e367bdf852fc837c9e6a6c39071c23d42f1be7c;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: ext4-fix-warning-in-ext4_dio_write_end_io.patch --- diff --git a/queue-5.10/ext4-fix-warning-in-ext4_dio_write_end_io.patch b/queue-5.10/ext4-fix-warning-in-ext4_dio_write_end_io.patch new file mode 100644 index 00000000000..6dc9330e308 --- /dev/null +++ b/queue-5.10/ext4-fix-warning-in-ext4_dio_write_end_io.patch @@ -0,0 +1,64 @@ +From 619f75dae2cf117b1d07f27b046b9ffb071c4685 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 30 Nov 2023 10:56:53 +0100 +Subject: ext4: fix warning in ext4_dio_write_end_io() + +From: Jan Kara + +commit 619f75dae2cf117b1d07f27b046b9ffb071c4685 upstream. + +The syzbot has reported that it can hit the warning in +ext4_dio_write_end_io() because i_size < i_disksize. Indeed the +reproducer creates a race between DIO IO completion and truncate +expanding the file and thus ext4_dio_write_end_io() sees an inconsistent +inode state where i_disksize is already updated but i_size is not +updated yet. Since we are careful when setting up DIO write and consider +it extending (and thus performing the IO synchronously with i_rwsem held +exclusively) whenever it goes past either of i_size or i_disksize, we +can use the same test during IO completion without risking entering +ext4_handle_inode_extension() without i_rwsem held. This way we make it +obvious both i_size and i_disksize are large enough when we report DIO +completion without relying on unreliable WARN_ON. + +Reported-by: +Fixes: 91562895f803 ("ext4: properly sync file size update after O_SYNC direct IO") +Signed-off-by: Jan Kara +Reviewed-by: Ritesh Harjani (IBM) +Link: https://lore.kernel.org/r/20231130095653.22679-1-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/file.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -323,9 +323,10 @@ static void ext4_inode_extension_cleanup + return; + } + /* +- * If i_disksize got extended due to writeback of delalloc blocks while +- * the DIO was running we could fail to cleanup the orphan list in +- * ext4_handle_inode_extension(). Do it now. ++ * If i_disksize got extended either due to writeback of delalloc ++ * blocks or extending truncate while the DIO was running we could fail ++ * to cleanup the orphan list in ext4_handle_inode_extension(). Do it ++ * now. + */ + if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) { + handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); +@@ -360,10 +361,11 @@ static int ext4_dio_write_end_io(struct + * blocks. But the code in ext4_iomap_alloc() is careful to use + * zeroed/unwritten extents if this is possible; thus we won't leave + * uninitialized blocks in a file even if we didn't succeed in writing +- * as much as we intended. ++ * as much as we intended. Also we can race with truncate or write ++ * expanding the file so we have to be a bit careful here. + */ +- WARN_ON_ONCE(i_size_read(inode) < READ_ONCE(EXT4_I(inode)->i_disksize)); +- if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize)) ++ if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize) && ++ pos + size <= i_size_read(inode)) + return size; + return ext4_handle_inode_extension(inode, pos, size); + } diff --git a/queue-5.10/series b/queue-5.10/series index bb08207f741..7cafe7ee220 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -521,3 +521,4 @@ net-handle-l3mdev-in-ip_tunnel_init_flow.patch net-seg6-fix-seg6_lookup_any_nexthop-to-handle-vrfs-using-flowi_l3mdev.patch net-vrf-determine-the-dst-using-the-original-ifindex-for-multicast.patch netfilter-ip6t_rpfilter-fix-regression-with-vrf-interfaces.patch +ext4-fix-warning-in-ext4_dio_write_end_io.patch