diff options
author | Pavel Begunkov <asml.silence@gmail.com> | 2020-10-13 09:43:56 +0100 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2020-10-17 09:25:42 -0600 |
commit | 368c5481ae7c6a9719c40984faea35480d9f4872 (patch) | |
tree | cfc458c06932434a70277ec75cb1db4f3d0bd778 | |
parent | 035fbafc7a54b8c7755b3c508b8f3ab6ff3c8d65 (diff) | |
download | linux-stable-368c5481ae7c6a9719c40984faea35480d9f4872.tar.gz linux-stable-368c5481ae7c6a9719c40984faea35480d9f4872.tar.bz2 linux-stable-368c5481ae7c6a9719c40984faea35480d9f4872.zip |
io_uring: don't set COMP_LOCKED if won't put
__io_kill_linked_timeout() sets REQ_F_COMP_LOCKED for a linked timeout
even if it can't cancel it, e.g. it's already running. It not only races
with io_link_timeout_fn() for ->flags field, but also leaves the flag
set and so io_link_timeout_fn() may find it and decide that it holds the
lock. Hopefully, the second problem is potential.
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | fs/io_uring.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index 717dd5d38d75..f0f4b5b5c2a0 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1769,6 +1769,7 @@ static bool io_link_cancel_timeout(struct io_kiocb *req) ret = hrtimer_try_to_cancel(&io->timer); if (ret != -1) { + req->flags |= REQ_F_COMP_LOCKED; io_cqring_fill_event(req, -ECANCELED); io_commit_cqring(ctx); req->flags &= ~REQ_F_LINK_HEAD; @@ -1791,7 +1792,6 @@ static bool __io_kill_linked_timeout(struct io_kiocb *req) return false; list_del_init(&link->link_list); - link->flags |= REQ_F_COMP_LOCKED; wake_ev = io_link_cancel_timeout(link); req->flags &= ~REQ_F_LINK_TIMEOUT; return wake_ev; |