Skip to content

Commit

Permalink
ext4: fix data corruption caused by overlapping unaligned and aligned IO
Browse files Browse the repository at this point in the history
commit 57a0da2 upstream.

Unaligned AIO must be serialized because the zeroing of partial blocks
of unaligned AIO can result in data corruption in case it's overlapping
another in flight IO.

Currently we wait for all unwritten extents before we submit unaligned
AIO which protects data in case of unaligned AIO is following overlapping
IO. However if a unaligned AIO is followed by overlapping aligned AIO we
can still end up corrupting data.

To fix this, we must make sure that the unaligned AIO is the only IO in
flight by waiting for unwritten extents conversion not just before the
IO submission, but right after it as well.

This problem can be reproduced by xfstest generic/538

Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Lukas Czerner authored and Greg Kroah-Hartman committed May 21, 2019
1 parent ab6d14e commit fa08977
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions fs/ext4/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
}

ret = __generic_file_write_iter(iocb, from);
/*
* Unaligned direct AIO must be the only IO in flight. Otherwise
* overlapping aligned IO after unaligned might result in data
* corruption.
*/
if (ret == -EIOCBQUEUED && unaligned_aio)
ext4_unwritten_wait(inode);
inode_unlock(inode);

if (ret > 0)
Expand Down

0 comments on commit fa08977

Please sign in to comment.