Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0 2 : #include <linux/kernel.h> 3 : #include <linux/errno.h> 4 : #include <linux/file.h> 5 : #include <linux/fs.h> 6 : #include <linux/uaccess.h> 7 : #include <linux/io_uring.h> 8 : #include <linux/eventpoll.h> 9 : 10 : #include <uapi/linux/io_uring.h> 11 : 12 : #include "io_uring.h" 13 : #include "epoll.h" 14 : 15 : #if defined(CONFIG_EPOLL) 16 : struct io_epoll { 17 : struct file *file; 18 : int epfd; 19 : int op; 20 : int fd; 21 : struct epoll_event event; 22 : }; 23 : 24 0 : int io_epoll_ctl_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 25 : { 26 0 : struct io_epoll *epoll = io_kiocb_to_cmd(req, struct io_epoll); 27 : 28 0 : if (sqe->buf_index || sqe->splice_fd_in) 29 : return -EINVAL; 30 : 31 0 : epoll->epfd = READ_ONCE(sqe->fd); 32 0 : epoll->op = READ_ONCE(sqe->len); 33 0 : epoll->fd = READ_ONCE(sqe->off); 34 : 35 0 : if (ep_op_has_event(epoll->op)) { 36 : struct epoll_event __user *ev; 37 : 38 0 : ev = u64_to_user_ptr(READ_ONCE(sqe->addr)); 39 0 : if (copy_from_user(&epoll->event, ev, sizeof(*ev))) 40 : return -EFAULT; 41 : } 42 : 43 : return 0; 44 : } 45 : 46 0 : int io_epoll_ctl(struct io_kiocb *req, unsigned int issue_flags) 47 : { 48 0 : struct io_epoll *ie = io_kiocb_to_cmd(req, struct io_epoll); 49 : int ret; 50 0 : bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; 51 : 52 0 : ret = do_epoll_ctl(ie->epfd, ie->op, ie->fd, &ie->event, force_nonblock); 53 0 : if (force_nonblock && ret == -EAGAIN) 54 : return -EAGAIN; 55 : 56 0 : if (ret < 0) 57 0 : req_set_fail(req); 58 0 : io_req_set_res(req, ret, 0); 59 0 : return IOU_OK; 60 : } 61 : #endif