io_uring: short circuit -EAGAIN for blocking read attempt
authorJens Axboe <axboe@kernel.dk>
Sat, 15 Aug 2020 22:58:42 +0000 (15:58 -0700)
committerJens Axboe <axboe@kernel.dk>
Sat, 15 Aug 2020 22:58:42 +0000 (15:58 -0700)
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>
fs/io_uring.c

index cb03091..dc506b7 100644 (file)
@@ -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;