Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+13
+6
fs/iomap/direct-io.c
··· 581 581 if (iov_iter_rw(iter) == READ && iomi.pos >= dio->i_size) 582 582 iov_iter_revert(iter, iomi.pos - dio->i_size); 583 583 584 + if (ret == -EFAULT && dio->size && (dio_flags & IOMAP_DIO_PARTIAL)) { 585 + if (!(iocb->ki_flags & IOCB_NOWAIT)) 586 + wait_for_completion = true; 587 + ret = 0; 588 + } 589 + 584 590 /* magic error code to fall back to buffered I/O */ 585 591 if (ret == -ENOTBLK) { 586 592 wait_for_completion = true;
+7
include/linux/iomap.h
··· 330 330 */ 331 331 #define IOMAP_DIO_OVERWRITE_ONLY (1 << 1) 332 332 333 + /* 334 + * When a page fault occurs, return a partial synchronous result and allow 335 + * the caller to retry the rest of the operation after dealing with the page 336 + * fault. 337 + */ 338 + #define IOMAP_DIO_PARTIAL (1 << 2) 339 + 333 340 ssize_t iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, 334 341 const struct iomap_ops *ops, const struct iomap_dio_ops *dops, 335 342 unsigned int dio_flags);