Skip to content

Commit c314094

Browse files
committed
io_uring/net: harden multishot termination case for recv
If the recv returns zero, or an error, then it doesn't matter if more data has already been received for this buffer. A condition like that should terminate the multishot receive. Rather than pass in the collected return value, pass in whether to terminate or keep the recv going separately. Note that this isn't a bug right now, as the only way to get there is via setting MSG_WAITALL with multishot receive. And if an application does that, then -EINVAL is returned anyway. But it seems like an easy bug to introduce, so let's make it a bit more explicit. Link: axboe/liburing#1246 Cc: [email protected] Fixes: b3fdea6 ("io_uring: multishot recv") Signed-off-by: Jens Axboe <[email protected]>
1 parent 17ea56b commit c314094

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

io_uring/net.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,7 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)
11331133
int ret, min_ret = 0;
11341134
bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
11351135
size_t len = sr->len;
1136+
bool mshot_finished;
11361137

11371138
if (!(req->flags & REQ_F_POLLED) &&
11381139
(sr->flags & IORING_RECVSEND_POLL_FIRST))
@@ -1187,14 +1188,15 @@ int io_recv(struct io_kiocb *req, unsigned int issue_flags)
11871188
req_set_fail(req);
11881189
}
11891190

1191+
mshot_finished = ret <= 0;
11901192
if (ret > 0)
11911193
ret += sr->done_io;
11921194
else if (sr->done_io)
11931195
ret = sr->done_io;
11941196
else
11951197
io_kbuf_recycle(req, issue_flags);
11961198

1197-
if (!io_recv_finish(req, &ret, kmsg, ret <= 0, issue_flags))
1199+
if (!io_recv_finish(req, &ret, kmsg, mshot_finished, issue_flags))
11981200
goto retry_multishot;
11991201

12001202
return ret;

0 commit comments

Comments
 (0)