FAILED: patch "[PATCH] io_uring: ensure recv and recvmsg handle MSG_WAITALL" failed to apply to 5.15-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 7ba89d2af17aa879dda30f5d5d3f152e587fc551 Mon Sep 17 00:00:00 2001
From: Jens Axboe <[email protected]>
Date: Wed, 23 Mar 2022 09:32:35 -0600
Subject: [PATCH] io_uring: ensure recv and recvmsg handle MSG_WAITALL
correctly
We currently don't attempt to get the full asked for length even if MSG_WAITALL is set, if we get a partial receive. If we do see a partial receive, then just note how many bytes we did and return -EAGAIN to get it retried.
The iov is advanced appropriately for the vector based case, and we manually bump the buffer and remainder for the non-vector case.
fs/io_uring.c +28 -0
@@ -612,6 +612,7 @@ struct io_sr_msg {int msg_flags;int bgid;size_t len; +size_t done_io; };struct io_open {
@@ -5417,12 +5418,21 @@ static int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)if (req->ctx->compat) sr->msg_flags |=MSG_CMSG_COMPAT ;#endif + sr->done_io =0 ;return 0 ; } +static bool io_net_retry (struct socket *sock,int flags) +{ +if (!(flags &MSG_WAITALL )) +return false; +return sock->type ==SOCK_STREAM || sock->type ==SOCK_SEQPACKET ; +} +static int io_recvmsg (struct io_kiocb *req,unsigned int issue_flags) {struct io_async_msghdr iomsg, *kmsg; +struct io_sr_msg *sr = &req->sr_msg;struct socket *sock;struct io_buffer *kbuf;unsigned flags;
@@ -5465,6 +5475,10 @@ static int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags)return io_setup_async_msg (req, kmsg);if (ret == -ERESTARTSYS ) ret = -EINTR ; +if (ret >0 &&io_net_retry (sock, flags)) { + sr->done_io += ret; +return io_setup_async_msg (req, kmsg); + }req_set_fail (req); }else if ((flags &MSG_WAITALL ) && (kmsg->msg.msg_flags & (MSG_TRUNC |MSG_CTRUNC ))) {req_set_fail (req);
@@ -5474,6 +5488,10 @@ static int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags)if (kmsg->free_iov)kfree (kmsg->free_iov); req->flags &= ~REQ_F_NEED_CLEANUP ; +if (ret >=0 ) + ret += sr->done_io; +else if (sr->done_io) + ret = sr->done_io;__io_req_complete (req, issue_flags, ret,io_put_kbuf (req, issue_flags));return 0 ; }
@@ -5524,12 +5542,22 @@ static int io_recv(struct io_kiocb *req, unsigned int issue_flags)return -EAGAIN ;if (ret == -ERESTARTSYS ) ret = -EINTR ; +if (ret >0 &&io_net_retry (sock, flags)) { + sr->len -= ret; + sr->buf += ret; + sr->done_io += ret; +return -EAGAIN ; + }req_set_fail (req); }else if ((flags &MSG_WAITALL ) && (msg.msg_flags & (MSG_TRUNC |MSG_CTRUNC ))) { out_free:req_set_fail (req); } +if (ret >=0 ) + ret += sr->done_io; +else if (sr->done_io) + ret = sr->done_io;__io_req_complete (req, issue_flags, ret,io_put_kbuf (req, issue_flags));return 0 ; }