diff --git a/fs/aio.c b/fs/aio.c index 134e5b635d64..e1d20124ec0e 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -1661,7 +1661,7 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, if (mask && !(mask & req->events)) return 0; - mask = file->f_op->poll_mask(file, req->events); + mask = file->f_op->poll_mask(file, req->events) & req->events; if (!mask) return 0; @@ -1719,7 +1719,7 @@ static ssize_t aio_poll(struct aio_kiocb *aiocb, struct iocb *iocb) spin_lock_irq(&ctx->ctx_lock); spin_lock(&req->head->lock); - mask = req->file->f_op->poll_mask(req->file, req->events); + mask = req->file->f_op->poll_mask(req->file, req->events) & req->events; if (!mask) { __add_wait_queue(req->head, &req->wait); list_add_tail(&aiocb->ki_list, &ctx->active_reqs); diff --git a/fs/eventfd.c b/fs/eventfd.c index 61c9514da5e9..ceb1031f1cac 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c @@ -156,11 +156,11 @@ static __poll_t eventfd_poll_mask(struct file *file, __poll_t eventmask) count = READ_ONCE(ctx->count); if (count > 0) - events |= EPOLLIN; + events |= (EPOLLIN & eventmask); if (count == ULLONG_MAX) events |= EPOLLERR; if (ULLONG_MAX - 1 > count) - events |= EPOLLOUT; + events |= (EPOLLOUT & eventmask); return events; } diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 67db22fe99c5..ea4436f409fb 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -922,14 +922,18 @@ static __poll_t ep_read_events_proc(struct eventpoll *ep, struct list_head *head return 0; } -static __poll_t ep_eventpoll_poll(struct file *file, poll_table *wait) +static struct wait_queue_head *ep_eventpoll_get_poll_head(struct file *file, + __poll_t eventmask) +{ + struct eventpoll *ep = file->private_data; + return &ep->poll_wait; +} + +static __poll_t ep_eventpoll_poll_mask(struct file *file, __poll_t eventmask) { struct eventpoll *ep = file->private_data; int depth = 0; - /* Insert inside our poll wait queue */ - poll_wait(file, &ep->poll_wait, wait); - /* * Proceed to find out if wanted events are really available inside * the ready list. @@ -968,7 +972,8 @@ static const struct file_operations eventpoll_fops = { .show_fdinfo = ep_show_fdinfo, #endif .release = ep_eventpoll_release, - .poll = ep_eventpoll_poll, + .get_poll_head = ep_eventpoll_get_poll_head, + .poll_mask = ep_eventpoll_poll_mask, .llseek = noop_llseek, }; diff --git a/include/uapi/linux/aio_abi.h b/include/uapi/linux/aio_abi.h index 75846164290e..d00221345c19 100644 --- a/include/uapi/linux/aio_abi.h +++ b/include/uapi/linux/aio_abi.h @@ -109,7 +109,7 @@ struct iocb { #undef IFLITTLE struct __aio_sigset { - sigset_t __user *sigmask; + const sigset_t __user *sigmask; size_t sigsetsize; };