io_uring: consider any io_read/write -EAGAIN as final

If the -EAGAIN happens because of a static condition, then a poll
or later retry won't fix it. We must call it again from blocking
condition. Play it safe and ensure that any -EAGAIN condition from read
or write must retry from async context.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Jens Axboe 2020-02-20 09:56:08 -07:00
parent 80ad894382
commit 29de5f6a35
1 changed files with 8 additions and 7 deletions

View File

@ -2234,7 +2234,7 @@ static int io_read(struct io_kiocb *req, struct io_kiocb **nxt,
/* Ensure we clear previously set non-block flag */
if (!force_nonblock)
req->rw.kiocb.ki_flags &= ~IOCB_NOWAIT;
kiocb->ki_flags &= ~IOCB_NOWAIT;
req->result = 0;
io_size = ret;
@ -2245,10 +2245,8 @@ static int io_read(struct io_kiocb *req, struct io_kiocb **nxt,
* 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)) {
req->flags |= REQ_F_MUST_PUNT;
if (force_nonblock && !io_file_supports_async(req->file))
goto copy_iov;
}
iov_count = iov_iter_count(&iter);
ret = rw_verify_area(READ, req->file, &kiocb->ki_pos, iov_count);
@ -2269,6 +2267,9 @@ copy_iov:
inline_vecs, &iter);
if (ret)
goto out_free;
/* any defer here is final, must blocking retry */
if (!(req->flags & REQ_F_NOWAIT))
req->flags |= REQ_F_MUST_PUNT;
return -EAGAIN;
}
}
@ -2334,10 +2335,8 @@ static int io_write(struct io_kiocb *req, struct io_kiocb **nxt,
* 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)) {
req->flags |= REQ_F_MUST_PUNT;
if (force_nonblock && !io_file_supports_async(req->file))
goto copy_iov;
}
/* file path doesn't support NOWAIT for non-direct_IO */
if (force_nonblock && !(kiocb->ki_flags & IOCB_DIRECT) &&
@ -2382,6 +2381,8 @@ copy_iov:
inline_vecs, &iter);
if (ret)
goto out_free;
/* any defer here is final, must blocking retry */
req->flags |= REQ_F_MUST_PUNT;
return -EAGAIN;
}
}