Commit ccbf7261 authored by Jens Axboe's avatar Jens Axboe
Browse files

io_uring: perform poll removal even if async work removal is successful



An active work can have poll armed, hence it's not enough to just do
the async work removal and return the value if it's different from "not
found". Rather than make poll removal special, just fall through to do
the remaining type lookups and removals.

Reported-by: default avatarFlorian Fischer <florian.fl.fischer@fau.de>
Link: https://lore.kernel.org/io-uring/20220118151337.fac6cthvbnu7icoc@pasture/


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 361aee45
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -6386,16 +6386,21 @@ static int io_try_cancel_userdata(struct io_kiocb *req, u64 sqe_addr)
	WARN_ON_ONCE(!io_wq_current_is_worker() && req->task != current);

	ret = io_async_cancel_one(req->task->io_uring, sqe_addr, ctx);
	if (ret != -ENOENT)
		return ret;
	/*
	 * Fall-through even for -EALREADY, as we may have poll armed
	 * that need unarming.
	 */
	if (!ret)
		return 0;

	spin_lock(&ctx->completion_lock);
	ret = io_poll_cancel(ctx, sqe_addr, false);
	if (ret != -ENOENT)
		goto out;

	spin_lock_irq(&ctx->timeout_lock);
	ret = io_timeout_cancel(ctx, sqe_addr);
	spin_unlock_irq(&ctx->timeout_lock);
	if (ret != -ENOENT)
		goto out;
	ret = io_poll_cancel(ctx, sqe_addr, false);
out:
	spin_unlock(&ctx->completion_lock);
	return ret;