aio: only return events requested in poll_mask() for IOCB_CMD_POLL
authorChristoph Hellwig <hch@lst.de>
Mon, 11 Jun 2018 06:50:10 +0000 (08:50 +0200)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 15 Jun 2018 00:08:14 +0000 (20:08 -0400)
The ->poll_mask() operation has a mask of events that the caller
is interested in, but not all implementations might take it into
account.  Mask the return value to only the requested events,
similar to what the poll and epoll code does.

Reported-by: Avi Kivity <avi@scylladb.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/aio.c

index 134e5b635d643da8868b477a0990e5d3cdb4077e..e1d20124ec0e8698a1e8a5940537ff45f2e57d2c 100644 (file)
--- 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);