Skip to content

Commit 9e4c6c1

Browse files
committed
Merge tag 'io_uring-6.12-20241011' of git://git.kernel.dk/linux
Pull io_uring fixes from Jens Axboe: - Explicitly have a mshot_finished condition for IORING_OP_RECV in multishot mode, similarly to what IORING_OP_RECVMSG has. This doesn't fix a bug right now, but it makes it harder to actually have a bug here if a request takes multiple iterations to finish. - Fix handling of retry of read/write of !FMODE_NOWAIT files. If they are pollable, that's all we need. * tag 'io_uring-6.12-20241011' of git://git.kernel.dk/linux: io_uring/rw: allow pollable non-blocking attempts for !FMODE_NOWAIT io_uring/rw: fix cflags posting for single issue multishot read
2 parents e643eda + f7c9134 commit 9e4c6c1

File tree

1 file changed

+24
-20
lines changed

1 file changed

+24
-20
lines changed

io_uring/rw.c

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,19 @@ struct io_rw {
3131
rwf_t flags;
3232
};
3333

34-
static inline bool io_file_supports_nowait(struct io_kiocb *req)
34+
static bool io_file_supports_nowait(struct io_kiocb *req, __poll_t mask)
3535
{
36-
return req->flags & REQ_F_SUPPORT_NOWAIT;
36+
/* If FMODE_NOWAIT is set for a file, we're golden */
37+
if (req->flags & REQ_F_SUPPORT_NOWAIT)
38+
return true;
39+
/* No FMODE_NOWAIT, if we can poll, check the status */
40+
if (io_file_can_poll(req)) {
41+
struct poll_table_struct pt = { ._key = mask };
42+
43+
return vfs_poll(req->file, &pt) & mask;
44+
}
45+
/* No FMODE_NOWAIT support, and file isn't pollable. Tough luck. */
46+
return false;
3747
}
3848

3949
#ifdef CONFIG_COMPAT
@@ -796,8 +806,8 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode, int rw_type)
796806
* supports async. Otherwise it's impossible to use O_NONBLOCK files
797807
* reliably. If not, or it IOCB_NOWAIT is set, don't retry.
798808
*/
799-
if ((kiocb->ki_flags & IOCB_NOWAIT) ||
800-
((file->f_flags & O_NONBLOCK) && !io_file_supports_nowait(req)))
809+
if (kiocb->ki_flags & IOCB_NOWAIT ||
810+
((file->f_flags & O_NONBLOCK && (req->flags & REQ_F_SUPPORT_NOWAIT))))
801811
req->flags |= REQ_F_NOWAIT;
802812

803813
if (ctx->flags & IORING_SETUP_IOPOLL) {
@@ -838,7 +848,7 @@ static int __io_read(struct io_kiocb *req, unsigned int issue_flags)
838848

839849
if (force_nonblock) {
840850
/* If the file doesn't support async, just async punt */
841-
if (unlikely(!io_file_supports_nowait(req)))
851+
if (unlikely(!io_file_supports_nowait(req, EPOLLIN)))
842852
return -EAGAIN;
843853
kiocb->ki_flags |= IOCB_NOWAIT;
844854
} else {
@@ -951,13 +961,6 @@ int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags)
951961

952962
ret = __io_read(req, issue_flags);
953963

954-
/*
955-
* If the file doesn't support proper NOWAIT, then disable multishot
956-
* and stay in single shot mode.
957-
*/
958-
if (!io_file_supports_nowait(req))
959-
req->flags &= ~REQ_F_APOLL_MULTISHOT;
960-
961964
/*
962965
* If we get -EAGAIN, recycle our buffer and just let normal poll
963966
* handling arm it.
@@ -972,14 +975,15 @@ int io_read_mshot(struct io_kiocb *req, unsigned int issue_flags)
972975
if (issue_flags & IO_URING_F_MULTISHOT)
973976
return IOU_ISSUE_SKIP_COMPLETE;
974977
return -EAGAIN;
975-
}
976-
977-
/*
978-
* Any successful return value will keep the multishot read armed.
979-
*/
980-
if (ret > 0 && req->flags & REQ_F_APOLL_MULTISHOT) {
978+
} else if (ret <= 0) {
979+
io_kbuf_recycle(req, issue_flags);
980+
if (ret < 0)
981+
req_set_fail(req);
982+
} else {
981983
/*
982-
* Put our buffer and post a CQE. If we fail to post a CQE, then
984+
* Any successful return value will keep the multishot read
985+
* armed, if it's still set. Put our buffer and post a CQE. If
986+
* we fail to post a CQE, or multishot is no longer set, then
983987
* jump to the termination path. This request is then done.
984988
*/
985989
cflags = io_put_kbuf(req, ret, issue_flags);
@@ -1026,7 +1030,7 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags)
10261030

10271031
if (force_nonblock) {
10281032
/* If the file doesn't support async, just async punt */
1029-
if (unlikely(!io_file_supports_nowait(req)))
1033+
if (unlikely(!io_file_supports_nowait(req, EPOLLOUT)))
10301034
goto ret_eagain;
10311035

10321036
/* Check if we can support NOWAIT. */

0 commit comments

Comments
 (0)