This allows an application to call accept4() in an async fashion. Like other opcodes, we first try a non-blocking accept, then punt to async context if we have to.
Unified · Split
| @@ -1686,6 +1686,40 @@ static int io_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 1685 unmodified lines | |||
| 1686 | #endif | 1686 | #endif |
| 1687 | } | 1687 | } |
| 1688 | 1688 | ||
| 1689 | static int io_accept(struct io_kiocb *req, const struct io_uring_sqe *sqe, | ||
| 1690 | struct io_kiocb **nxt, bool force_nonblock) | ||
| 1691 | { | ||
| 1692 | #if defined(CONFIG_NET) | ||
| 1693 | struct sockaddr __user *addr; | ||
| 1694 | int __user *addr_len; | ||
| 1695 | unsigned file_flags; | ||
| 1696 | int flags, ret; | ||
| 1697 | |||
| 1698 | if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL))) | ||
| 1699 | return -EINVAL; | ||
| 1700 | if (sqe->ioprio || sqe->off || sqe->len || sqe->buf_index) | ||
| 1701 | return -EINVAL; | ||
| 1702 | |||
| 1703 | addr = (struct sockaddr __user *) (unsigned long) READ_ONCE(sqe->addr); | ||
| 1704 | addr_len = (int __user *) (unsigned long) READ_ONCE(sqe->addr2); | ||
| 1705 | flags = READ_ONCE(sqe->accept_flags); | ||
| 1706 | file_flags = force_nonblock ? O_NONBLOCK : 0; | ||
| 1707 | |||
| 1708 | ret = __sys_accept4_file(req->file, file_flags, addr, addr_len, flags); | ||
| 1709 | if (ret == -EAGAIN && force_nonblock) { | ||
| 1710 | req->work.flags |= IO_WQ_WORK_NEEDS_FILES; | ||
| 1711 | return -EAGAIN; | ||
| 1712 | } | ||
| 1713 | if (ret < 0 && (req->flags & REQ_F_LINK)) | ||
| 1714 | req->flags |= REQ_F_FAIL_LINK; | ||
| 1715 | io_cqring_add_event(req->ctx, sqe->user_data, ret); | ||
| 1716 | io_put_req(req, nxt); | ||
| 1717 | return 0; | ||
| 1718 | #else | ||
| 1719 | return -EOPNOTSUPP; | ||
| 1720 | #endif | ||
| 1721 | } | ||
| 1722 | |||
| 1689 | static void io_poll_remove_one(struct io_kiocb *req) | 1723 | static void io_poll_remove_one(struct io_kiocb *req) |
| 1690 | { | 1724 | { |
| 1691 | struct io_poll_iocb *poll = &req->poll; | 1725 | struct io_poll_iocb *poll = &req->poll; |
| @@ -2173,6 +2207,9 @@ static int __io_submit_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, · 481 unmodified lines | |||
| 2173 | case IORING_OP_TIMEOUT_REMOVE: | 2207 | case IORING_OP_TIMEOUT_REMOVE: |
| 2174 | ret = io_timeout_remove(req, s->sqe); | 2208 | ret = io_timeout_remove(req, s->sqe); |
| 2175 | break; | 2209 | break; |
| 2210 | case IORING_OP_ACCEPT: | ||
| 2211 | ret = io_accept(req, s->sqe, nxt, force_nonblock); | ||
| 2212 | break; | ||
| 2176 | default: | 2213 | default: |
| 2177 | ret = -EINVAL; | 2214 | ret = -EINVAL; |
| 2178 | break; | 2215 | break; |
| @@ -19,7 +19,10 @@ struct io_uring_sqe { · 18 unmodified lines | |||
| 19 | __u8 flags; /* IOSQE_ flags */ | 19 | __u8 flags; /* IOSQE_ flags */ |
| 20 | __u16 ioprio; /* ioprio for the request */ | 20 | __u16 ioprio; /* ioprio for the request */ |
| 21 | __s32 fd; /* file descriptor to do IO on */ | 21 | __s32 fd; /* file descriptor to do IO on */ |
| 22 | __u64 off; /* offset into file */ | 22 | union { |
| 23 | __u64 off; /* offset into file */ | ||
| 24 | __u64 addr2; | ||
| 25 | }; | ||
| 23 | __u64 addr; /* pointer to buffer or iovecs */ | 26 | __u64 addr; /* pointer to buffer or iovecs */ |
| 24 | __u32 len; /* buffer size or number of iovecs */ | 27 | __u32 len; /* buffer size or number of iovecs */ |
| 25 | union { | 28 | union { |
| @@ -29,6 +32,7 @@ struct io_uring_sqe { · 3 unmodified lines | |||
| 29 | __u32 sync_range_flags; | 32 | __u32 sync_range_flags; |
| 30 | __u32 msg_flags; | 33 | __u32 msg_flags; |
| 31 | __u32 timeout_flags; | 34 | __u32 timeout_flags; |
| 35 | __u32 accept_flags; | ||
| 32 | }; | 36 | }; |
| 33 | __u64 user_data; /* data to be passed back at completion time */ | 37 | __u64 user_data; /* data to be passed back at completion time */ |
| 34 | union { | 38 | union { |
| @@ -65,6 +69,7 @@ struct io_uring_sqe { · 30 unmodified lines | |||
| 65 | #define IORING_OP_RECVMSG 10 | 69 | #define IORING_OP_RECVMSG 10 |
| 66 | #define IORING_OP_TIMEOUT 11 | 70 | #define IORING_OP_TIMEOUT 11 |
| 67 | #define IORING_OP_TIMEOUT_REMOVE 12 | 71 | #define IORING_OP_TIMEOUT_REMOVE 12 |
| 72 | #define IORING_OP_ACCEPT 13 | ||
| 68 | 73 | ||
| 69 | /* | 74 | /* |
| 70 | * sqe->fsync_flags | 75 | * sqe->fsync_flags |