summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorGabriel Krisman Bertazi <krisman@collabora.com>2020-10-08 08:26:19 +0200
committerJan Kara <jack@suse.cz>2020-10-08 18:26:33 +0200
commit0a9164cb7ff32d6936f14657aebc3c4c2a0d5f9d (patch)
treebbba9006d7180638d8384c0702dd47f041b8c83e /fs
parentdirect-io: clean up error paths of do_blockdev_direct_IO (diff)
downloadlinux-0a9164cb7ff32d6936f14657aebc3c4c2a0d5f9d.tar.xz
linux-0a9164cb7ff32d6936f14657aebc3c4c2a0d5f9d.zip
direct-io: don't force writeback for reads beyond EOF
If a DIO read starts past EOF, the kernel won't attempt it, so we don't need to flush dirty pages before failing the syscall. Link: https://lore.kernel.org/r/20201008062620.2928326-3-krisman@collabora.com Suggested-by: Jan Kara <jack@suse.cz> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs')
-rw-r--r--fs/direct-io.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 6c11db1cec27..c17efe58f1c9 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1188,19 +1188,9 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
memset(dio, 0, offsetof(struct dio, pages));
dio->flags = flags;
- if (dio->flags & DIO_LOCKING) {
- if (iov_iter_rw(iter) == READ) {
- struct address_space *mapping =
- iocb->ki_filp->f_mapping;
-
- /* will be released by direct_io_worker */
- inode_lock(inode);
-
- retval = filemap_write_and_wait_range(mapping, offset,
- end - 1);
- if (retval)
- goto fail_dio;
- }
+ if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) {
+ /* will be released by direct_io_worker */
+ inode_lock(inode);
}
/* Once we sampled i_size check for reads beyond EOF */
@@ -1210,6 +1200,14 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
goto fail_dio;
}
+ if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) {
+ struct address_space *mapping = iocb->ki_filp->f_mapping;
+
+ retval = filemap_write_and_wait_range(mapping, offset, end - 1);
+ if (retval)
+ goto fail_dio;
+ }
+
/*
* For file extending writes updating i_size before data writeouts
* complete can expose uninitialized blocks in dumb filesystems.