From 654493cf8195cc9cd0ef4c201d652722f4d82e85 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 14 Sep 2020 09:30:38 -0600 Subject: [PATCH 2410/2944] io_uring: don't use retry based buffered reads for non-async bdev task #31332859 commit f5cac8b156e8b7b67bb0fdfd19900855bf9569f3 upstream. Some block devices, like dm, bubble back -EAGAIN through the completion handler. We check for this in io_read(), but don't honor it for when we have copied the iov. Return -EAGAIN for this case before retrying, to force punt to io-wq. Backport Notes: manully apply the diff chunks since io_read() is a bit different between 5.10's and our 4.19's Fixes: bcf5a06304d6 ("io_uring: support true async buffered reads, if file provides it") Reported-by: Zorro Lang Tested-by: Zorro Lang Signed-off-by: Jens Axboe Signed-off-by: Hao Xu Reviewed-by: Joseph Qi --- fs/io_uring.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index b61fb1a..7dd75b6 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2956,6 +2956,7 @@ static int io_read(struct io_kiocb *req, bool force_nonblock) struct iov_iter iter; size_t iov_count; ssize_t io_size, ret; + bool no_async; ret = io_import_iovec(READ, req, &iovec, &iter, !force_nonblock); if (ret < 0) @@ -2974,7 +2975,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock) * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so * we know to async punt it even if it was opened O_NONBLOCK */ - if (force_nonblock && !io_file_supports_async(req->file, READ)) + no_async = force_nonblock && !io_file_supports_async(req->file, READ); + if (no_async) goto copy_iov; iov_count = iov_iter_count(&iter); @@ -3000,6 +3002,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock) if (!(req->flags & REQ_F_NOWAIT) && !file_can_poll(req->file)) req->flags |= REQ_F_MUST_PUNT; + if (no_async) + return -EAGAIN; /* if we can retry, do so with the callbacks armed */ if (io_rw_should_retry(req)) { ret2 = io_iter_do_read(req, &iter); -- 1.8.3.1