History

io_uring: add support for IORING_OP_ACCEPT

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.

Jens Axboe committed 7 years ago

Commit 17f2fe31 parent de2ea4b2 files · +43 −1Browse files

Unified · Split

2 files
  1. fs/io_uring.c +37 −0
  2. include/uapi/linux/io_uring.h +6 −1
fs/io_uring.c+37−0
@@ -1686,6 +1686,40 @@ static int io_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 1685 unmodified lines
1686#endif1686#endif
1687}1687}
1688 1688
1689static 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
1689static void io_poll_remove_one(struct io_kiocb *req)1723static 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;
include/uapi/linux/io_uring.h+6−1
@@ -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 1069#define IORING_OP_RECVMSG 10
66#define IORING_OP_TIMEOUT 1170#define IORING_OP_TIMEOUT 11
67#define IORING_OP_TIMEOUT_REMOVE 1271#define IORING_OP_TIMEOUT_REMOVE 12
72#define IORING_OP_ACCEPT 13
68 73
69/*74/*
70 * sqe->fsync_flags75 * sqe->fsync_flags