Commit 906b973cf0ae8f10a6e8182845729b2ecc0da95a
Committed by
Linus Torvalds
1 parent
2d68449e86
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 1 changed file with 43 additions and 36 deletions Side-by-side Diff
fs/aio.c
... | ... | @@ -220,6 +220,29 @@ |
220 | 220 | __put_ioctx(kioctx); |
221 | 221 | } |
222 | 222 | |
223 | +static 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 | 246 | /* ioctx_alloc |
224 | 247 | * Allocates and initializes an ioctx. Returns an ERR_PTR if it failed. |
225 | 248 | */ |
226 | 249 | |
227 | 250 | |
... | ... | @@ -290,25 +313,19 @@ |
290 | 313 | */ |
291 | 314 | static void kill_ctx(struct kioctx *ctx) |
292 | 315 | { |
293 | - int (*cancel)(struct kiocb *, struct io_event *); | |
294 | 316 | struct task_struct *tsk = current; |
295 | 317 | DECLARE_WAITQUEUE(wait, tsk); |
296 | 318 | struct io_event res; |
319 | + struct kiocb *req; | |
297 | 320 | |
298 | 321 | spin_lock_irq(&ctx->ctx_lock); |
299 | 322 | ctx->dead = 1; |
300 | 323 | while (!list_empty(&ctx->active_reqs)) { |
301 | - struct list_head *pos = ctx->active_reqs.next; | |
302 | - struct kiocb *iocb = list_kiocb(pos); | |
303 | - list_del_init(&iocb->ki_list); | |
304 | - cancel = iocb->ki_cancel; | |
305 | - kiocbSetCancelled(iocb); | |
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 | - } | |
324 | + req = list_first_entry(&ctx->active_reqs, | |
325 | + struct kiocb, ki_list); | |
326 | + | |
327 | + list_del_init(&req->ki_list); | |
328 | + kiocb_cancel(ctx, req, &res); | |
312 | 329 | } |
313 | 330 | |
314 | 331 | if (!ctx->reqs_active) |
... | ... | @@ -1416,7 +1433,7 @@ |
1416 | 1433 | SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, |
1417 | 1434 | struct io_event __user *, result) |
1418 | 1435 | { |
1419 | - int (*cancel)(struct kiocb *iocb, struct io_event *res); | |
1436 | + struct io_event res; | |
1420 | 1437 | struct kioctx *ctx; |
1421 | 1438 | struct kiocb *kiocb; |
1422 | 1439 | u32 key; |
1423 | 1440 | |
1424 | 1441 | |
... | ... | @@ -1431,32 +1448,22 @@ |
1431 | 1448 | return -EINVAL; |
1432 | 1449 | |
1433 | 1450 | spin_lock_irq(&ctx->ctx_lock); |
1434 | - ret = -EAGAIN; | |
1451 | + | |
1435 | 1452 | kiocb = lookup_kiocb(ctx, iocb, key); |
1436 | - if (kiocb && kiocb->ki_cancel) { | |
1437 | - cancel = kiocb->ki_cancel; | |
1438 | - kiocb->ki_users ++; | |
1439 | - kiocbSetCancelled(kiocb); | |
1440 | - } else | |
1441 | - cancel = NULL; | |
1453 | + if (kiocb) | |
1454 | + ret = kiocb_cancel(ctx, kiocb, &res); | |
1455 | + else | |
1456 | + ret = -EINVAL; | |
1457 | + | |
1442 | 1458 | spin_unlock_irq(&ctx->ctx_lock); |
1443 | 1459 | |
1444 | - if (NULL != cancel) { | |
1445 | - struct io_event tmp; | |
1446 | - pr_debug("calling cancel\n"); | |
1447 | - memset(&tmp, 0, sizeof(tmp)); | |
1448 | - tmp.obj = (u64)(unsigned long)kiocb->ki_obj.user; | |
1449 | - tmp.data = kiocb->ki_user_data; | |
1450 | - ret = cancel(kiocb, &tmp); | |
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 | + if (!ret) { | |
1461 | + /* Cancellation succeeded -- copy the result | |
1462 | + * into the user's buffer. | |
1463 | + */ | |
1464 | + if (copy_to_user(result, &res, sizeof(res))) | |
1465 | + ret = -EFAULT; | |
1466 | + } | |
1460 | 1467 | |
1461 | 1468 | put_ioctx(ctx); |
1462 | 1469 |