[AIO] kiocb locking to serialise retry and cancel Implement a per-kiocb lock to serialise retry operations and cancel. This is done using wait_on_bit_lock() on the KIF_LOCKED bit of kiocb->ki_flags. Also, make the cancellation path lock the kiocb and subsequently release all references to it if the cancel was successful. Signed-off-by: Benjamin LaHaise diff -purN --exclude=description 35_cancel_aio_put_req/fs/aio.c 40_lock_kiocb/fs/aio.c --- 35_cancel_aio_put_req/fs/aio.c 2005-08-08 17:15:34.000000000 -0400 +++ 40_lock_kiocb/fs/aio.c 2005-08-08 17:15:37.000000000 -0400 @@ -546,6 +546,24 @@ struct kioctx *lookup_ioctx(unsigned lon return ioctx; } +static int lock_kiocb_action(void *param) +{ + schedule(); + return 0; +} + +static inline void lock_kiocb(struct kiocb *iocb) +{ + wait_on_bit_lock(&iocb->ki_flags, KIF_LOCKED, lock_kiocb_action, + TASK_UNINTERRUPTIBLE); +} + +static inline void unlock_kiocb(struct kiocb *iocb) +{ + kiocbClearLocked(iocb); + wake_up_bit(&iocb->ki_flags, KIF_LOCKED); +} + /* * use_mm * Makes the calling kernel thread take on the specified @@ -782,7 +800,9 @@ static int __aio_run_iocbs(struct kioctx * Hold an extra reference while retrying i/o. */ iocb->ki_users++; /* grab extra reference */ + lock_kiocb(iocb); aio_run_iocb(iocb); + unlock_kiocb(iocb); if (__aio_put_req(ctx, iocb)) /* drop extra ref */ put_ioctx(ctx); } @@ -1532,6 +1552,7 @@ int fastcall io_submit_one(struct kioctx ; } spin_unlock_irq(&ctx->ctx_lock); + unlock_kiocb(req); aio_put_req(req); /* drop extra ref to req */ return 0; @@ -1657,6 +1678,7 @@ asmlinkage long sys_io_cancel(aio_contex if (NULL != cancel) { struct io_event tmp; pr_debug("calling cancel\n"); + lock_kiocb(kiocb); memset(&tmp, 0, sizeof(tmp)); tmp.obj = (u64)(unsigned long)kiocb->ki_obj.user; tmp.data = kiocb->ki_user_data; @@ -1668,6 +1690,7 @@ asmlinkage long sys_io_cancel(aio_contex if (copy_to_user(result, &tmp, sizeof(tmp))) ret = -EFAULT; } + unlock_kiocb(kiocb); /* If the cancellation was successful, we must discard the * reference held for completion of the iocb. */