diff options
author | Gabriel Krisman Bertazi <krisman@collabora.com> | 2020-10-08 08:26:19 +0200 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2020-10-08 18:26:33 +0200 |
commit | 0a9164cb7ff32d6936f14657aebc3c4c2a0d5f9d (patch) | |
tree | bbba9006d7180638d8384c0702dd47f041b8c83e /fs | |
parent | direct-io: clean up error paths of do_blockdev_direct_IO (diff) | |
download | linux-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.c | 24 |
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. |