--- x/fs/aio.c +++ y/fs/aio.c @@ -2194,6 +2194,8 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t list_for_each_entry(kiocb, &ctx->active_reqs, ki_list) { if (kiocb->ki_res.obj == obj) { ret = kiocb->ki_cancel(&kiocb->rw); + if (ret == 0) + refcount_inc(&kiocb->ki_refcnt); list_del_init(&kiocb->ki_list); break; } @@ -2204,8 +2206,11 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t * The result argument is no longer used - the io_event is always * delivered via the ring buffer. */ - if (ret == 0 && kiocb->rw.ki_flags & IOCB_AIO_RW) - aio_complete_rw(&kiocb->rw, -EINTR); + if (ret == 0) + if (kiocb->rw.ki_flags & IOCB_AIO_RW) + aio_complete_rw(&kiocb->rw, -EINTR); + else + iocb_put(kiocb); percpu_ref_put(&ctx->users);