mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-08 14:23:19 +00:00
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>
This commit is contained in:
parent
42c498c18a
commit
97308f8b0d
@ -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)
|
if (iov_iter_rw(iter) == READ && iomi.pos >= dio->i_size)
|
||||||
iov_iter_revert(iter, 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 */
|
/* magic error code to fall back to buffered I/O */
|
||||||
if (ret == -ENOTBLK) {
|
if (ret == -ENOTBLK) {
|
||||||
wait_for_completion = true;
|
wait_for_completion = true;
|
||||||
|
@ -330,6 +330,13 @@ struct iomap_dio_ops {
|
|||||||
*/
|
*/
|
||||||
#define IOMAP_DIO_OVERWRITE_ONLY (1 << 1)
|
#define IOMAP_DIO_OVERWRITE_ONLY (1 << 1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When a page fault occurs, return a partial synchronous result and allow
|
||||||
|
* the caller to retry the rest of the operation after dealing with the page
|
||||||
|
* fault.
|
||||||
|
*/
|
||||||
|
#define IOMAP_DIO_PARTIAL (1 << 2)
|
||||||
|
|
||||||
ssize_t iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
|
ssize_t iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
|
||||||
const struct iomap_ops *ops, const struct iomap_dio_ops *dops,
|
const struct iomap_ops *ops, const struct iomap_dio_ops *dops,
|
||||||
unsigned int dio_flags);
|
unsigned int dio_flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user