diff options
Diffstat (limited to 'fs/io_uring.c')
-rw-r--r-- | fs/io_uring.c | 37 |
1 files changed, 16 insertions, 21 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index ab30c0a0c09b..bfba7558ea86 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -5172,19 +5172,29 @@ static int io_arm_poll_handler(struct io_kiocb *req) struct io_ring_ctx *ctx = req->ctx; struct async_poll *apoll; struct io_poll_table ipt; - __poll_t mask, ret; + __poll_t ret, mask = EPOLLONESHOT | POLLERR | POLLPRI; int rw; if (!req->file || !file_can_poll(req->file)) return IO_APOLL_ABORTED; if (req->flags & REQ_F_POLLED) return IO_APOLL_ABORTED; - if (def->pollin) + if (!def->pollin && !def->pollout) + return IO_APOLL_ABORTED; + + if (def->pollin) { rw = READ; - else if (def->pollout) + mask |= POLLIN | POLLRDNORM; + + /* If reading from MSG_ERRQUEUE using recvmsg, ignore POLLIN */ + if ((req->opcode == IORING_OP_RECVMSG) && + (req->sr_msg.msg_flags & MSG_ERRQUEUE)) + mask &= ~POLLIN; + } else { rw = WRITE; - else - return IO_APOLL_ABORTED; + mask |= POLLOUT | POLLWRNORM; + } + /* if we can't nonblock try, then no point in arming a poll handler */ if (!io_file_supports_async(req, rw)) return IO_APOLL_ABORTED; @@ -5193,23 +5203,8 @@ static int io_arm_poll_handler(struct io_kiocb *req) if (unlikely(!apoll)) return IO_APOLL_ABORTED; apoll->double_poll = NULL; - - req->flags |= REQ_F_POLLED; req->apoll = apoll; - - mask = EPOLLONESHOT; - if (def->pollin) - mask |= POLLIN | POLLRDNORM; - if (def->pollout) - mask |= POLLOUT | POLLWRNORM; - - /* If reading from MSG_ERRQUEUE using recvmsg, ignore POLLIN */ - if ((req->opcode == IORING_OP_RECVMSG) && - (req->sr_msg.msg_flags & MSG_ERRQUEUE)) - mask &= ~POLLIN; - - mask |= POLLERR | POLLPRI; - + req->flags |= REQ_F_POLLED; ipt.pt._qproc = io_async_queue_proc; ret = __io_arm_poll_handler(req, &apoll->poll, &ipt, mask, |