summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2020-08-16 00:58:42 +0200
committerJens Axboe <axboe@kernel.dk>2020-08-16 00:58:42 +0200
commitf91daf565b0e272a33bd3fcd19eaebd331c5cffd (patch)
treeebb9688b7038d2ec980ab1d3bbc798b874033406 /fs
parentio_uring: sanitize double poll handling (diff)
downloadlinux-f91daf565b0e272a33bd3fcd19eaebd331c5cffd.tar.xz
linux-f91daf565b0e272a33bd3fcd19eaebd331c5cffd.zip
io_uring: short circuit -EAGAIN for blocking read attempt
One case was missed in the short IO retry handling, and that's hitting -EAGAIN on a blocking attempt read (eg from io-wq context). This is a problem on sockets that are marked as non-blocking when created, they don't carry any REQ_F_NOWAIT information to help us terminate them instead of perpetually retrying. Fixes: 227c0c9673d8 ("io_uring: internally retry short reads") Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs')
-rw-r--r--fs/io_uring.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index cb030912bf5e..dc506b75659c 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -3186,6 +3186,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock,
ret = 0;
goto out_free;
} else if (ret == -EAGAIN) {
+ if (!force_nonblock)
+ goto done;
ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false);
if (ret)
goto out_free;
@@ -3195,7 +3197,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock,
}
/* read it all, or we did blocking attempt. no retry. */
- if (!iov_iter_count(iter) || !force_nonblock)
+ if (!iov_iter_count(iter) || !force_nonblock ||
+ (req->file->f_flags & O_NONBLOCK))
goto done;
io_size -= ret;