]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.45/ext4-fix-data-corruption-caused-by-overlapping-unaligned-and-aligned-io.patch
drop queue-4.14/mips-make-sure-dt-memory-regions-are-valid.patch
[thirdparty/kernel/stable-queue.git] / releases / 4.19.45 / ext4-fix-data-corruption-caused-by-overlapping-unaligned-and-aligned-io.patch
CommitLineData
ebe9a58d
GKH
1From 57a0da28ced8707cb9f79f071a016b9d005caf5a Mon Sep 17 00:00:00 2001
2From: Lukas Czerner <lczerner@redhat.com>
3Date: Fri, 10 May 2019 21:45:33 -0400
4Subject: ext4: fix data corruption caused by overlapping unaligned and aligned IO
5
6From: Lukas Czerner <lczerner@redhat.com>
7
8commit 57a0da28ced8707cb9f79f071a016b9d005caf5a upstream.
9
10Unaligned AIO must be serialized because the zeroing of partial blocks
11of unaligned AIO can result in data corruption in case it's overlapping
12another in flight IO.
13
14Currently we wait for all unwritten extents before we submit unaligned
15AIO which protects data in case of unaligned AIO is following overlapping
16IO. However if a unaligned AIO is followed by overlapping aligned AIO we
17can still end up corrupting data.
18
19To fix this, we must make sure that the unaligned AIO is the only IO in
20flight by waiting for unwritten extents conversion not just before the
21IO submission, but right after it as well.
22
23This problem can be reproduced by xfstest generic/538
24
25Signed-off-by: Lukas Czerner <lczerner@redhat.com>
26Signed-off-by: Theodore Ts'o <tytso@mit.edu>
27Cc: stable@kernel.org
28Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
29
30---
31 fs/ext4/file.c | 7 +++++++
32 1 file changed, 7 insertions(+)
33
34--- a/fs/ext4/file.c
35+++ b/fs/ext4/file.c
36@@ -264,6 +264,13 @@ ext4_file_write_iter(struct kiocb *iocb,
37 }
38
39 ret = __generic_file_write_iter(iocb, from);
40+ /*
41+ * Unaligned direct AIO must be the only IO in flight. Otherwise
42+ * overlapping aligned IO after unaligned might result in data
43+ * corruption.
44+ */
45+ if (ret == -EIOCBQUEUED && unaligned_aio)
46+ ext4_unwritten_wait(inode);
47 inode_unlock(inode);
48
49 if (ret > 0)