summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--io_uring/Makefile2
-rw-r--r--io_uring/epoll.c62
-rw-r--r--io_uring/epoll.h6
-rw-r--r--io_uring/io_uring.c50
4 files changed, 70 insertions, 50 deletions
diff --git a/io_uring/Makefile b/io_uring/Makefile
index 2e2cbeb272a8..59e70f2d8c56 100644
--- a/io_uring/Makefile
+++ b/io_uring/Makefile
@@ -4,5 +4,5 @@
obj-$(CONFIG_IO_URING) += io_uring.o xattr.o nop.o fs.o splice.o \
sync.o advise.o filetable.o \
- openclose.o uring_cmd.o
+ openclose.o uring_cmd.o epoll.o
obj-$(CONFIG_IO_WQ) += io-wq.o
diff --git a/io_uring/epoll.c b/io_uring/epoll.c
new file mode 100644
index 000000000000..acbb32498127
--- /dev/null
+++ b/io_uring/epoll.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/io_uring.h>
+#include <linux/eventpoll.h>
+
+#include <uapi/linux/io_uring.h>
+
+#include "io_uring_types.h"
+#include "io_uring.h"
+#include "epoll.h"
+
+#if defined(CONFIG_EPOLL)
+struct io_epoll {
+ struct file *file;
+ int epfd;
+ int op;
+ int fd;
+ struct epoll_event event;
+};
+
+int io_epoll_ctl_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+{
+ struct io_epoll *epoll = io_kiocb_to_cmd(req);
+
+ if (sqe->buf_index || sqe->splice_fd_in)
+ return -EINVAL;
+
+ epoll->epfd = READ_ONCE(sqe->fd);
+ epoll->op = READ_ONCE(sqe->len);
+ epoll->fd = READ_ONCE(sqe->off);
+
+ if (ep_op_has_event(epoll->op)) {
+ struct epoll_event __user *ev;
+
+ ev = u64_to_user_ptr(READ_ONCE(sqe->addr));
+ if (copy_from_user(&epoll->event, ev, sizeof(*ev)))
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int io_epoll_ctl(struct io_kiocb *req, unsigned int issue_flags)
+{
+ struct io_epoll *ie = io_kiocb_to_cmd(req);
+ int ret;
+ bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
+
+ ret = do_epoll_ctl(ie->epfd, ie->op, ie->fd, &ie->event, force_nonblock);
+ if (force_nonblock && ret == -EAGAIN)
+ return -EAGAIN;
+
+ if (ret < 0)
+ req_set_fail(req);
+ io_req_set_res(req, ret, 0);
+ return IOU_OK;
+}
+#endif
diff --git a/io_uring/epoll.h b/io_uring/epoll.h
new file mode 100644
index 000000000000..870cce11ba98
--- /dev/null
+++ b/io_uring/epoll.h
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#if defined(CONFIG_EPOLL)
+int io_epoll_ctl_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+int io_epoll_ctl(struct io_kiocb *req, unsigned int issue_flags);
+#endif
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index 15d0377b7d9d..78828e294e53 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -100,6 +100,7 @@
#include "advise.h"
#include "openclose.h"
#include "uring_cmd.h"
+#include "epoll.h"
#define IORING_MAX_ENTRIES 32768
#define IORING_MAX_CQ_ENTRIES (2 * IORING_MAX_ENTRIES)
@@ -374,14 +375,6 @@ struct io_rsrc_update {
u32 offset;
};
-struct io_epoll {
- struct file *file;
- int epfd;
- int op;
- int fd;
- struct epoll_event event;
-};
-
struct io_provide_buf {
struct file *file;
__u64 addr;
@@ -4040,47 +4033,6 @@ static __maybe_unused int io_eopnotsupp_prep(struct io_kiocb *kiocb,
return -EOPNOTSUPP;
}
-#if defined(CONFIG_EPOLL)
-static int io_epoll_ctl_prep(struct io_kiocb *req,
- const struct io_uring_sqe *sqe)
-{
- struct io_epoll *epoll = io_kiocb_to_cmd(req);
-
- if (sqe->buf_index || sqe->splice_fd_in)
- return -EINVAL;
-
- epoll->epfd = READ_ONCE(sqe->fd);
- epoll->op = READ_ONCE(sqe->len);
- epoll->fd = READ_ONCE(sqe->off);
-
- if (ep_op_has_event(epoll->op)) {
- struct epoll_event __user *ev;
-
- ev = u64_to_user_ptr(READ_ONCE(sqe->addr));
- if (copy_from_user(&epoll->event, ev, sizeof(*ev)))
- return -EFAULT;
- }
-
- return 0;
-}
-
-static int io_epoll_ctl(struct io_kiocb *req, unsigned int issue_flags)
-{
- struct io_epoll *ie = io_kiocb_to_cmd(req);
- int ret;
- bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
-
- ret = do_epoll_ctl(ie->epfd, ie->op, ie->fd, &ie->event, force_nonblock);
- if (force_nonblock && ret == -EAGAIN)
- return -EAGAIN;
-
- if (ret < 0)
- req_set_fail(req);
- io_req_set_res(req, ret, 0);
- return IOU_OK;
-}
-#endif
-
static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{
struct io_statx *sx = io_kiocb_to_cmd(req);