aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
authorKent Overstreet <koverstreet@google.com>2013-05-07 19:18:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-07 21:38:28 -0400
commit906b973cf0ae8f10a6e8182845729b2ecc0da95a (patch)
tree5114e6ab2158a70aece6f93831add922425a8b50 /fs/aio.c
parent2d68449e86168744513ca4f13477f081ce167130 (diff)
aio: add kiocb_cancel()
Minor refactoring, to get rid of some duplicated code [akpm@linux-foundation.org: fix warning] 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> Acked-by: Jeff Moyer <jmoyer@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Benjamin LaHaise <bcrl@kvack.org> Reviewed-by: "Theodore Ts'o" <tytso@mit.edu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c79
1 files changed, 43 insertions, 36 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 8b43d6bf8c50..dbfcd67003ef 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -220,6 +220,29 @@ static inline void put_ioctx(struct kioctx *kioctx)
220 __put_ioctx(kioctx); 220 __put_ioctx(kioctx);
221} 221}
222 222
223static int kiocb_cancel(struct kioctx *ctx, struct kiocb *kiocb,
224 struct io_event *res)
225{
226 int (*cancel)(struct kiocb *, struct io_event *);
227 int ret = -EINVAL;
228
229 cancel = kiocb->ki_cancel;
230 kiocbSetCancelled(kiocb);
231 if (cancel) {
232 kiocb->ki_users++;
233 spin_unlock_irq(&ctx->ctx_lock);
234
235 memset(res, 0, sizeof(*res));
236 res->obj = (u64)(unsigned long)kiocb->ki_obj.user;
237 res->data = kiocb->ki_user_data;
238 ret = cancel(kiocb, res);
239
240 spin_lock_irq(&ctx->ctx_lock);
241 }
242
243 return ret;
244}
245
223/* ioctx_alloc 246/* ioctx_alloc
224 * Allocates and initializes an ioctx. Returns an ERR_PTR if it failed. 247 * Allocates and initializes an ioctx. Returns an ERR_PTR if it failed.
225 */ 248 */
@@ -290,25 +313,19 @@ out_freectx:
290 */ 313 */
291static void kill_ctx(struct kioctx *ctx) 314static void kill_ctx(struct kioctx *ctx)
292{ 315{
293 int (*cancel)(struct kiocb *, struct io_event *);
294 struct task_struct *tsk = current; 316 struct task_struct *tsk = current;
295 DECLARE_WAITQUEUE(wait, tsk); 317 DECLARE_WAITQUEUE(wait, tsk);
296 struct io_event res; 318 struct io_event res;
319 struct kiocb *req;
297 320
298 spin_lock_irq(&ctx->ctx_lock); 321 spin_lock_irq(&ctx->ctx_lock);
299 ctx->dead = 1; 322 ctx->dead = 1;
300 while (!list_empty(&ctx->active_reqs)) { 323 while (!list_empty(&ctx->active_reqs)) {
301 struct list_head *pos = ctx->active_reqs.next; 324 req = list_first_entry(&ctx->active_reqs,
302 struct kiocb *iocb = list_kiocb(pos); 325 struct kiocb, ki_list);
303 list_del_init(&iocb->ki_list); 326
304 cancel = iocb->ki_cancel; 327 list_del_init(&req->ki_list);
305 kiocbSetCancelled(iocb); 328 kiocb_cancel(ctx, req, &res);
306 if (cancel) {
307 iocb->ki_users++;
308 spin_unlock_irq(&ctx->ctx_lock);
309 cancel(iocb, &res);
310 spin_lock_irq(&ctx->ctx_lock);
311 }
312 } 329 }
313 330
314 if (!ctx->reqs_active) 331 if (!ctx->reqs_active)
@@ -1416,7 +1433,7 @@ static struct kiocb *lookup_kiocb(struct kioctx *ctx, struct iocb __user *iocb,
1416SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, 1433SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
1417 struct io_event __user *, result) 1434 struct io_event __user *, result)
1418{ 1435{
1419 int (*cancel)(struct kiocb *iocb, struct io_event *res); 1436 struct io_event res;
1420 struct kioctx *ctx; 1437 struct kioctx *ctx;
1421 struct kiocb *kiocb; 1438 struct kiocb *kiocb;
1422 u32 key; 1439 u32 key;
@@ -1431,32 +1448,22 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
1431 return -EINVAL; 1448 return -EINVAL;
1432 1449
1433 spin_lock_irq(&ctx->ctx_lock); 1450 spin_lock_irq(&ctx->ctx_lock);
1434 ret = -EAGAIN; 1451
1435 kiocb = lookup_kiocb(ctx, iocb, key); 1452 kiocb = lookup_kiocb(ctx, iocb, key);
1436 if (kiocb && kiocb->ki_cancel) { 1453 if (kiocb)
1437 cancel = kiocb->ki_cancel; 1454 ret = kiocb_cancel(ctx, kiocb, &res);
1438 kiocb->ki_users ++; 1455 else
1439 kiocbSetCancelled(kiocb); 1456 ret = -EINVAL;
1440 } else 1457
1441 cancel = NULL;
1442 spin_unlock_irq(&ctx->ctx_lock); 1458 spin_unlock_irq(&ctx->ctx_lock);
1443 1459
1444 if (NULL != cancel) { 1460 if (!ret) {
1445 struct io_event tmp; 1461 /* Cancellation succeeded -- copy the result
1446 pr_debug("calling cancel\n"); 1462 * into the user's buffer.
1447 memset(&tmp, 0, sizeof(tmp)); 1463 */
1448 tmp.obj = (u64)(unsigned long)kiocb->ki_obj.user; 1464 if (copy_to_user(result, &res, sizeof(res)))
1449 tmp.data = kiocb->ki_user_data; 1465 ret = -EFAULT;
1450 ret = cancel(kiocb, &tmp); 1466 }
1451 if (!ret) {
1452 /* Cancellation succeeded -- copy the result
1453 * into the user's buffer.
1454 */
1455 if (copy_to_user(result, &tmp, sizeof(tmp)))
1456 ret = -EFAULT;
1457 }
1458 } else
1459 ret = -EINVAL;
1460 1467
1461 put_ioctx(ctx); 1468 put_ioctx(ctx);
1462 1469