Skip to content

Commit

Permalink
io_uring: enable poll retry for any file with ->read_iter / ->write_iter
Browse files Browse the repository at this point in the history
We can have files like eventfd where it's perfectly fine to do poll
based retry on them, right now io_file_supports_async() doesn't take
that into account.

Pass in data direction and check the f_op instead of just always needing
an async worker.

Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
axboe committed May 1, 2020
1 parent 5b0bbee commit af197f5
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions fs/io_uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -2038,7 +2038,7 @@ static struct file *__io_file_get(struct io_submit_state *state, int fd)
* any file. For now, just ensure that anything potentially problematic is done
* inline.
*/
static bool io_file_supports_async(struct file *file)
static bool io_file_supports_async(struct file *file, int rw)
{
umode_t mode = file_inode(file)->i_mode;

Expand All @@ -2047,7 +2047,13 @@ static bool io_file_supports_async(struct file *file)
if (S_ISREG(mode) && file->f_op != &io_uring_fops)
return true;

return false;
if (!(file->f_mode & FMODE_NOWAIT))
return false;

if (rw == READ)
return file->f_op->read_iter != NULL;

return file->f_op->write_iter != NULL;
}

static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe,
Expand Down Expand Up @@ -2575,7 +2581,7 @@ 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))
if (force_nonblock && !io_file_supports_async(req->file, READ))
goto copy_iov;

iov_count = iov_iter_count(&iter);
Expand Down Expand Up @@ -2666,7 +2672,7 @@ static int io_write(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))
if (force_nonblock && !io_file_supports_async(req->file, WRITE))
goto copy_iov;

/* file path doesn't support NOWAIT for non-direct_IO */
Expand Down Expand Up @@ -2760,11 +2766,11 @@ static int io_splice_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
return 0;
}

static bool io_splice_punt(struct file *file)
static bool io_splice_punt(struct file *file, int rw)
{
if (get_pipe_info(file))
return false;
if (!io_file_supports_async(file))
if (!io_file_supports_async(file, rw))
return true;
return !(file->f_flags & O_NONBLOCK);
}
Expand All @@ -2779,7 +2785,7 @@ static int io_splice(struct io_kiocb *req, bool force_nonblock)
long ret;

if (force_nonblock) {
if (io_splice_punt(in) || io_splice_punt(out))
if (io_splice_punt(in, READ) || io_splice_punt(out, WRITE))
return -EAGAIN;
flags |= SPLICE_F_NONBLOCK;
}
Expand Down

0 comments on commit af197f5

Please sign in to comment.