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
16861686 #endif
16871687 }
16881688
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+
16891723 static void io_poll_remove_one(struct io_kiocb *req)
16901724 {
16911725 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
21732207 case IORING_OP_TIMEOUT_REMOVE:
21742208 ret = io_timeout_remove(req, s->sqe);
21752209 break;
2210+ case IORING_OP_ACCEPT:
2211+ ret = io_accept(req, s->sqe, nxt, force_nonblock);
2212+ break;
21762213 default:
21772214 ret = -EINVAL;
21782215 break;
include/uapi/linux/io_uring.h+6−1
@@ -19,7 +19,10 @@ struct io_uring_sqe { · 18 unmodified lines
1919 __u8 flags; /* IOSQE_ flags */
2020 __u16 ioprio; /* ioprio for the request */
2121 __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+ };
2326 __u64 addr; /* pointer to buffer or iovecs */
2427 __u32 len; /* buffer size or number of iovecs */
2528 union {
@@ -29,6 +32,7 @@ struct io_uring_sqe { · 3 unmodified lines
2932 __u32 sync_range_flags;
3033 __u32 msg_flags;
3134 __u32 timeout_flags;
35+ __u32 accept_flags;
3236 };
3337 __u64 user_data; /* data to be passed back at completion time */
3438 union {
@@ -65,6 +69,7 @@ struct io_uring_sqe { · 30 unmodified lines
6569 #define IORING_OP_RECVMSG 10
6670 #define IORING_OP_TIMEOUT 11
6771 #define IORING_OP_TIMEOUT_REMOVE 12
72+#define IORING_OP_ACCEPT 13
6873
6974 /*
7075 * sqe->fsync_flags