File Index
Files and directories
Sign in
FILE

epoll.c

File preview with syntax highlighting.

linux-6.19.14/io_uring/epoll.c C
 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
15struct io_epoll {
16	struct file			*file;
17	int				epfd;
18	int				op;
19	int				fd;
20	struct epoll_event		event;
21};
22
23struct io_epoll_wait {
24	struct file			*file;
25	int				maxevents;
26	struct epoll_event __user	*events;
27};
28
29int io_epoll_ctl_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
30{
31	struct io_epoll *epoll = io_kiocb_to_cmd(req, struct io_epoll);
32
33	if (sqe->buf_index || sqe->splice_fd_in)
34		return -EINVAL;
35
36	epoll->epfd = READ_ONCE(sqe->fd);
37	epoll->op = READ_ONCE(sqe->len);
38	epoll->fd = READ_ONCE(sqe->off);
39
40	if (ep_op_has_event(epoll->op)) {
41		struct epoll_event __user *ev;
42
43		ev = u64_to_user_ptr(READ_ONCE(sqe->addr));
44		if (copy_from_user(&epoll->event, ev, sizeof(*ev)))
45			return -EFAULT;
46	}
47
48	return 0;
49}
50
51int io_epoll_ctl(struct io_kiocb *req, unsigned int issue_flags)
52{
53	struct io_epoll *ie = io_kiocb_to_cmd(req, struct io_epoll);
54	int ret;
55	bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
56
57	ret = do_epoll_ctl(ie->epfd, ie->op, ie->fd, &ie->event, force_nonblock);
58	if (force_nonblock && ret == -EAGAIN)
59		return -EAGAIN;
60
61	if (ret < 0)
62		req_set_fail(req);
63	io_req_set_res(req, ret, 0);
64	return IOU_COMPLETE;
65}
66
67int io_epoll_wait_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
68{
69	struct io_epoll_wait *iew = io_kiocb_to_cmd(req, struct io_epoll_wait);
70
71	if (sqe->off || sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in)
72		return -EINVAL;
73
74	iew->maxevents = READ_ONCE(sqe->len);
75	iew->events = u64_to_user_ptr(READ_ONCE(sqe->addr));
76	return 0;
77}
78
79int io_epoll_wait(struct io_kiocb *req, unsigned int issue_flags)
80{
81	struct io_epoll_wait *iew = io_kiocb_to_cmd(req, struct io_epoll_wait);
82	int ret;
83
84	ret = epoll_sendevents(req->file, iew->events, iew->maxevents);
85	if (ret == 0)
86		return -EAGAIN;
87	if (ret < 0)
88		req_set_fail(req);
89
90	io_req_set_res(req, ret, 0);
91	return IOU_COMPLETE;
92}
~/ Read-only file preview.