Commit c5b85625 authored by Jens Axboe's avatar Jens Axboe
Browse files

io_uring: allow O_NONBLOCK async retry



We can assume that O_NONBLOCK is always honored, even if we don't
have a ->read/write_iter() for the file type. Also unify the read/write
checking for allowing async punt, having the write side factoring in the
REQ_F_NOWAIT flag as well.

Cc: stable@vger.kernel.org
Fixes: 490e8967 ("io_uring: only force async punt if poll based retry can't handle it")
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent f5fa38c5
Loading
Loading
Loading
Loading
+7 −3
Original line number Original line Diff line number Diff line
@@ -2061,6 +2061,10 @@ static bool io_file_supports_async(struct file *file, int rw)
	if (S_ISREG(mode) && file->f_op != &io_uring_fops)
	if (S_ISREG(mode) && file->f_op != &io_uring_fops)
		return true;
		return true;


	/* any ->read/write should understand O_NONBLOCK */
	if (file->f_flags & O_NONBLOCK)
		return true;

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


@@ -2103,8 +2107,7 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe,
		kiocb->ki_ioprio = get_current_ioprio();
		kiocb->ki_ioprio = get_current_ioprio();


	/* don't allow async punt if RWF_NOWAIT was requested */
	/* don't allow async punt if RWF_NOWAIT was requested */
	if ((kiocb->ki_flags & IOCB_NOWAIT) ||
	if (kiocb->ki_flags & IOCB_NOWAIT)
	    (req->file->f_flags & O_NONBLOCK))
		req->flags |= REQ_F_NOWAIT;
		req->flags |= REQ_F_NOWAIT;


	if (force_nonblock)
	if (force_nonblock)
@@ -2745,7 +2748,8 @@ static int io_write(struct io_kiocb *req, bool force_nonblock)
			if (ret)
			if (ret)
				goto out_free;
				goto out_free;
			/* any defer here is final, must blocking retry */
			/* any defer here is final, must blocking retry */
			if (!file_can_poll(req->file))
			if (!(req->flags & REQ_F_NOWAIT) &&
			    !file_can_poll(req->file))
				req->flags |= REQ_F_MUST_PUNT;
				req->flags |= REQ_F_MUST_PUNT;
			return -EAGAIN;
			return -EAGAIN;
		}
		}