mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 17:23:36 +00:00
eventpoll: abstract out epoll_ctl() handler
No functional changes in this patch. Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
f86cd20c94
commit
58e41a44c4
@ -2074,27 +2074,15 @@ SYSCALL_DEFINE1(epoll_create, int, size)
|
||||
return do_epoll_create(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function implements the controller interface for
|
||||
* the eventpoll file that enables the insertion/removal/change of
|
||||
* file descriptors inside the interest set.
|
||||
*/
|
||||
SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||
struct epoll_event __user *, event)
|
||||
static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *epds)
|
||||
{
|
||||
int error;
|
||||
int full_check = 0;
|
||||
struct fd f, tf;
|
||||
struct eventpoll *ep;
|
||||
struct epitem *epi;
|
||||
struct epoll_event epds;
|
||||
struct eventpoll *tep = NULL;
|
||||
|
||||
error = -EFAULT;
|
||||
if (ep_op_has_event(op) &&
|
||||
copy_from_user(&epds, event, sizeof(struct epoll_event)))
|
||||
goto error_return;
|
||||
|
||||
error = -EBADF;
|
||||
f = fdget(epfd);
|
||||
if (!f.file)
|
||||
@ -2112,7 +2100,7 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||
|
||||
/* Check if EPOLLWAKEUP is allowed */
|
||||
if (ep_op_has_event(op))
|
||||
ep_take_care_of_epollwakeup(&epds);
|
||||
ep_take_care_of_epollwakeup(epds);
|
||||
|
||||
/*
|
||||
* We have to check that the file structure underneath the file descriptor
|
||||
@ -2128,11 +2116,11 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||
* so EPOLLEXCLUSIVE is not allowed for a EPOLL_CTL_MOD operation.
|
||||
* Also, we do not currently supported nested exclusive wakeups.
|
||||
*/
|
||||
if (ep_op_has_event(op) && (epds.events & EPOLLEXCLUSIVE)) {
|
||||
if (ep_op_has_event(op) && (epds->events & EPOLLEXCLUSIVE)) {
|
||||
if (op == EPOLL_CTL_MOD)
|
||||
goto error_tgt_fput;
|
||||
if (op == EPOLL_CTL_ADD && (is_file_epoll(tf.file) ||
|
||||
(epds.events & ~EPOLLEXCLUSIVE_OK_BITS)))
|
||||
(epds->events & ~EPOLLEXCLUSIVE_OK_BITS)))
|
||||
goto error_tgt_fput;
|
||||
}
|
||||
|
||||
@ -2192,8 +2180,8 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||
switch (op) {
|
||||
case EPOLL_CTL_ADD:
|
||||
if (!epi) {
|
||||
epds.events |= EPOLLERR | EPOLLHUP;
|
||||
error = ep_insert(ep, &epds, tf.file, fd, full_check);
|
||||
epds->events |= EPOLLERR | EPOLLHUP;
|
||||
error = ep_insert(ep, epds, tf.file, fd, full_check);
|
||||
} else
|
||||
error = -EEXIST;
|
||||
if (full_check)
|
||||
@ -2208,8 +2196,8 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||
case EPOLL_CTL_MOD:
|
||||
if (epi) {
|
||||
if (!(epi->event.events & EPOLLEXCLUSIVE)) {
|
||||
epds.events |= EPOLLERR | EPOLLHUP;
|
||||
error = ep_modify(ep, epi, &epds);
|
||||
epds->events |= EPOLLERR | EPOLLHUP;
|
||||
error = ep_modify(ep, epi, epds);
|
||||
}
|
||||
} else
|
||||
error = -ENOENT;
|
||||
@ -2231,6 +2219,23 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function implements the controller interface for
|
||||
* the eventpoll file that enables the insertion/removal/change of
|
||||
* file descriptors inside the interest set.
|
||||
*/
|
||||
SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||
struct epoll_event __user *, event)
|
||||
{
|
||||
struct epoll_event epds;
|
||||
|
||||
if (ep_op_has_event(op) &&
|
||||
copy_from_user(&epds, event, sizeof(struct epoll_event)))
|
||||
return -EFAULT;
|
||||
|
||||
return do_epoll_ctl(epfd, op, fd, &epds);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement the event wait interface for the eventpoll file. It is the kernel
|
||||
* part of the user space epoll_wait(2).
|
||||
|
Loading…
Reference in New Issue
Block a user