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
74#include <linux/namei.h>74#include <linux/namei.h>
75#include <linux/fsnotify.h>75#include <linux/fsnotify.h>
76#include <linux/fadvise.h>76#include <linux/fadvise.h>
77#include <linux/eventpoll.h>
77 78
78#define CREATE_TRACE_POINTS79#define CREATE_TRACE_POINTS
79#include <trace/events/io_uring.h>80#include <trace/events/io_uring.h>
@@ -423,6 +424,14 @@ struct io_madvise { · 343 unmodified lines
423 u32 advice;424 u32 advice;
424};425};
425 426
427struct io_epoll {
428 struct file *file;
429 int epfd;
430 int op;
431 int fd;
432 struct epoll_event event;
433};
434
426struct io_async_connect {435struct io_async_connect {
427 struct sockaddr_storage address;436 struct sockaddr_storage address;
428};437};
@@ -536,6 +545,7 @@ struct io_kiocb { · 107 unmodified lines
536 struct io_files_update files_update;545 struct io_files_update files_update;
537 struct io_fadvise fadvise;546 struct io_fadvise fadvise;
538 struct io_madvise madvise;547 struct io_madvise madvise;
548 struct io_epoll epoll;
539 };549 };
540 550
541 struct io_async_ctx *io;551 struct io_async_ctx *io;
@@ -728,6 +738,10 @@ static const struct io_op_def io_op_defs[] = { · 186 unmodified lines
728 .fd_non_neg = 1,738 .fd_non_neg = 1,
729 .file_table = 1,739 .file_table = 1,
730 },740 },
741 [IORING_OP_EPOLL_CTL] = {
742 .unbound_nonreg_file = 1,
743 .file_table = 1,
744 },
731};745};
732 746
733static void io_wq_submit_work(struct io_wq_work **workptr);747static 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
2611 return io_openat2(req, nxt, force_nonblock);2625 return io_openat2(req, nxt, force_nonblock);
2612}2626}
2613 2627
2628static 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
2653static 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
2614static int io_madvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)2674static int io_madvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
2615{2675{
2616#if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU)2676#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
4075 case IORING_OP_OPENAT2:4135 case IORING_OP_OPENAT2:
4076 ret = io_openat2_prep(req, sqe);4136 ret = io_openat2_prep(req, sqe);
4077 break;4137 break;
4138 case IORING_OP_EPOLL_CTL:
4139 ret = io_epoll_ctl_prep(req, sqe);
4140 break;
4078 default:4141 default:
4079 printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n",4142 printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n",
4080 req->opcode);4143 req->opcode);
@@ -4303,6 +4366,14 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 222 unmodified lines
4303 }4366 }
4304 ret = io_openat2(req, nxt, force_nonblock);4367 ret = io_openat2(req, nxt, force_nonblock);
4305 break;4368 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;
4306 default:4377 default:
4307 ret = -EINVAL;4378 ret = -EINVAL;
4308 break;4379 break;
include/uapi/linux/io_uring.h+1−0
@@ -112,6 +112,7 @@ enum { · 111 unmodified lines
112 IORING_OP_SEND,112 IORING_OP_SEND,
113 IORING_OP_RECV,113 IORING_OP_RECV,
114 IORING_OP_OPENAT2,114 IORING_OP_OPENAT2,
115 IORING_OP_EPOLL_CTL,
115 116
116 /* this goes last, obviously */117 /* this goes last, obviously */
117 IORING_OP_LAST,118 IORING_OP_LAST,