|
@@ -164,19 +164,6 @@ struct fsync_iocb {
|
|
|
bool datasync;
|
|
|
};
|
|
|
|
|
|
-/*
|
|
|
- * We use ki_cancel == KIOCB_CANCELLED to indicate that a kiocb has been either
|
|
|
- * cancelled or completed (this makes a certain amount of sense because
|
|
|
- * successful cancellation - io_cancel() - does deliver the completion to
|
|
|
- * userspace).
|
|
|
- *
|
|
|
- * And since most things don't implement kiocb cancellation and we'd really like
|
|
|
- * kiocb completion to be lockless when possible, we use ki_cancel to
|
|
|
- * synchronize cancellation and completion - we only set it to KIOCB_CANCELLED
|
|
|
- * with xchg() or cmpxchg(), see batch_complete_aio() and kiocb_cancel().
|
|
|
- */
|
|
|
-#define KIOCB_CANCELLED ((void *) (~0ULL))
|
|
|
-
|
|
|
struct aio_kiocb {
|
|
|
union {
|
|
|
struct kiocb rw;
|
|
@@ -574,27 +561,6 @@ void kiocb_set_cancel_fn(struct kiocb *iocb, kiocb_cancel_fn *cancel)
|
|
|
}
|
|
|
EXPORT_SYMBOL(kiocb_set_cancel_fn);
|
|
|
|
|
|
-static int kiocb_cancel(struct aio_kiocb *kiocb)
|
|
|
-{
|
|
|
- kiocb_cancel_fn *old, *cancel;
|
|
|
-
|
|
|
- /*
|
|
|
- * Don't want to set kiocb->ki_cancel = KIOCB_CANCELLED unless it
|
|
|
- * actually has a cancel function, hence the cmpxchg()
|
|
|
- */
|
|
|
-
|
|
|
- cancel = READ_ONCE(kiocb->ki_cancel);
|
|
|
- do {
|
|
|
- if (!cancel || cancel == KIOCB_CANCELLED)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- old = cancel;
|
|
|
- cancel = cmpxchg(&kiocb->ki_cancel, old, KIOCB_CANCELLED);
|
|
|
- } while (cancel != old);
|
|
|
-
|
|
|
- return cancel(&kiocb->rw);
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* free_ioctx() should be RCU delayed to synchronize against the RCU
|
|
|
* protected lookup_ioctx() and also needs process context to call
|
|
@@ -641,7 +607,7 @@ static void free_ioctx_users(struct percpu_ref *ref)
|
|
|
while (!list_empty(&ctx->active_reqs)) {
|
|
|
req = list_first_entry(&ctx->active_reqs,
|
|
|
struct aio_kiocb, ki_list);
|
|
|
- kiocb_cancel(req);
|
|
|
+ req->ki_cancel(&req->rw);
|
|
|
list_del_init(&req->ki_list);
|
|
|
}
|
|
|
|
|
@@ -1842,8 +1808,8 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
|
|
|
{
|
|
|
struct kioctx *ctx;
|
|
|
struct aio_kiocb *kiocb;
|
|
|
+ int ret = -EINVAL;
|
|
|
u32 key;
|
|
|
- int ret;
|
|
|
|
|
|
if (unlikely(get_user(key, &iocb->aio_key)))
|
|
|
return -EFAULT;
|
|
@@ -1855,13 +1821,11 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
|
|
|
return -EINVAL;
|
|
|
|
|
|
spin_lock_irq(&ctx->ctx_lock);
|
|
|
-
|
|
|
kiocb = lookup_kiocb(ctx, iocb);
|
|
|
- if (kiocb)
|
|
|
- ret = kiocb_cancel(kiocb);
|
|
|
- else
|
|
|
- ret = -EINVAL;
|
|
|
-
|
|
|
+ if (kiocb) {
|
|
|
+ ret = kiocb->ki_cancel(&kiocb->rw);
|
|
|
+ list_del_init(&kiocb->ki_list);
|
|
|
+ }
|
|
|
spin_unlock_irq(&ctx->ctx_lock);
|
|
|
|
|
|
if (!ret) {
|