direct-io: don't force writeback for reads beyond EOF
authorGabriel Krisman Bertazi <krisman@collabora.com>
Thu, 8 Oct 2020 06:26:19 +0000 (02:26 -0400)
committerJan Kara <jack@suse.cz>
Thu, 8 Oct 2020 16:26:33 +0000 (18:26 +0200)
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>
fs/direct-io.c

index 6c11db1..c17efe5 100644 (file)
@@ -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.