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:
Родитель
f86cd20c94
Коммит
58e41a44c4
|
@ -2074,27 +2074,15 @@ SYSCALL_DEFINE1(epoll_create, int, size)
|
||||||
return do_epoll_create(0);
|
return do_epoll_create(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *epds)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
int full_check = 0;
|
int full_check = 0;
|
||||||
struct fd f, tf;
|
struct fd f, tf;
|
||||||
struct eventpoll *ep;
|
struct eventpoll *ep;
|
||||||
struct epitem *epi;
|
struct epitem *epi;
|
||||||
struct epoll_event epds;
|
|
||||||
struct eventpoll *tep = NULL;
|
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;
|
error = -EBADF;
|
||||||
f = fdget(epfd);
|
f = fdget(epfd);
|
||||||
if (!f.file)
|
if (!f.file)
|
||||||
|
@ -2112,7 +2100,7 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||||
|
|
||||||
/* Check if EPOLLWAKEUP is allowed */
|
/* Check if EPOLLWAKEUP is allowed */
|
||||||
if (ep_op_has_event(op))
|
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
|
* 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.
|
* so EPOLLEXCLUSIVE is not allowed for a EPOLL_CTL_MOD operation.
|
||||||
* Also, we do not currently supported nested exclusive wakeups.
|
* 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)
|
if (op == EPOLL_CTL_MOD)
|
||||||
goto error_tgt_fput;
|
goto error_tgt_fput;
|
||||||
if (op == EPOLL_CTL_ADD && (is_file_epoll(tf.file) ||
|
if (op == EPOLL_CTL_ADD && (is_file_epoll(tf.file) ||
|
||||||
(epds.events & ~EPOLLEXCLUSIVE_OK_BITS)))
|
(epds->events & ~EPOLLEXCLUSIVE_OK_BITS)))
|
||||||
goto error_tgt_fput;
|
goto error_tgt_fput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2192,8 +2180,8 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case EPOLL_CTL_ADD:
|
case EPOLL_CTL_ADD:
|
||||||
if (!epi) {
|
if (!epi) {
|
||||||
epds.events |= EPOLLERR | EPOLLHUP;
|
epds->events |= EPOLLERR | EPOLLHUP;
|
||||||
error = ep_insert(ep, &epds, tf.file, fd, full_check);
|
error = ep_insert(ep, epds, tf.file, fd, full_check);
|
||||||
} else
|
} else
|
||||||
error = -EEXIST;
|
error = -EEXIST;
|
||||||
if (full_check)
|
if (full_check)
|
||||||
|
@ -2208,8 +2196,8 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||||
case EPOLL_CTL_MOD:
|
case EPOLL_CTL_MOD:
|
||||||
if (epi) {
|
if (epi) {
|
||||||
if (!(epi->event.events & EPOLLEXCLUSIVE)) {
|
if (!(epi->event.events & EPOLLEXCLUSIVE)) {
|
||||||
epds.events |= EPOLLERR | EPOLLHUP;
|
epds->events |= EPOLLERR | EPOLLHUP;
|
||||||
error = ep_modify(ep, epi, &epds);
|
error = ep_modify(ep, epi, epds);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
error = -ENOENT;
|
error = -ENOENT;
|
||||||
|
@ -2231,6 +2219,23 @@ error_return:
|
||||||
return error;
|
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
|
* Implement the event wait interface for the eventpoll file. It is the kernel
|
||||||
* part of the user space epoll_wait(2).
|
* part of the user space epoll_wait(2).
|
||||||
|
|
Загрузка…
Ссылка в новой задаче