Skip to content

Commit 4c3c094

Browse files
committed
io_uring: support MSG_WAITALL for IORING_OP_SEND(MSG)
Like commit 7ba89d2 for recv/recvmsg, support MSG_WAITALL for the send side. If this flag is set and we do a short send, retry for a stream of seqpacket socket. Signed-off-by: Jens Axboe <[email protected]>
1 parent 970f256 commit 4c3c094

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

fs/io_uring.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5235,6 +5235,13 @@ static int io_sync_file_range(struct io_kiocb *req, unsigned int issue_flags)
52355235
}
52365236

52375237
#if defined(CONFIG_NET)
5238+
static bool io_net_retry(struct socket *sock, int flags)
5239+
{
5240+
if (!(flags & MSG_WAITALL))
5241+
return false;
5242+
return sock->type == SOCK_STREAM || sock->type == SOCK_SEQPACKET;
5243+
}
5244+
52385245
static int io_setup_async_msg(struct io_kiocb *req,
52395246
struct io_async_msghdr *kmsg)
52405247
{
@@ -5293,12 +5300,14 @@ static int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
52935300
if (req->ctx->compat)
52945301
sr->msg_flags |= MSG_CMSG_COMPAT;
52955302
#endif
5303+
sr->done_io = 0;
52965304
return 0;
52975305
}
52985306

52995307
static int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags)
53005308
{
53015309
struct io_async_msghdr iomsg, *kmsg;
5310+
struct io_sr_msg *sr = &req->sr_msg;
53025311
struct socket *sock;
53035312
unsigned flags;
53045313
int min_ret = 0;
@@ -5330,12 +5339,21 @@ static int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags)
53305339
return io_setup_async_msg(req, kmsg);
53315340
if (ret == -ERESTARTSYS)
53325341
ret = -EINTR;
5342+
if (ret > 0 && io_net_retry(sock, flags)) {
5343+
sr->done_io += ret;
5344+
req->flags |= REQ_F_PARTIAL_IO;
5345+
return io_setup_async_msg(req, kmsg);
5346+
}
53335347
req_set_fail(req);
53345348
}
53355349
/* fast path, check for non-NULL to avoid function call */
53365350
if (kmsg->free_iov)
53375351
kfree(kmsg->free_iov);
53385352
req->flags &= ~REQ_F_NEED_CLEANUP;
5353+
if (ret >= 0)
5354+
ret += sr->done_io;
5355+
else if (sr->done_io)
5356+
ret = sr->done_io;
53395357
__io_req_complete(req, issue_flags, ret, 0);
53405358
return 0;
53415359
}
@@ -5376,8 +5394,19 @@ static int io_send(struct io_kiocb *req, unsigned int issue_flags)
53765394
return -EAGAIN;
53775395
if (ret == -ERESTARTSYS)
53785396
ret = -EINTR;
5397+
if (ret > 0 && io_net_retry(sock, flags)) {
5398+
sr->len -= ret;
5399+
sr->buf += ret;
5400+
sr->done_io += ret;
5401+
req->flags |= REQ_F_PARTIAL_IO;
5402+
return -EAGAIN;
5403+
}
53795404
req_set_fail(req);
53805405
}
5406+
if (ret >= 0)
5407+
ret += sr->done_io;
5408+
else if (sr->done_io)
5409+
ret = sr->done_io;
53815410
__io_req_complete(req, issue_flags, ret, 0);
53825411
return 0;
53835412
}
@@ -5509,13 +5538,6 @@ static int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
55095538
return 0;
55105539
}
55115540

5512-
static bool io_net_retry(struct socket *sock, int flags)
5513-
{
5514-
if (!(flags & MSG_WAITALL))
5515-
return false;
5516-
return sock->type == SOCK_STREAM || sock->type == SOCK_SEQPACKET;
5517-
}
5518-
55195541
static int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags)
55205542
{
55215543
struct io_async_msghdr iomsg, *kmsg;

0 commit comments

Comments
 (0)