OSDN Git Service

io_uring: io_fail_links() should only consider first linked timeout
authorJens Axboe <axboe@kernel.dk>
Tue, 19 Nov 2019 22:31:28 +0000 (15:31 -0700)
committerJens Axboe <axboe@kernel.dk>
Tue, 26 Nov 2019 02:56:06 +0000 (19:56 -0700)
We currently clear the linked timeout field if we cancel such a timeout,
but we should only attempt to cancel if it's the first one we see.
Others should simply be freed like other requests, as they haven't
been started yet.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c

index f88e12b..09fc295 100644 (file)
@@ -942,12 +942,12 @@ static void io_fail_links(struct io_kiocb *req)
                if ((req->flags & REQ_F_LINK_TIMEOUT) &&
                    link->submit.sqe->opcode == IORING_OP_LINK_TIMEOUT) {
                        io_link_cancel_timeout(link);
-                       req->flags &= ~REQ_F_LINK_TIMEOUT;
                } else {
                        io_cqring_fill_event(link, -ECANCELED);
                        __io_double_put_req(link);
                }
                kfree(sqe_to_free);
+               req->flags &= ~REQ_F_LINK_TIMEOUT;
        }
 
        io_commit_cqring(ctx);
@@ -2837,9 +2837,10 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer)
         */
        if (!list_empty(&req->list)) {
                prev = list_entry(req->list.prev, struct io_kiocb, link_list);
-               if (refcount_inc_not_zero(&prev->refs))
+               if (refcount_inc_not_zero(&prev->refs)) {
                        list_del_init(&req->list);
-               else
+                       prev->flags &= ~REQ_F_LINK_TIMEOUT;
+               } else
                        prev = NULL;
        }