1f9ead18cSJens Axboe // SPDX-License-Identifier: GPL-2.0 2f9ead18cSJens Axboe #include <linux/kernel.h> 3f9ead18cSJens Axboe #include <linux/errno.h> 4f9ead18cSJens Axboe #include <linux/file.h> 5f9ead18cSJens Axboe #include <linux/slab.h> 6f9ead18cSJens Axboe #include <linux/net.h> 7f9ead18cSJens Axboe #include <linux/compat.h> 8f9ead18cSJens Axboe #include <net/compat.h> 9f9ead18cSJens Axboe #include <linux/io_uring.h> 10f9ead18cSJens Axboe 11f9ead18cSJens Axboe #include <uapi/linux/io_uring.h> 12f9ead18cSJens Axboe 13f9ead18cSJens Axboe #include "io_uring.h" 143b77495aSJens Axboe #include "kbuf.h" 1543e0bbbdSJens Axboe #include "alloc_cache.h" 16f9ead18cSJens Axboe #include "net.h" 17f9ead18cSJens Axboe 18f9ead18cSJens Axboe #if defined(CONFIG_NET) 19f9ead18cSJens Axboe struct io_shutdown { 20f9ead18cSJens Axboe struct file *file; 21f9ead18cSJens Axboe int how; 22f9ead18cSJens Axboe }; 23f9ead18cSJens Axboe 24f9ead18cSJens Axboe struct io_accept { 25f9ead18cSJens Axboe struct file *file; 26f9ead18cSJens Axboe struct sockaddr __user *addr; 27f9ead18cSJens Axboe int __user *addr_len; 28f9ead18cSJens Axboe int flags; 29f9ead18cSJens Axboe u32 file_slot; 30f9ead18cSJens Axboe unsigned long nofile; 31f9ead18cSJens Axboe }; 32f9ead18cSJens Axboe 33f9ead18cSJens Axboe struct io_socket { 34f9ead18cSJens Axboe struct file *file; 35f9ead18cSJens Axboe int domain; 36f9ead18cSJens Axboe int type; 37f9ead18cSJens Axboe int protocol; 38f9ead18cSJens Axboe int flags; 39f9ead18cSJens Axboe u32 file_slot; 40f9ead18cSJens Axboe unsigned long nofile; 41f9ead18cSJens Axboe }; 42f9ead18cSJens Axboe 43f9ead18cSJens Axboe struct io_connect { 44f9ead18cSJens Axboe struct file *file; 45f9ead18cSJens Axboe struct sockaddr __user *addr; 46f9ead18cSJens Axboe int addr_len; 47f9ead18cSJens Axboe }; 48f9ead18cSJens Axboe 49f9ead18cSJens Axboe struct io_sr_msg { 50f9ead18cSJens Axboe struct file *file; 51f9ead18cSJens Axboe union { 52f9ead18cSJens Axboe struct compat_msghdr __user *umsg_compat; 53f9ead18cSJens Axboe struct user_msghdr __user *umsg; 54f9ead18cSJens Axboe void __user *buf; 55f9ead18cSJens Axboe }; 56f9ead18cSJens Axboe int msg_flags; 57f9ead18cSJens Axboe size_t len; 58f9ead18cSJens Axboe size_t done_io; 59f9ead18cSJens Axboe unsigned int flags; 60f9ead18cSJens Axboe }; 61f9ead18cSJens Axboe 62f9ead18cSJens Axboe #define IO_APOLL_MULTI_POLLED (REQ_F_APOLL_MULTISHOT | REQ_F_POLLED) 63f9ead18cSJens Axboe 64f9ead18cSJens Axboe int io_shutdown_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 65f9ead18cSJens Axboe { 66f9ead18cSJens Axboe struct io_shutdown *shutdown = io_kiocb_to_cmd(req); 67f9ead18cSJens Axboe 68f9ead18cSJens Axboe if (unlikely(sqe->off || sqe->addr || sqe->rw_flags || 69f9ead18cSJens Axboe sqe->buf_index || sqe->splice_fd_in)) 70f9ead18cSJens Axboe return -EINVAL; 71f9ead18cSJens Axboe 72f9ead18cSJens Axboe shutdown->how = READ_ONCE(sqe->len); 73f9ead18cSJens Axboe return 0; 74f9ead18cSJens Axboe } 75f9ead18cSJens Axboe 76f9ead18cSJens Axboe int io_shutdown(struct io_kiocb *req, unsigned int issue_flags) 77f9ead18cSJens Axboe { 78f9ead18cSJens Axboe struct io_shutdown *shutdown = io_kiocb_to_cmd(req); 79f9ead18cSJens Axboe struct socket *sock; 80f9ead18cSJens Axboe int ret; 81f9ead18cSJens Axboe 82f9ead18cSJens Axboe if (issue_flags & IO_URING_F_NONBLOCK) 83f9ead18cSJens Axboe return -EAGAIN; 84f9ead18cSJens Axboe 85f9ead18cSJens Axboe sock = sock_from_file(req->file); 86f9ead18cSJens Axboe if (unlikely(!sock)) 87f9ead18cSJens Axboe return -ENOTSOCK; 88f9ead18cSJens Axboe 89f9ead18cSJens Axboe ret = __sys_shutdown_sock(sock, shutdown->how); 90f9ead18cSJens Axboe io_req_set_res(req, ret, 0); 91f9ead18cSJens Axboe return IOU_OK; 92f9ead18cSJens Axboe } 93f9ead18cSJens Axboe 94f9ead18cSJens Axboe static bool io_net_retry(struct socket *sock, int flags) 95f9ead18cSJens Axboe { 96f9ead18cSJens Axboe if (!(flags & MSG_WAITALL)) 97f9ead18cSJens Axboe return false; 98f9ead18cSJens Axboe return sock->type == SOCK_STREAM || sock->type == SOCK_SEQPACKET; 99f9ead18cSJens Axboe } 100f9ead18cSJens Axboe 10143e0bbbdSJens Axboe static void io_netmsg_recycle(struct io_kiocb *req, unsigned int issue_flags) 10243e0bbbdSJens Axboe { 10343e0bbbdSJens Axboe struct io_async_msghdr *hdr = req->async_data; 10443e0bbbdSJens Axboe 10543e0bbbdSJens Axboe if (!hdr || issue_flags & IO_URING_F_UNLOCKED) 10643e0bbbdSJens Axboe return; 10743e0bbbdSJens Axboe 10843e0bbbdSJens Axboe /* Let normal cleanup path reap it if we fail adding to the cache */ 10943e0bbbdSJens Axboe if (io_alloc_cache_put(&req->ctx->netmsg_cache, &hdr->cache)) { 11043e0bbbdSJens Axboe req->async_data = NULL; 11143e0bbbdSJens Axboe req->flags &= ~REQ_F_ASYNC_DATA; 11243e0bbbdSJens Axboe } 11343e0bbbdSJens Axboe } 11443e0bbbdSJens Axboe 11543e0bbbdSJens Axboe static struct io_async_msghdr *io_recvmsg_alloc_async(struct io_kiocb *req, 11643e0bbbdSJens Axboe unsigned int issue_flags) 11743e0bbbdSJens Axboe { 11843e0bbbdSJens Axboe struct io_ring_ctx *ctx = req->ctx; 11943e0bbbdSJens Axboe struct io_cache_entry *entry; 12043e0bbbdSJens Axboe 12143e0bbbdSJens Axboe if (!(issue_flags & IO_URING_F_UNLOCKED) && 12243e0bbbdSJens Axboe (entry = io_alloc_cache_get(&ctx->netmsg_cache)) != NULL) { 12343e0bbbdSJens Axboe struct io_async_msghdr *hdr; 12443e0bbbdSJens Axboe 12543e0bbbdSJens Axboe hdr = container_of(entry, struct io_async_msghdr, cache); 12643e0bbbdSJens Axboe req->flags |= REQ_F_ASYNC_DATA; 12743e0bbbdSJens Axboe req->async_data = hdr; 12843e0bbbdSJens Axboe return hdr; 12943e0bbbdSJens Axboe } 13043e0bbbdSJens Axboe 13143e0bbbdSJens Axboe if (!io_alloc_async_data(req)) 13243e0bbbdSJens Axboe return req->async_data; 13343e0bbbdSJens Axboe 13443e0bbbdSJens Axboe return NULL; 13543e0bbbdSJens Axboe } 13643e0bbbdSJens Axboe 137f9ead18cSJens Axboe static int io_setup_async_msg(struct io_kiocb *req, 13843e0bbbdSJens Axboe struct io_async_msghdr *kmsg, 13943e0bbbdSJens Axboe unsigned int issue_flags) 140f9ead18cSJens Axboe { 141f9ead18cSJens Axboe struct io_async_msghdr *async_msg = req->async_data; 142f9ead18cSJens Axboe 143f9ead18cSJens Axboe if (async_msg) 144f9ead18cSJens Axboe return -EAGAIN; 14543e0bbbdSJens Axboe async_msg = io_recvmsg_alloc_async(req, issue_flags); 14643e0bbbdSJens Axboe if (!async_msg) { 147f9ead18cSJens Axboe kfree(kmsg->free_iov); 148f9ead18cSJens Axboe return -ENOMEM; 149f9ead18cSJens Axboe } 150f9ead18cSJens Axboe req->flags |= REQ_F_NEED_CLEANUP; 151f9ead18cSJens Axboe memcpy(async_msg, kmsg, sizeof(*kmsg)); 152f9ead18cSJens Axboe async_msg->msg.msg_name = &async_msg->addr; 153f9ead18cSJens Axboe /* if were using fast_iov, set it to the new one */ 154f9ead18cSJens Axboe if (!async_msg->free_iov) 155f9ead18cSJens Axboe async_msg->msg.msg_iter.iov = async_msg->fast_iov; 156f9ead18cSJens Axboe 157f9ead18cSJens Axboe return -EAGAIN; 158f9ead18cSJens Axboe } 159f9ead18cSJens Axboe 160f9ead18cSJens Axboe static int io_sendmsg_copy_hdr(struct io_kiocb *req, 161f9ead18cSJens Axboe struct io_async_msghdr *iomsg) 162f9ead18cSJens Axboe { 163f9ead18cSJens Axboe struct io_sr_msg *sr = io_kiocb_to_cmd(req); 164f9ead18cSJens Axboe 165f9ead18cSJens Axboe iomsg->msg.msg_name = &iomsg->addr; 166f9ead18cSJens Axboe iomsg->free_iov = iomsg->fast_iov; 167f9ead18cSJens Axboe return sendmsg_copy_msghdr(&iomsg->msg, sr->umsg, sr->msg_flags, 168f9ead18cSJens Axboe &iomsg->free_iov); 169f9ead18cSJens Axboe } 170f9ead18cSJens Axboe 171f9ead18cSJens Axboe int io_sendmsg_prep_async(struct io_kiocb *req) 172f9ead18cSJens Axboe { 173f9ead18cSJens Axboe int ret; 174f9ead18cSJens Axboe 175f9ead18cSJens Axboe ret = io_sendmsg_copy_hdr(req, req->async_data); 176f9ead18cSJens Axboe if (!ret) 177f9ead18cSJens Axboe req->flags |= REQ_F_NEED_CLEANUP; 178f9ead18cSJens Axboe return ret; 179f9ead18cSJens Axboe } 180f9ead18cSJens Axboe 181f9ead18cSJens Axboe void io_sendmsg_recvmsg_cleanup(struct io_kiocb *req) 182f9ead18cSJens Axboe { 183f9ead18cSJens Axboe struct io_async_msghdr *io = req->async_data; 184f9ead18cSJens Axboe 185f9ead18cSJens Axboe kfree(io->free_iov); 186f9ead18cSJens Axboe } 187f9ead18cSJens Axboe 188f9ead18cSJens Axboe int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 189f9ead18cSJens Axboe { 190f9ead18cSJens Axboe struct io_sr_msg *sr = io_kiocb_to_cmd(req); 191f9ead18cSJens Axboe 192f9ead18cSJens Axboe if (unlikely(sqe->file_index || sqe->addr2)) 193f9ead18cSJens Axboe return -EINVAL; 194f9ead18cSJens Axboe 195f9ead18cSJens Axboe sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr)); 196f9ead18cSJens Axboe sr->len = READ_ONCE(sqe->len); 197f9ead18cSJens Axboe sr->flags = READ_ONCE(sqe->ioprio); 198f9ead18cSJens Axboe if (sr->flags & ~IORING_RECVSEND_POLL_FIRST) 199f9ead18cSJens Axboe return -EINVAL; 200f9ead18cSJens Axboe sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL; 201f9ead18cSJens Axboe if (sr->msg_flags & MSG_DONTWAIT) 202f9ead18cSJens Axboe req->flags |= REQ_F_NOWAIT; 203f9ead18cSJens Axboe 204f9ead18cSJens Axboe #ifdef CONFIG_COMPAT 205f9ead18cSJens Axboe if (req->ctx->compat) 206f9ead18cSJens Axboe sr->msg_flags |= MSG_CMSG_COMPAT; 207f9ead18cSJens Axboe #endif 208f9ead18cSJens Axboe sr->done_io = 0; 209f9ead18cSJens Axboe return 0; 210f9ead18cSJens Axboe } 211f9ead18cSJens Axboe 212f9ead18cSJens Axboe int io_sendmsg(struct io_kiocb *req, unsigned int issue_flags) 213f9ead18cSJens Axboe { 214f9ead18cSJens Axboe struct io_sr_msg *sr = io_kiocb_to_cmd(req); 215f9ead18cSJens Axboe struct io_async_msghdr iomsg, *kmsg; 216f9ead18cSJens Axboe struct socket *sock; 217f9ead18cSJens Axboe unsigned flags; 218f9ead18cSJens Axboe int min_ret = 0; 219f9ead18cSJens Axboe int ret; 220f9ead18cSJens Axboe 221f9ead18cSJens Axboe sock = sock_from_file(req->file); 222f9ead18cSJens Axboe if (unlikely(!sock)) 223f9ead18cSJens Axboe return -ENOTSOCK; 224f9ead18cSJens Axboe 225f9ead18cSJens Axboe if (req_has_async_data(req)) { 226f9ead18cSJens Axboe kmsg = req->async_data; 227f9ead18cSJens Axboe } else { 228f9ead18cSJens Axboe ret = io_sendmsg_copy_hdr(req, &iomsg); 229f9ead18cSJens Axboe if (ret) 230f9ead18cSJens Axboe return ret; 231f9ead18cSJens Axboe kmsg = &iomsg; 232f9ead18cSJens Axboe } 233f9ead18cSJens Axboe 234f9ead18cSJens Axboe if (!(req->flags & REQ_F_POLLED) && 235f9ead18cSJens Axboe (sr->flags & IORING_RECVSEND_POLL_FIRST)) 23643e0bbbdSJens Axboe return io_setup_async_msg(req, kmsg, issue_flags); 237f9ead18cSJens Axboe 238f9ead18cSJens Axboe flags = sr->msg_flags; 239f9ead18cSJens Axboe if (issue_flags & IO_URING_F_NONBLOCK) 240f9ead18cSJens Axboe flags |= MSG_DONTWAIT; 241f9ead18cSJens Axboe if (flags & MSG_WAITALL) 242f9ead18cSJens Axboe min_ret = iov_iter_count(&kmsg->msg.msg_iter); 243f9ead18cSJens Axboe 244f9ead18cSJens Axboe ret = __sys_sendmsg_sock(sock, &kmsg->msg, flags); 245f9ead18cSJens Axboe 246f9ead18cSJens Axboe if (ret < min_ret) { 247f9ead18cSJens Axboe if (ret == -EAGAIN && (issue_flags & IO_URING_F_NONBLOCK)) 24843e0bbbdSJens Axboe return io_setup_async_msg(req, kmsg, issue_flags); 249f9ead18cSJens Axboe if (ret == -ERESTARTSYS) 250f9ead18cSJens Axboe ret = -EINTR; 251f9ead18cSJens Axboe if (ret > 0 && io_net_retry(sock, flags)) { 252f9ead18cSJens Axboe sr->done_io += ret; 253f9ead18cSJens Axboe req->flags |= REQ_F_PARTIAL_IO; 25443e0bbbdSJens Axboe return io_setup_async_msg(req, kmsg, issue_flags); 255f9ead18cSJens Axboe } 256f9ead18cSJens Axboe req_set_fail(req); 257f9ead18cSJens Axboe } 258f9ead18cSJens Axboe /* fast path, check for non-NULL to avoid function call */ 259f9ead18cSJens Axboe if (kmsg->free_iov) 260f9ead18cSJens Axboe kfree(kmsg->free_iov); 261f9ead18cSJens Axboe req->flags &= ~REQ_F_NEED_CLEANUP; 26243e0bbbdSJens Axboe io_netmsg_recycle(req, issue_flags); 263f9ead18cSJens Axboe if (ret >= 0) 264f9ead18cSJens Axboe ret += sr->done_io; 265f9ead18cSJens Axboe else if (sr->done_io) 266f9ead18cSJens Axboe ret = sr->done_io; 267f9ead18cSJens Axboe io_req_set_res(req, ret, 0); 268f9ead18cSJens Axboe return IOU_OK; 269f9ead18cSJens Axboe } 270f9ead18cSJens Axboe 271f9ead18cSJens Axboe int io_send(struct io_kiocb *req, unsigned int issue_flags) 272f9ead18cSJens Axboe { 273f9ead18cSJens Axboe struct io_sr_msg *sr = io_kiocb_to_cmd(req); 274f9ead18cSJens Axboe struct msghdr msg; 275f9ead18cSJens Axboe struct iovec iov; 276f9ead18cSJens Axboe struct socket *sock; 277f9ead18cSJens Axboe unsigned flags; 278f9ead18cSJens Axboe int min_ret = 0; 279f9ead18cSJens Axboe int ret; 280f9ead18cSJens Axboe 281f9ead18cSJens Axboe if (!(req->flags & REQ_F_POLLED) && 282f9ead18cSJens Axboe (sr->flags & IORING_RECVSEND_POLL_FIRST)) 283f9ead18cSJens Axboe return -EAGAIN; 284f9ead18cSJens Axboe 285f9ead18cSJens Axboe sock = sock_from_file(req->file); 286f9ead18cSJens Axboe if (unlikely(!sock)) 287f9ead18cSJens Axboe return -ENOTSOCK; 288f9ead18cSJens Axboe 289f9ead18cSJens Axboe ret = import_single_range(WRITE, sr->buf, sr->len, &iov, &msg.msg_iter); 290f9ead18cSJens Axboe if (unlikely(ret)) 291f9ead18cSJens Axboe return ret; 292f9ead18cSJens Axboe 293f9ead18cSJens Axboe msg.msg_name = NULL; 294f9ead18cSJens Axboe msg.msg_control = NULL; 295f9ead18cSJens Axboe msg.msg_controllen = 0; 296f9ead18cSJens Axboe msg.msg_namelen = 0; 297f9ead18cSJens Axboe 298f9ead18cSJens Axboe flags = sr->msg_flags; 299f9ead18cSJens Axboe if (issue_flags & IO_URING_F_NONBLOCK) 300f9ead18cSJens Axboe flags |= MSG_DONTWAIT; 301f9ead18cSJens Axboe if (flags & MSG_WAITALL) 302f9ead18cSJens Axboe min_ret = iov_iter_count(&msg.msg_iter); 303f9ead18cSJens Axboe 304f9ead18cSJens Axboe msg.msg_flags = flags; 305f9ead18cSJens Axboe ret = sock_sendmsg(sock, &msg); 306f9ead18cSJens Axboe if (ret < min_ret) { 307f9ead18cSJens Axboe if (ret == -EAGAIN && (issue_flags & IO_URING_F_NONBLOCK)) 308f9ead18cSJens Axboe return -EAGAIN; 309f9ead18cSJens Axboe if (ret == -ERESTARTSYS) 310f9ead18cSJens Axboe ret = -EINTR; 311f9ead18cSJens Axboe if (ret > 0 && io_net_retry(sock, flags)) { 312f9ead18cSJens Axboe sr->len -= ret; 313f9ead18cSJens Axboe sr->buf += ret; 314f9ead18cSJens Axboe sr->done_io += ret; 315f9ead18cSJens Axboe req->flags |= REQ_F_PARTIAL_IO; 316f9ead18cSJens Axboe return -EAGAIN; 317f9ead18cSJens Axboe } 318f9ead18cSJens Axboe req_set_fail(req); 319f9ead18cSJens Axboe } 320f9ead18cSJens Axboe if (ret >= 0) 321f9ead18cSJens Axboe ret += sr->done_io; 322f9ead18cSJens Axboe else if (sr->done_io) 323f9ead18cSJens Axboe ret = sr->done_io; 324f9ead18cSJens Axboe io_req_set_res(req, ret, 0); 325f9ead18cSJens Axboe return IOU_OK; 326f9ead18cSJens Axboe } 327f9ead18cSJens Axboe 328f9ead18cSJens Axboe static int __io_recvmsg_copy_hdr(struct io_kiocb *req, 329f9ead18cSJens Axboe struct io_async_msghdr *iomsg) 330f9ead18cSJens Axboe { 331f9ead18cSJens Axboe struct io_sr_msg *sr = io_kiocb_to_cmd(req); 332*7fa875b8SDylan Yudaken struct user_msghdr msg; 333f9ead18cSJens Axboe int ret; 334f9ead18cSJens Axboe 335*7fa875b8SDylan Yudaken if (copy_from_user(&msg, sr->umsg, sizeof(*sr->umsg))) 336*7fa875b8SDylan Yudaken return -EFAULT; 337*7fa875b8SDylan Yudaken 338*7fa875b8SDylan Yudaken ret = __copy_msghdr(&iomsg->msg, &msg, &iomsg->uaddr); 339f9ead18cSJens Axboe if (ret) 340f9ead18cSJens Axboe return ret; 341f9ead18cSJens Axboe 342f9ead18cSJens Axboe if (req->flags & REQ_F_BUFFER_SELECT) { 343*7fa875b8SDylan Yudaken if (msg.msg_iovlen == 0) { 3445702196eSDylan Yudaken sr->len = iomsg->fast_iov[0].iov_len = 0; 3455702196eSDylan Yudaken iomsg->fast_iov[0].iov_base = NULL; 3465702196eSDylan Yudaken iomsg->free_iov = NULL; 347*7fa875b8SDylan Yudaken } else if (msg.msg_iovlen > 1) { 348f9ead18cSJens Axboe return -EINVAL; 3495702196eSDylan Yudaken } else { 350*7fa875b8SDylan Yudaken if (copy_from_user(iomsg->fast_iov, msg.msg_iov, sizeof(*msg.msg_iov))) 351f9ead18cSJens Axboe return -EFAULT; 352f9ead18cSJens Axboe sr->len = iomsg->fast_iov[0].iov_len; 353f9ead18cSJens Axboe iomsg->free_iov = NULL; 3545702196eSDylan Yudaken } 355f9ead18cSJens Axboe } else { 356f9ead18cSJens Axboe iomsg->free_iov = iomsg->fast_iov; 357*7fa875b8SDylan Yudaken ret = __import_iovec(READ, msg.msg_iov, msg.msg_iovlen, UIO_FASTIOV, 358f9ead18cSJens Axboe &iomsg->free_iov, &iomsg->msg.msg_iter, 359f9ead18cSJens Axboe false); 360f9ead18cSJens Axboe if (ret > 0) 361f9ead18cSJens Axboe ret = 0; 362f9ead18cSJens Axboe } 363f9ead18cSJens Axboe 364f9ead18cSJens Axboe return ret; 365f9ead18cSJens Axboe } 366f9ead18cSJens Axboe 367f9ead18cSJens Axboe #ifdef CONFIG_COMPAT 368f9ead18cSJens Axboe static int __io_compat_recvmsg_copy_hdr(struct io_kiocb *req, 369f9ead18cSJens Axboe struct io_async_msghdr *iomsg) 370f9ead18cSJens Axboe { 371f9ead18cSJens Axboe struct io_sr_msg *sr = io_kiocb_to_cmd(req); 372f9ead18cSJens Axboe struct compat_iovec __user *uiov; 373f9ead18cSJens Axboe compat_uptr_t ptr; 374f9ead18cSJens Axboe compat_size_t len; 375f9ead18cSJens Axboe int ret; 376f9ead18cSJens Axboe 377f9ead18cSJens Axboe ret = __get_compat_msghdr(&iomsg->msg, sr->umsg_compat, &iomsg->uaddr, 378f9ead18cSJens Axboe &ptr, &len); 379f9ead18cSJens Axboe if (ret) 380f9ead18cSJens Axboe return ret; 381f9ead18cSJens Axboe 382f9ead18cSJens Axboe uiov = compat_ptr(ptr); 383f9ead18cSJens Axboe if (req->flags & REQ_F_BUFFER_SELECT) { 384f9ead18cSJens Axboe compat_ssize_t clen; 385f9ead18cSJens Axboe 3866d2f75a0SDylan Yudaken if (len == 0) { 3876d2f75a0SDylan Yudaken sr->len = 0; 3886d2f75a0SDylan Yudaken iomsg->free_iov = NULL; 3896d2f75a0SDylan Yudaken } else if (len > 1) { 390f9ead18cSJens Axboe return -EINVAL; 3916d2f75a0SDylan Yudaken } else { 392f9ead18cSJens Axboe if (!access_ok(uiov, sizeof(*uiov))) 393f9ead18cSJens Axboe return -EFAULT; 394f9ead18cSJens Axboe if (__get_user(clen, &uiov->iov_len)) 395f9ead18cSJens Axboe return -EFAULT; 396f9ead18cSJens Axboe if (clen < 0) 397f9ead18cSJens Axboe return -EINVAL; 398f9ead18cSJens Axboe sr->len = clen; 399f9ead18cSJens Axboe iomsg->free_iov = NULL; 4006d2f75a0SDylan Yudaken } 401f9ead18cSJens Axboe } else { 402f9ead18cSJens Axboe iomsg->free_iov = iomsg->fast_iov; 403f9ead18cSJens Axboe ret = __import_iovec(READ, (struct iovec __user *)uiov, len, 404f9ead18cSJens Axboe UIO_FASTIOV, &iomsg->free_iov, 405f9ead18cSJens Axboe &iomsg->msg.msg_iter, true); 406f9ead18cSJens Axboe if (ret < 0) 407f9ead18cSJens Axboe return ret; 408f9ead18cSJens Axboe } 409f9ead18cSJens Axboe 410f9ead18cSJens Axboe return 0; 411f9ead18cSJens Axboe } 412f9ead18cSJens Axboe #endif 413f9ead18cSJens Axboe 414f9ead18cSJens Axboe static int io_recvmsg_copy_hdr(struct io_kiocb *req, 415f9ead18cSJens Axboe struct io_async_msghdr *iomsg) 416f9ead18cSJens Axboe { 417f9ead18cSJens Axboe iomsg->msg.msg_name = &iomsg->addr; 418f9ead18cSJens Axboe 419f9ead18cSJens Axboe #ifdef CONFIG_COMPAT 420f9ead18cSJens Axboe if (req->ctx->compat) 421f9ead18cSJens Axboe return __io_compat_recvmsg_copy_hdr(req, iomsg); 422f9ead18cSJens Axboe #endif 423f9ead18cSJens Axboe 424f9ead18cSJens Axboe return __io_recvmsg_copy_hdr(req, iomsg); 425f9ead18cSJens Axboe } 426f9ead18cSJens Axboe 427f9ead18cSJens Axboe int io_recvmsg_prep_async(struct io_kiocb *req) 428f9ead18cSJens Axboe { 429f9ead18cSJens Axboe int ret; 430f9ead18cSJens Axboe 431f9ead18cSJens Axboe ret = io_recvmsg_copy_hdr(req, req->async_data); 432f9ead18cSJens Axboe if (!ret) 433f9ead18cSJens Axboe req->flags |= REQ_F_NEED_CLEANUP; 434f9ead18cSJens Axboe return ret; 435f9ead18cSJens Axboe } 436f9ead18cSJens Axboe 437b3fdea6eSDylan Yudaken #define RECVMSG_FLAGS (IORING_RECVSEND_POLL_FIRST | IORING_RECV_MULTISHOT) 438b3fdea6eSDylan Yudaken 439f9ead18cSJens Axboe int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 440f9ead18cSJens Axboe { 441f9ead18cSJens Axboe struct io_sr_msg *sr = io_kiocb_to_cmd(req); 442f9ead18cSJens Axboe 443f9ead18cSJens Axboe if (unlikely(sqe->file_index || sqe->addr2)) 444f9ead18cSJens Axboe return -EINVAL; 445f9ead18cSJens Axboe 446f9ead18cSJens Axboe sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr)); 447f9ead18cSJens Axboe sr->len = READ_ONCE(sqe->len); 448f9ead18cSJens Axboe sr->flags = READ_ONCE(sqe->ioprio); 449b3fdea6eSDylan Yudaken if (sr->flags & ~(RECVMSG_FLAGS)) 450f9ead18cSJens Axboe return -EINVAL; 451f9ead18cSJens Axboe sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL; 452f9ead18cSJens Axboe if (sr->msg_flags & MSG_DONTWAIT) 453f9ead18cSJens Axboe req->flags |= REQ_F_NOWAIT; 454f9ead18cSJens Axboe if (sr->msg_flags & MSG_ERRQUEUE) 455f9ead18cSJens Axboe req->flags |= REQ_F_CLEAR_POLLIN; 456b3fdea6eSDylan Yudaken if (sr->flags & IORING_RECV_MULTISHOT) { 457cf0dd952SDylan Yudaken if (req->opcode == IORING_OP_RECVMSG) 458cf0dd952SDylan Yudaken return -EINVAL; 459b3fdea6eSDylan Yudaken if (!(req->flags & REQ_F_BUFFER_SELECT)) 460b3fdea6eSDylan Yudaken return -EINVAL; 461b3fdea6eSDylan Yudaken if (sr->msg_flags & MSG_WAITALL) 462b3fdea6eSDylan Yudaken return -EINVAL; 463b3fdea6eSDylan Yudaken if (req->opcode == IORING_OP_RECV && sr->len) 464b3fdea6eSDylan Yudaken return -EINVAL; 465b3fdea6eSDylan Yudaken req->flags |= REQ_F_APOLL_MULTISHOT; 466b3fdea6eSDylan Yudaken } 467f9ead18cSJens Axboe 468f9ead18cSJens Axboe #ifdef CONFIG_COMPAT 469f9ead18cSJens Axboe if (req->ctx->compat) 470f9ead18cSJens Axboe sr->msg_flags |= MSG_CMSG_COMPAT; 471f9ead18cSJens Axboe #endif 472f9ead18cSJens Axboe sr->done_io = 0; 473f9ead18cSJens Axboe return 0; 474f9ead18cSJens Axboe } 475f9ead18cSJens Axboe 476b3fdea6eSDylan Yudaken static inline void io_recv_prep_retry(struct io_kiocb *req) 477b3fdea6eSDylan Yudaken { 478b3fdea6eSDylan Yudaken struct io_sr_msg *sr = io_kiocb_to_cmd(req); 479b3fdea6eSDylan Yudaken 480b3fdea6eSDylan Yudaken sr->done_io = 0; 481b3fdea6eSDylan Yudaken sr->len = 0; /* get from the provided buffer */ 482b3fdea6eSDylan Yudaken } 483b3fdea6eSDylan Yudaken 484b3fdea6eSDylan Yudaken /* 485cf0dd952SDylan Yudaken * Finishes io_recv 486b3fdea6eSDylan Yudaken * 487b3fdea6eSDylan Yudaken * Returns true if it is actually finished, or false if it should run 488b3fdea6eSDylan Yudaken * again (for multishot). 489b3fdea6eSDylan Yudaken */ 490b3fdea6eSDylan Yudaken static inline bool io_recv_finish(struct io_kiocb *req, int *ret, unsigned int cflags) 491b3fdea6eSDylan Yudaken { 492b3fdea6eSDylan Yudaken if (!(req->flags & REQ_F_APOLL_MULTISHOT)) { 493b3fdea6eSDylan Yudaken io_req_set_res(req, *ret, cflags); 494b3fdea6eSDylan Yudaken *ret = IOU_OK; 495b3fdea6eSDylan Yudaken return true; 496b3fdea6eSDylan Yudaken } 497b3fdea6eSDylan Yudaken 498b3fdea6eSDylan Yudaken if (*ret > 0) { 499b3fdea6eSDylan Yudaken if (io_post_aux_cqe(req->ctx, req->cqe.user_data, *ret, 500b3fdea6eSDylan Yudaken cflags | IORING_CQE_F_MORE, false)) { 501b3fdea6eSDylan Yudaken io_recv_prep_retry(req); 502b3fdea6eSDylan Yudaken return false; 503b3fdea6eSDylan Yudaken } 504b3fdea6eSDylan Yudaken /* 505b3fdea6eSDylan Yudaken * Otherwise stop multishot but use the current result. 506b3fdea6eSDylan Yudaken * Probably will end up going into overflow, but this means 507b3fdea6eSDylan Yudaken * we cannot trust the ordering anymore 508b3fdea6eSDylan Yudaken */ 509b3fdea6eSDylan Yudaken } 510b3fdea6eSDylan Yudaken 511b3fdea6eSDylan Yudaken io_req_set_res(req, *ret, cflags); 512b3fdea6eSDylan Yudaken 513b3fdea6eSDylan Yudaken if (req->flags & REQ_F_POLLED) 514b3fdea6eSDylan Yudaken *ret = IOU_STOP_MULTISHOT; 515e2df2ccbSDylan Yudaken else 516e2df2ccbSDylan Yudaken *ret = IOU_OK; 517b3fdea6eSDylan Yudaken return true; 518b3fdea6eSDylan Yudaken } 519b3fdea6eSDylan Yudaken 520f9ead18cSJens Axboe int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags) 521f9ead18cSJens Axboe { 522f9ead18cSJens Axboe struct io_sr_msg *sr = io_kiocb_to_cmd(req); 523f9ead18cSJens Axboe struct io_async_msghdr iomsg, *kmsg; 524f9ead18cSJens Axboe struct socket *sock; 525f9ead18cSJens Axboe unsigned int cflags; 526f9ead18cSJens Axboe unsigned flags; 527f9ead18cSJens Axboe int ret, min_ret = 0; 528f9ead18cSJens Axboe bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; 529f9ead18cSJens Axboe 530f9ead18cSJens Axboe sock = sock_from_file(req->file); 531f9ead18cSJens Axboe if (unlikely(!sock)) 532f9ead18cSJens Axboe return -ENOTSOCK; 533f9ead18cSJens Axboe 534f9ead18cSJens Axboe if (req_has_async_data(req)) { 535f9ead18cSJens Axboe kmsg = req->async_data; 536f9ead18cSJens Axboe } else { 537f9ead18cSJens Axboe ret = io_recvmsg_copy_hdr(req, &iomsg); 538f9ead18cSJens Axboe if (ret) 539f9ead18cSJens Axboe return ret; 540f9ead18cSJens Axboe kmsg = &iomsg; 541f9ead18cSJens Axboe } 542f9ead18cSJens Axboe 543f9ead18cSJens Axboe if (!(req->flags & REQ_F_POLLED) && 544f9ead18cSJens Axboe (sr->flags & IORING_RECVSEND_POLL_FIRST)) 54543e0bbbdSJens Axboe return io_setup_async_msg(req, kmsg, issue_flags); 546f9ead18cSJens Axboe 547f9ead18cSJens Axboe if (io_do_buffer_select(req)) { 548f9ead18cSJens Axboe void __user *buf; 549f9ead18cSJens Axboe 550cf0dd952SDylan Yudaken buf = io_buffer_select(req, &sr->len, issue_flags); 551f9ead18cSJens Axboe if (!buf) 552f9ead18cSJens Axboe return -ENOBUFS; 553f9ead18cSJens Axboe kmsg->fast_iov[0].iov_base = buf; 554cf0dd952SDylan Yudaken kmsg->fast_iov[0].iov_len = sr->len; 555f9ead18cSJens Axboe iov_iter_init(&kmsg->msg.msg_iter, READ, kmsg->fast_iov, 1, 556cf0dd952SDylan Yudaken sr->len); 557f9ead18cSJens Axboe } 558f9ead18cSJens Axboe 559f9ead18cSJens Axboe flags = sr->msg_flags; 560f9ead18cSJens Axboe if (force_nonblock) 561f9ead18cSJens Axboe flags |= MSG_DONTWAIT; 562f9ead18cSJens Axboe if (flags & MSG_WAITALL) 563f9ead18cSJens Axboe min_ret = iov_iter_count(&kmsg->msg.msg_iter); 564f9ead18cSJens Axboe 565f9ead18cSJens Axboe kmsg->msg.msg_get_inq = 1; 566f9ead18cSJens Axboe ret = __sys_recvmsg_sock(sock, &kmsg->msg, sr->umsg, kmsg->uaddr, flags); 567f9ead18cSJens Axboe if (ret < min_ret) { 568cf0dd952SDylan Yudaken if (ret == -EAGAIN && force_nonblock) 56943e0bbbdSJens Axboe return io_setup_async_msg(req, kmsg, issue_flags); 570f9ead18cSJens Axboe if (ret == -ERESTARTSYS) 571f9ead18cSJens Axboe ret = -EINTR; 572f9ead18cSJens Axboe if (ret > 0 && io_net_retry(sock, flags)) { 573f9ead18cSJens Axboe sr->done_io += ret; 574f9ead18cSJens Axboe req->flags |= REQ_F_PARTIAL_IO; 57543e0bbbdSJens Axboe return io_setup_async_msg(req, kmsg, issue_flags); 576f9ead18cSJens Axboe } 577f9ead18cSJens Axboe req_set_fail(req); 578f9ead18cSJens Axboe } else if ((flags & MSG_WAITALL) && (kmsg->msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) { 579f9ead18cSJens Axboe req_set_fail(req); 580f9ead18cSJens Axboe } 581f9ead18cSJens Axboe 582f9ead18cSJens Axboe /* fast path, check for non-NULL to avoid function call */ 583f9ead18cSJens Axboe if (kmsg->free_iov) 584f9ead18cSJens Axboe kfree(kmsg->free_iov); 58543e0bbbdSJens Axboe io_netmsg_recycle(req, issue_flags); 586f9ead18cSJens Axboe req->flags &= ~REQ_F_NEED_CLEANUP; 587d4e097daSDylan Yudaken if (ret > 0) 588f9ead18cSJens Axboe ret += sr->done_io; 589f9ead18cSJens Axboe else if (sr->done_io) 590f9ead18cSJens Axboe ret = sr->done_io; 591d4e097daSDylan Yudaken else 592d4e097daSDylan Yudaken io_kbuf_recycle(req, issue_flags); 593d4e097daSDylan Yudaken 594f9ead18cSJens Axboe cflags = io_put_kbuf(req, issue_flags); 595f9ead18cSJens Axboe if (kmsg->msg.msg_inq) 596f9ead18cSJens Axboe cflags |= IORING_CQE_F_SOCK_NONEMPTY; 597b3fdea6eSDylan Yudaken 598cf0dd952SDylan Yudaken io_req_set_res(req, ret, cflags); 599cf0dd952SDylan Yudaken return IOU_OK; 600f9ead18cSJens Axboe } 601f9ead18cSJens Axboe 602f9ead18cSJens Axboe int io_recv(struct io_kiocb *req, unsigned int issue_flags) 603f9ead18cSJens Axboe { 604f9ead18cSJens Axboe struct io_sr_msg *sr = io_kiocb_to_cmd(req); 605f9ead18cSJens Axboe struct msghdr msg; 606f9ead18cSJens Axboe struct socket *sock; 607f9ead18cSJens Axboe struct iovec iov; 608f9ead18cSJens Axboe unsigned int cflags; 609f9ead18cSJens Axboe unsigned flags; 610f9ead18cSJens Axboe int ret, min_ret = 0; 611f9ead18cSJens Axboe bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; 612b3fdea6eSDylan Yudaken size_t len = sr->len; 613f9ead18cSJens Axboe 614f9ead18cSJens Axboe if (!(req->flags & REQ_F_POLLED) && 615f9ead18cSJens Axboe (sr->flags & IORING_RECVSEND_POLL_FIRST)) 616f9ead18cSJens Axboe return -EAGAIN; 617f9ead18cSJens Axboe 618f9ead18cSJens Axboe sock = sock_from_file(req->file); 619f9ead18cSJens Axboe if (unlikely(!sock)) 620f9ead18cSJens Axboe return -ENOTSOCK; 621f9ead18cSJens Axboe 622b3fdea6eSDylan Yudaken retry_multishot: 623f9ead18cSJens Axboe if (io_do_buffer_select(req)) { 624f9ead18cSJens Axboe void __user *buf; 625f9ead18cSJens Axboe 626b3fdea6eSDylan Yudaken buf = io_buffer_select(req, &len, issue_flags); 627f9ead18cSJens Axboe if (!buf) 628f9ead18cSJens Axboe return -ENOBUFS; 629f9ead18cSJens Axboe sr->buf = buf; 630f9ead18cSJens Axboe } 631f9ead18cSJens Axboe 632b3fdea6eSDylan Yudaken ret = import_single_range(READ, sr->buf, len, &iov, &msg.msg_iter); 633f9ead18cSJens Axboe if (unlikely(ret)) 634f9ead18cSJens Axboe goto out_free; 635f9ead18cSJens Axboe 636f9ead18cSJens Axboe msg.msg_name = NULL; 637f9ead18cSJens Axboe msg.msg_namelen = 0; 638f9ead18cSJens Axboe msg.msg_control = NULL; 639f9ead18cSJens Axboe msg.msg_get_inq = 1; 640f9ead18cSJens Axboe msg.msg_flags = 0; 641f9ead18cSJens Axboe msg.msg_controllen = 0; 642f9ead18cSJens Axboe msg.msg_iocb = NULL; 643f9ead18cSJens Axboe 644f9ead18cSJens Axboe flags = sr->msg_flags; 645f9ead18cSJens Axboe if (force_nonblock) 646f9ead18cSJens Axboe flags |= MSG_DONTWAIT; 647f9ead18cSJens Axboe if (flags & MSG_WAITALL) 648f9ead18cSJens Axboe min_ret = iov_iter_count(&msg.msg_iter); 649f9ead18cSJens Axboe 650f9ead18cSJens Axboe ret = sock_recvmsg(sock, &msg, flags); 651f9ead18cSJens Axboe if (ret < min_ret) { 652b3fdea6eSDylan Yudaken if (ret == -EAGAIN && force_nonblock) { 653b3fdea6eSDylan Yudaken if ((req->flags & IO_APOLL_MULTI_POLLED) == IO_APOLL_MULTI_POLLED) { 654b3fdea6eSDylan Yudaken io_kbuf_recycle(req, issue_flags); 655b3fdea6eSDylan Yudaken return IOU_ISSUE_SKIP_COMPLETE; 656b3fdea6eSDylan Yudaken } 657b3fdea6eSDylan Yudaken 658f9ead18cSJens Axboe return -EAGAIN; 659b3fdea6eSDylan Yudaken } 660f9ead18cSJens Axboe if (ret == -ERESTARTSYS) 661f9ead18cSJens Axboe ret = -EINTR; 662f9ead18cSJens Axboe if (ret > 0 && io_net_retry(sock, flags)) { 663f9ead18cSJens Axboe sr->len -= ret; 664f9ead18cSJens Axboe sr->buf += ret; 665f9ead18cSJens Axboe sr->done_io += ret; 666f9ead18cSJens Axboe req->flags |= REQ_F_PARTIAL_IO; 667f9ead18cSJens Axboe return -EAGAIN; 668f9ead18cSJens Axboe } 669f9ead18cSJens Axboe req_set_fail(req); 670f9ead18cSJens Axboe } else if ((flags & MSG_WAITALL) && (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) { 671f9ead18cSJens Axboe out_free: 672f9ead18cSJens Axboe req_set_fail(req); 673f9ead18cSJens Axboe } 674f9ead18cSJens Axboe 675d4e097daSDylan Yudaken if (ret > 0) 676f9ead18cSJens Axboe ret += sr->done_io; 677f9ead18cSJens Axboe else if (sr->done_io) 678f9ead18cSJens Axboe ret = sr->done_io; 679d4e097daSDylan Yudaken else 680d4e097daSDylan Yudaken io_kbuf_recycle(req, issue_flags); 681d4e097daSDylan Yudaken 682f9ead18cSJens Axboe cflags = io_put_kbuf(req, issue_flags); 683f9ead18cSJens Axboe if (msg.msg_inq) 684f9ead18cSJens Axboe cflags |= IORING_CQE_F_SOCK_NONEMPTY; 685b3fdea6eSDylan Yudaken 686b3fdea6eSDylan Yudaken if (!io_recv_finish(req, &ret, cflags)) 687b3fdea6eSDylan Yudaken goto retry_multishot; 688b3fdea6eSDylan Yudaken 689b3fdea6eSDylan Yudaken return ret; 690f9ead18cSJens Axboe } 691f9ead18cSJens Axboe 692f9ead18cSJens Axboe int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 693f9ead18cSJens Axboe { 694f9ead18cSJens Axboe struct io_accept *accept = io_kiocb_to_cmd(req); 695f9ead18cSJens Axboe unsigned flags; 696f9ead18cSJens Axboe 697f9ead18cSJens Axboe if (sqe->len || sqe->buf_index) 698f9ead18cSJens Axboe return -EINVAL; 699f9ead18cSJens Axboe 700f9ead18cSJens Axboe accept->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); 701f9ead18cSJens Axboe accept->addr_len = u64_to_user_ptr(READ_ONCE(sqe->addr2)); 702f9ead18cSJens Axboe accept->flags = READ_ONCE(sqe->accept_flags); 703f9ead18cSJens Axboe accept->nofile = rlimit(RLIMIT_NOFILE); 704f9ead18cSJens Axboe flags = READ_ONCE(sqe->ioprio); 705f9ead18cSJens Axboe if (flags & ~IORING_ACCEPT_MULTISHOT) 706f9ead18cSJens Axboe return -EINVAL; 707f9ead18cSJens Axboe 708f9ead18cSJens Axboe accept->file_slot = READ_ONCE(sqe->file_index); 709f9ead18cSJens Axboe if (accept->file_slot) { 710f9ead18cSJens Axboe if (accept->flags & SOCK_CLOEXEC) 711f9ead18cSJens Axboe return -EINVAL; 712f9ead18cSJens Axboe if (flags & IORING_ACCEPT_MULTISHOT && 713f9ead18cSJens Axboe accept->file_slot != IORING_FILE_INDEX_ALLOC) 714f9ead18cSJens Axboe return -EINVAL; 715f9ead18cSJens Axboe } 716f9ead18cSJens Axboe if (accept->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) 717f9ead18cSJens Axboe return -EINVAL; 718f9ead18cSJens Axboe if (SOCK_NONBLOCK != O_NONBLOCK && (accept->flags & SOCK_NONBLOCK)) 719f9ead18cSJens Axboe accept->flags = (accept->flags & ~SOCK_NONBLOCK) | O_NONBLOCK; 720f9ead18cSJens Axboe if (flags & IORING_ACCEPT_MULTISHOT) 721f9ead18cSJens Axboe req->flags |= REQ_F_APOLL_MULTISHOT; 722f9ead18cSJens Axboe return 0; 723f9ead18cSJens Axboe } 724f9ead18cSJens Axboe 725f9ead18cSJens Axboe int io_accept(struct io_kiocb *req, unsigned int issue_flags) 726f9ead18cSJens Axboe { 727f9ead18cSJens Axboe struct io_ring_ctx *ctx = req->ctx; 728f9ead18cSJens Axboe struct io_accept *accept = io_kiocb_to_cmd(req); 729f9ead18cSJens Axboe bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; 730f9ead18cSJens Axboe unsigned int file_flags = force_nonblock ? O_NONBLOCK : 0; 731f9ead18cSJens Axboe bool fixed = !!accept->file_slot; 732f9ead18cSJens Axboe struct file *file; 733f9ead18cSJens Axboe int ret, fd; 734f9ead18cSJens Axboe 735f9ead18cSJens Axboe retry: 736f9ead18cSJens Axboe if (!fixed) { 737f9ead18cSJens Axboe fd = __get_unused_fd_flags(accept->flags, accept->nofile); 738f9ead18cSJens Axboe if (unlikely(fd < 0)) 739f9ead18cSJens Axboe return fd; 740f9ead18cSJens Axboe } 741f9ead18cSJens Axboe file = do_accept(req->file, file_flags, accept->addr, accept->addr_len, 742f9ead18cSJens Axboe accept->flags); 743f9ead18cSJens Axboe if (IS_ERR(file)) { 744f9ead18cSJens Axboe if (!fixed) 745f9ead18cSJens Axboe put_unused_fd(fd); 746f9ead18cSJens Axboe ret = PTR_ERR(file); 747f9ead18cSJens Axboe if (ret == -EAGAIN && force_nonblock) { 748f9ead18cSJens Axboe /* 749f9ead18cSJens Axboe * if it's multishot and polled, we don't need to 750f9ead18cSJens Axboe * return EAGAIN to arm the poll infra since it 751f9ead18cSJens Axboe * has already been done 752f9ead18cSJens Axboe */ 753f9ead18cSJens Axboe if ((req->flags & IO_APOLL_MULTI_POLLED) == 754f9ead18cSJens Axboe IO_APOLL_MULTI_POLLED) 755f9ead18cSJens Axboe ret = IOU_ISSUE_SKIP_COMPLETE; 756f9ead18cSJens Axboe return ret; 757f9ead18cSJens Axboe } 758f9ead18cSJens Axboe if (ret == -ERESTARTSYS) 759f9ead18cSJens Axboe ret = -EINTR; 760f9ead18cSJens Axboe req_set_fail(req); 761f9ead18cSJens Axboe } else if (!fixed) { 762f9ead18cSJens Axboe fd_install(fd, file); 763f9ead18cSJens Axboe ret = fd; 764f9ead18cSJens Axboe } else { 765f9ead18cSJens Axboe ret = io_fixed_fd_install(req, issue_flags, file, 766f9ead18cSJens Axboe accept->file_slot); 767f9ead18cSJens Axboe } 768f9ead18cSJens Axboe 769f9ead18cSJens Axboe if (!(req->flags & REQ_F_APOLL_MULTISHOT)) { 770f9ead18cSJens Axboe io_req_set_res(req, ret, 0); 771f9ead18cSJens Axboe return IOU_OK; 772f9ead18cSJens Axboe } 773f9ead18cSJens Axboe 774cbd25748SDylan Yudaken if (ret >= 0 && 775cbd25748SDylan Yudaken io_post_aux_cqe(ctx, req->cqe.user_data, ret, IORING_CQE_F_MORE, false)) 776d245bca6SPavel Begunkov goto retry; 777cbd25748SDylan Yudaken 778cbd25748SDylan Yudaken io_req_set_res(req, ret, 0); 779cbd25748SDylan Yudaken if (req->flags & REQ_F_POLLED) 780cbd25748SDylan Yudaken return IOU_STOP_MULTISHOT; 781cbd25748SDylan Yudaken return IOU_OK; 782f9ead18cSJens Axboe } 783f9ead18cSJens Axboe 784f9ead18cSJens Axboe int io_socket_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 785f9ead18cSJens Axboe { 786f9ead18cSJens Axboe struct io_socket *sock = io_kiocb_to_cmd(req); 787f9ead18cSJens Axboe 788f9ead18cSJens Axboe if (sqe->addr || sqe->rw_flags || sqe->buf_index) 789f9ead18cSJens Axboe return -EINVAL; 790f9ead18cSJens Axboe 791f9ead18cSJens Axboe sock->domain = READ_ONCE(sqe->fd); 792f9ead18cSJens Axboe sock->type = READ_ONCE(sqe->off); 793f9ead18cSJens Axboe sock->protocol = READ_ONCE(sqe->len); 794f9ead18cSJens Axboe sock->file_slot = READ_ONCE(sqe->file_index); 795f9ead18cSJens Axboe sock->nofile = rlimit(RLIMIT_NOFILE); 796f9ead18cSJens Axboe 797f9ead18cSJens Axboe sock->flags = sock->type & ~SOCK_TYPE_MASK; 798f9ead18cSJens Axboe if (sock->file_slot && (sock->flags & SOCK_CLOEXEC)) 799f9ead18cSJens Axboe return -EINVAL; 800f9ead18cSJens Axboe if (sock->flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) 801f9ead18cSJens Axboe return -EINVAL; 802f9ead18cSJens Axboe return 0; 803f9ead18cSJens Axboe } 804f9ead18cSJens Axboe 805f9ead18cSJens Axboe int io_socket(struct io_kiocb *req, unsigned int issue_flags) 806f9ead18cSJens Axboe { 807f9ead18cSJens Axboe struct io_socket *sock = io_kiocb_to_cmd(req); 808f9ead18cSJens Axboe bool fixed = !!sock->file_slot; 809f9ead18cSJens Axboe struct file *file; 810f9ead18cSJens Axboe int ret, fd; 811f9ead18cSJens Axboe 812f9ead18cSJens Axboe if (!fixed) { 813f9ead18cSJens Axboe fd = __get_unused_fd_flags(sock->flags, sock->nofile); 814f9ead18cSJens Axboe if (unlikely(fd < 0)) 815f9ead18cSJens Axboe return fd; 816f9ead18cSJens Axboe } 817f9ead18cSJens Axboe file = __sys_socket_file(sock->domain, sock->type, sock->protocol); 818f9ead18cSJens Axboe if (IS_ERR(file)) { 819f9ead18cSJens Axboe if (!fixed) 820f9ead18cSJens Axboe put_unused_fd(fd); 821f9ead18cSJens Axboe ret = PTR_ERR(file); 822f9ead18cSJens Axboe if (ret == -EAGAIN && (issue_flags & IO_URING_F_NONBLOCK)) 823f9ead18cSJens Axboe return -EAGAIN; 824f9ead18cSJens Axboe if (ret == -ERESTARTSYS) 825f9ead18cSJens Axboe ret = -EINTR; 826f9ead18cSJens Axboe req_set_fail(req); 827f9ead18cSJens Axboe } else if (!fixed) { 828f9ead18cSJens Axboe fd_install(fd, file); 829f9ead18cSJens Axboe ret = fd; 830f9ead18cSJens Axboe } else { 831f9ead18cSJens Axboe ret = io_fixed_fd_install(req, issue_flags, file, 832f9ead18cSJens Axboe sock->file_slot); 833f9ead18cSJens Axboe } 834f9ead18cSJens Axboe io_req_set_res(req, ret, 0); 835f9ead18cSJens Axboe return IOU_OK; 836f9ead18cSJens Axboe } 837f9ead18cSJens Axboe 838f9ead18cSJens Axboe int io_connect_prep_async(struct io_kiocb *req) 839f9ead18cSJens Axboe { 840f9ead18cSJens Axboe struct io_async_connect *io = req->async_data; 841f9ead18cSJens Axboe struct io_connect *conn = io_kiocb_to_cmd(req); 842f9ead18cSJens Axboe 843f9ead18cSJens Axboe return move_addr_to_kernel(conn->addr, conn->addr_len, &io->address); 844f9ead18cSJens Axboe } 845f9ead18cSJens Axboe 846f9ead18cSJens Axboe int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 847f9ead18cSJens Axboe { 848f9ead18cSJens Axboe struct io_connect *conn = io_kiocb_to_cmd(req); 849f9ead18cSJens Axboe 850f9ead18cSJens Axboe if (sqe->len || sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in) 851f9ead18cSJens Axboe return -EINVAL; 852f9ead18cSJens Axboe 853f9ead18cSJens Axboe conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr)); 854f9ead18cSJens Axboe conn->addr_len = READ_ONCE(sqe->addr2); 855f9ead18cSJens Axboe return 0; 856f9ead18cSJens Axboe } 857f9ead18cSJens Axboe 858f9ead18cSJens Axboe int io_connect(struct io_kiocb *req, unsigned int issue_flags) 859f9ead18cSJens Axboe { 860f9ead18cSJens Axboe struct io_connect *connect = io_kiocb_to_cmd(req); 861f9ead18cSJens Axboe struct io_async_connect __io, *io; 862f9ead18cSJens Axboe unsigned file_flags; 863f9ead18cSJens Axboe int ret; 864f9ead18cSJens Axboe bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; 865f9ead18cSJens Axboe 866f9ead18cSJens Axboe if (req_has_async_data(req)) { 867f9ead18cSJens Axboe io = req->async_data; 868f9ead18cSJens Axboe } else { 869f9ead18cSJens Axboe ret = move_addr_to_kernel(connect->addr, 870f9ead18cSJens Axboe connect->addr_len, 871f9ead18cSJens Axboe &__io.address); 872f9ead18cSJens Axboe if (ret) 873f9ead18cSJens Axboe goto out; 874f9ead18cSJens Axboe io = &__io; 875f9ead18cSJens Axboe } 876f9ead18cSJens Axboe 877f9ead18cSJens Axboe file_flags = force_nonblock ? O_NONBLOCK : 0; 878f9ead18cSJens Axboe 879f9ead18cSJens Axboe ret = __sys_connect_file(req->file, &io->address, 880f9ead18cSJens Axboe connect->addr_len, file_flags); 881f9ead18cSJens Axboe if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) { 882f9ead18cSJens Axboe if (req_has_async_data(req)) 883f9ead18cSJens Axboe return -EAGAIN; 884f9ead18cSJens Axboe if (io_alloc_async_data(req)) { 885f9ead18cSJens Axboe ret = -ENOMEM; 886f9ead18cSJens Axboe goto out; 887f9ead18cSJens Axboe } 888f9ead18cSJens Axboe memcpy(req->async_data, &__io, sizeof(__io)); 889f9ead18cSJens Axboe return -EAGAIN; 890f9ead18cSJens Axboe } 891f9ead18cSJens Axboe if (ret == -ERESTARTSYS) 892f9ead18cSJens Axboe ret = -EINTR; 893f9ead18cSJens Axboe out: 894f9ead18cSJens Axboe if (ret < 0) 895f9ead18cSJens Axboe req_set_fail(req); 896f9ead18cSJens Axboe io_req_set_res(req, ret, 0); 897f9ead18cSJens Axboe return IOU_OK; 898f9ead18cSJens Axboe } 89943e0bbbdSJens Axboe 90043e0bbbdSJens Axboe void io_netmsg_cache_free(struct io_cache_entry *entry) 90143e0bbbdSJens Axboe { 90243e0bbbdSJens Axboe kfree(container_of(entry, struct io_async_msghdr, cache)); 90343e0bbbdSJens Axboe } 904f9ead18cSJens Axboe #endif 905