aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/fs/iomap/direct-io.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2021-07-23 01:59:41 +0200
committerAndreas Gruenbacher <agruenba@redhat.com>2021-10-24 15:26:05 +0200
commit97308f8b0d867e9ef59528cd97f0db55ffdf5651 (patch)
treeddf419571b6bf50ea98c445d822627b24a5fbb0b /fs/iomap/direct-io.c
parentiomap: Fix iomap_dio_rw return value for user copies (diff)
downloadwireguard-linux-97308f8b0d867e9ef59528cd97f0db55ffdf5651.tar.xz
wireguard-linux-97308f8b0d867e9ef59528cd97f0db55ffdf5651.zip
iomap: Support partial direct I/O on user copy failures
In iomap_dio_rw, when iomap_apply returns an -EFAULT error and the IOMAP_DIO_PARTIAL flag is set, complete the request synchronously and return a partial result. This allows the caller to deal with the page fault and retry the remainder of the request. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/iomap/direct-io.c')
-rw-r--r--fs/iomap/direct-io.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index a2a368e824c0..a434fb7887b2 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -581,6 +581,12 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
if (iov_iter_rw(iter) == READ && iomi.pos >= dio->i_size)
iov_iter_revert(iter, iomi.pos - dio->i_size);
+ if (ret == -EFAULT && dio->size && (dio_flags & IOMAP_DIO_PARTIAL)) {
+ if (!(iocb->ki_flags & IOCB_NOWAIT))
+ wait_for_completion = true;
+ ret = 0;
+ }
+
/* magic error code to fall back to buffered I/O */
if (ret == -ENOTBLK) {
wait_for_completion = true;