diff options
author | Jens Axboe <axboe@kernel.dk> | 2019-09-18 11:18:23 -0600 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-09-18 11:19:26 -0600 |
commit | 6cc47d1d2a9b631f62405f56df651975c7587a97 (patch) | |
tree | 0c4953ff478f9a93ea337e637b5ede612830dd8d /fs | |
parent | 5f5ad9ced33621d353be6429c3900f8a526fcae8 (diff) |
io_uring: ensure poll commands clear ->sqe
If we end up getting woken in poll (due to a signal), then we may need
to punt the poll request to an async worker. When we do that, we look up
the list to queue at, deferefencing req->submit.sqe, however that is
only set for requests we initially decided to queue async.
This fixes a crash with poll command usage and wakeups that need to punt
to async context.
Fixes: 54a91f3bb9b9 ("io_uring: limit parallelism of buffered writes")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/io_uring.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index 1621243da1ea..f9139f5bd158 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -446,16 +446,15 @@ static void __io_commit_cqring(struct io_ring_ctx *ctx) static inline void io_queue_async_work(struct io_ring_ctx *ctx, struct io_kiocb *req) { - int rw; + int rw = 0; - switch (req->submit.sqe->opcode) { - case IORING_OP_WRITEV: - case IORING_OP_WRITE_FIXED: - rw = !(req->rw.ki_flags & IOCB_DIRECT); - break; - default: - rw = 0; - break; + if (req->submit.sqe) { + switch (req->submit.sqe->opcode) { + case IORING_OP_WRITEV: + case IORING_OP_WRITE_FIXED: + rw = !(req->rw.ki_flags & IOCB_DIRECT); + break; + } } queue_work(ctx->sqo_wq[rw], &req->work); @@ -1714,6 +1713,7 @@ static int io_poll_add(struct io_kiocb *req, const struct io_uring_sqe *sqe) if (!poll->file) return -EBADF; + req->submit.sqe = NULL; INIT_WORK(&req->work, io_poll_complete_work); events = READ_ONCE(sqe->poll_events); poll->events = demangle_poll(events) | EPOLLERR | EPOLLHUP; |