Skip to content

Commit

Permalink
io_uring: move epoll handler to its own file
Browse files Browse the repository at this point in the history
Would be nice to sort out Kconfig for this and don't even compile
epoll.c if we don't have epoll configured.

Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
axboe committed Jul 25, 2022
1 parent 4cf9049 commit a9c210c
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 50 deletions.
2 changes: 1 addition & 1 deletion io_uring/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
62 changes: 62 additions & 0 deletions io_uring/epoll.c
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions io_uring/epoll.h
Original file line number Diff line number Diff line change
@@ -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
50 changes: 1 addition & 49 deletions io_uring/io_uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit a9c210c

Please sign in to comment.