Merge branch 'work.aio' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull aio fixes from Al Viro:
"Assorted AIO followups and fixes"
* 'work.aio' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
eventpoll: switch to ->poll_mask
aio: only return events requested in poll_mask() for IOCB_CMD_POLL
eventfd: only return events requested in poll_mask()
aio: mark __aio_sigset::sigmask const
diff --git a/fs/aio.c b/fs/aio.c
index 134e5b6..e1d2012 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1661,7 +1661,7 @@
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 @@
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 61c9514..ceb1031 100644
--- a/fs/eventfd.c
+++ b/fs/eventfd.c
@@ -156,11 +156,11 @@
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 67db22f..ea4436f 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -922,14 +922,18 @@
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 @@
.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 7584616..d002213 100644
--- a/include/uapi/linux/aio_abi.h
+++ b/include/uapi/linux/aio_abi.h
@@ -109,7 +109,7 @@
#undef IFLITTLE
struct __aio_sigset {
- sigset_t __user *sigmask;
+ const sigset_t __user *sigmask;
size_t sigsetsize;
};