History

io_uring: add support for epoll_ctl(2)

This adds IORING_OP_EPOLL_CTL, which can perform the same work as the epoll_ctl(2) system call.

Jens Axboe committed 6 years ago

Commit 3e4827b1 parent 39220e82 files · +72 −0Browse files

Unified · Split

2 files
  1. fs/io_uring.c +71 −0
  2. include/uapi/linux/io_uring.h +1 −0
fs/io_uring.c+71−0
@@ -74,6 +74,7 @@ · 73 unmodified lines
7474 #include <linux/namei.h>
7575 #include <linux/fsnotify.h>
7676 #include <linux/fadvise.h>
77+#include <linux/eventpoll.h>
7778
7879 #define CREATE_TRACE_POINTS
7980 #include <trace/events/io_uring.h>
@@ -423,6 +424,14 @@ struct io_madvise { · 343 unmodified lines
423424 u32 advice;
424425 };
425426
427+struct io_epoll {
428+ struct file *file;
429+ int epfd;
430+ int op;
431+ int fd;
432+ struct epoll_event event;
433+};
434+
426435 struct io_async_connect {
427436 struct sockaddr_storage address;
428437 };
@@ -536,6 +545,7 @@ struct io_kiocb { · 107 unmodified lines
536545 struct io_files_update files_update;
537546 struct io_fadvise fadvise;
538547 struct io_madvise madvise;
548+ struct io_epoll epoll;
539549 };
540550
541551 struct io_async_ctx *io;
@@ -728,6 +738,10 @@ static const struct io_op_def io_op_defs[] = { · 186 unmodified lines
728738 .fd_non_neg = 1,
729739 .file_table = 1,
730740 },
741+ [IORING_OP_EPOLL_CTL] = {
742+ .unbound_nonreg_file = 1,
743+ .file_table = 1,
744+ },
731745 };
732746
733747 static void io_wq_submit_work(struct io_wq_work **workptr);
@@ -2611,6 +2625,52 @@ static int io_openat(struct io_kiocb *req, struct io_kiocb **nxt, · 1877 unmodified lines
26112625 return io_openat2(req, nxt, force_nonblock);
26122626 }
26132627
2628+static int io_epoll_ctl_prep(struct io_kiocb *req,
2629+ const struct io_uring_sqe *sqe)
2630+{
2631+#if defined(CONFIG_EPOLL)
2632+ if (sqe->ioprio || sqe->buf_index)
2633+ return -EINVAL;
2634+
2635+ req->epoll.epfd = READ_ONCE(sqe->fd);
2636+ req->epoll.op = READ_ONCE(sqe->len);
2637+ req->epoll.fd = READ_ONCE(sqe->off);
2638+
2639+ if (ep_op_has_event(req->epoll.op)) {
2640+ struct epoll_event __user *ev;
2641+
2642+ ev = u64_to_user_ptr(READ_ONCE(sqe->addr));
2643+ if (copy_from_user(&req->epoll.event, ev, sizeof(*ev)))
2644+ return -EFAULT;
2645+ }
2646+
2647+ return 0;
2648+#else
2649+ return -EOPNOTSUPP;
2650+#endif
2651+}
2652+
2653+static int io_epoll_ctl(struct io_kiocb *req, struct io_kiocb **nxt,
2654+ bool force_nonblock)
2655+{
2656+#if defined(CONFIG_EPOLL)
2657+ struct io_epoll *ie = &req->epoll;
2658+ int ret;
2659+
2660+ ret = do_epoll_ctl(ie->epfd, ie->op, ie->fd, &ie->event, force_nonblock);
2661+ if (force_nonblock && ret == -EAGAIN)
2662+ return -EAGAIN;
2663+
2664+ if (ret < 0)
2665+ req_set_fail_links(req);
2666+ io_cqring_add_event(req, ret);
2667+ io_put_req_find_next(req, nxt);
2668+ return 0;
2669+#else
2670+ return -EOPNOTSUPP;
2671+#endif
2672+}
2673+
26142674 static int io_madvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
26152675 {
26162676 #if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU)
@@ -4075,6 +4135,9 @@ static int io_req_defer_prep(struct io_kiocb *req, · 1458 unmodified lines
40754135 case IORING_OP_OPENAT2:
40764136 ret = io_openat2_prep(req, sqe);
40774137 break;
4138+ case IORING_OP_EPOLL_CTL:
4139+ ret = io_epoll_ctl_prep(req, sqe);
4140+ break;
40784141 default:
40794142 printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n",
40804143 req->opcode);
@@ -4303,6 +4366,14 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 222 unmodified lines
43034366 }
43044367 ret = io_openat2(req, nxt, force_nonblock);
43054368 break;
4369+ case IORING_OP_EPOLL_CTL:
4370+ if (sqe) {
4371+ ret = io_epoll_ctl_prep(req, sqe);
4372+ if (ret)
4373+ break;
4374+ }
4375+ ret = io_epoll_ctl(req, nxt, force_nonblock);
4376+ break;
43064377 default:
43074378 ret = -EINVAL;
43084379 break;
include/uapi/linux/io_uring.h+1−0
@@ -112,6 +112,7 @@ enum { · 111 unmodified lines
112112 IORING_OP_SEND,
113113 IORING_OP_RECV,
114114 IORING_OP_OPENAT2,
115+ IORING_OP_EPOLL_CTL,
115116
116117 /* this goes last, obviously */
117118 IORING_OP_LAST,