Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

aio: io_cancel() no longer returns the io_event

Originally, io_event() was documented to return the io_event if
cancellation succeeded - the io_event wouldn't be delivered via the ring
buffer like it normally would.

But this isn't what the implementation was actually doing; the only
driver implementing cancellation, the usb gadget code, never returned an
io_event in its cancel function. And aio_complete() was recently changed
to no longer suppress event delivery if the kiocb had been cancelled.

This gets rid of the unused io_event argument to kiocb_cancel() and
kiocb->ki_cancel(), and changes io_cancel() to return -EINPROGRESS if
kiocb->ki_cancel() returned success.

Also tweak the refcounting in kiocb_cancel() to make more sense.

Signed-off-by: Kent Overstreet <koverstreet@google.com>
Cc: Zach Brown <zab@redhat.com>
Cc: Felipe Balbi <balbi@ti.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Asai Thambi S P <asamymuthupa@micron.com>
Cc: Selvan Mani <smani@micron.com>
Cc: Sam Bradshaw <sbradshaw@micron.com>
Cc: Jeff Moyer <jmoyer@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Benjamin LaHaise <bcrl@kvack.org>
Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>

authored by

Kent Overstreet and committed by
Benjamin LaHaise
bec68faa 723be6e3

+12 -33
+1 -2
drivers/usb/gadget/inode.c
··· 524 524 unsigned actual; 525 525 }; 526 526 527 - static int ep_aio_cancel(struct kiocb *iocb, struct io_event *e) 527 + static int ep_aio_cancel(struct kiocb *iocb) 528 528 { 529 529 struct kiocb_priv *priv = iocb->private; 530 530 struct ep_data *epdata; ··· 540 540 // spin_unlock(&epdata->dev->lock); 541 541 local_irq_enable(); 542 542 543 - aio_put_req(iocb); 544 543 return value; 545 544 } 546 545
+10 -30
fs/aio.c
··· 358 358 } 359 359 EXPORT_SYMBOL(kiocb_set_cancel_fn); 360 360 361 - static int kiocb_cancel(struct kioctx *ctx, struct kiocb *kiocb, 362 - struct io_event *res) 361 + static int kiocb_cancel(struct kioctx *ctx, struct kiocb *kiocb) 363 362 { 364 363 kiocb_cancel_fn *old, *cancel; 365 364 int ret = -EINVAL; ··· 380 381 atomic_inc(&kiocb->ki_users); 381 382 spin_unlock_irq(&ctx->ctx_lock); 382 383 383 - memset(res, 0, sizeof(*res)); 384 - res->obj = (u64)(unsigned long)kiocb->ki_obj.user; 385 - res->data = kiocb->ki_user_data; 386 - ret = cancel(kiocb, res); 384 + ret = cancel(kiocb); 387 385 388 386 spin_lock_irq(&ctx->ctx_lock); 387 + aio_put_req(kiocb); 389 388 390 389 return ret; 391 390 } ··· 405 408 { 406 409 struct kioctx *ctx = container_of(work, struct kioctx, free_work); 407 410 struct aio_ring *ring; 408 - struct io_event res; 409 411 struct kiocb *req; 410 412 unsigned cpu, head, avail; 411 413 ··· 415 419 struct kiocb, ki_list); 416 420 417 421 list_del_init(&req->ki_list); 418 - kiocb_cancel(ctx, req, &res); 422 + kiocb_cancel(ctx, req); 419 423 } 420 424 421 425 spin_unlock_irq(&ctx->ctx_lock); ··· 792 796 } 793 797 794 798 /* 795 - * cancelled requests don't get events, userland was given one 796 - * when the event got cancelled. 797 - */ 798 - if (unlikely(xchg(&iocb->ki_cancel, 799 - KIOCB_CANCELLED) == KIOCB_CANCELLED)) { 800 - /* 801 - * Can't use the percpu reqs_available here - could race with 802 - * free_ioctx() 803 - */ 804 - atomic_inc(&ctx->reqs_available); 805 - /* Still need the wake_up in case free_ioctx is waiting */ 806 - goto put_rq; 807 - } 808 - 809 - /* 810 799 * Add a completion event to the ring buffer. Must be done holding 811 800 * ctx->completion_lock to prevent other code from messing with the tail 812 801 * pointer since we might be called from irq context. ··· 843 862 if (iocb->ki_eventfd != NULL) 844 863 eventfd_signal(iocb->ki_eventfd, 1); 845 864 846 - put_rq: 847 865 /* everything turned out well, dispose of the aiocb. */ 848 866 aio_put_req(iocb); 849 867 ··· 1419 1439 SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, 1420 1440 struct io_event __user *, result) 1421 1441 { 1422 - struct io_event res; 1423 1442 struct kioctx *ctx; 1424 1443 struct kiocb *kiocb; 1425 1444 u32 key; ··· 1436 1457 1437 1458 kiocb = lookup_kiocb(ctx, iocb, key); 1438 1459 if (kiocb) 1439 - ret = kiocb_cancel(ctx, kiocb, &res); 1460 + ret = kiocb_cancel(ctx, kiocb); 1440 1461 else 1441 1462 ret = -EINVAL; 1442 1463 1443 1464 spin_unlock_irq(&ctx->ctx_lock); 1444 1465 1445 1466 if (!ret) { 1446 - /* Cancellation succeeded -- copy the result 1447 - * into the user's buffer. 1467 + /* 1468 + * The result argument is no longer used - the io_event is 1469 + * always delivered via the ring buffer. -EINPROGRESS indicates 1470 + * cancellation is progress: 1448 1471 */ 1449 - if (copy_to_user(result, &res, sizeof(res))) 1450 - ret = -EFAULT; 1472 + ret = -EINPROGRESS; 1451 1473 } 1452 1474 1453 1475 percpu_ref_put(&ctx->users);
+1 -1
include/linux/aio.h
··· 27 27 */ 28 28 #define KIOCB_CANCELLED ((void *) (~0ULL)) 29 29 30 - typedef int (kiocb_cancel_fn)(struct kiocb *, struct io_event *); 30 + typedef int (kiocb_cancel_fn)(struct kiocb *); 31 31 32 32 struct kiocb { 33 33 atomic_t ki_users;