aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c43
1 files changed, 20 insertions, 23 deletions
diff --git a/fs/aio.c b/fs/aio.c
index c5b1a8c10411..2bbcacf74d0c 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -141,9 +141,6 @@ static void aio_free_ring(struct kioctx *ctx)
141 for (i = 0; i < ctx->nr_pages; i++) 141 for (i = 0; i < ctx->nr_pages; i++)
142 put_page(ctx->ring_pages[i]); 142 put_page(ctx->ring_pages[i]);
143 143
144 if (ctx->mmap_size)
145 vm_munmap(ctx->mmap_base, ctx->mmap_size);
146
147 if (ctx->ring_pages && ctx->ring_pages != ctx->internal_pages) 144 if (ctx->ring_pages && ctx->ring_pages != ctx->internal_pages)
148 kfree(ctx->ring_pages); 145 kfree(ctx->ring_pages);
149} 146}
@@ -307,7 +304,9 @@ static void free_ioctx(struct kioctx *ctx)
307 kunmap_atomic(ring); 304 kunmap_atomic(ring);
308 305
309 while (atomic_read(&ctx->reqs_active) > 0) { 306 while (atomic_read(&ctx->reqs_active) > 0) {
310 wait_event(ctx->wait, head != ctx->tail); 307 wait_event(ctx->wait,
308 head != ctx->tail ||
309 atomic_read(&ctx->reqs_active) <= 0);
311 310
312 avail = (head <= ctx->tail ? ctx->tail : ctx->nr_events) - head; 311 avail = (head <= ctx->tail ? ctx->tail : ctx->nr_events) - head;
313 312
@@ -320,11 +319,6 @@ static void free_ioctx(struct kioctx *ctx)
320 319
321 aio_free_ring(ctx); 320 aio_free_ring(ctx);
322 321
323 spin_lock(&aio_nr_lock);
324 BUG_ON(aio_nr - ctx->max_reqs > aio_nr);
325 aio_nr -= ctx->max_reqs;
326 spin_unlock(&aio_nr_lock);
327
328 pr_debug("freeing %p\n", ctx); 322 pr_debug("freeing %p\n", ctx);
329 323
330 /* 324 /*
@@ -433,17 +427,24 @@ static void kill_ioctx(struct kioctx *ctx)
433{ 427{
434 if (!atomic_xchg(&ctx->dead, 1)) { 428 if (!atomic_xchg(&ctx->dead, 1)) {
435 hlist_del_rcu(&ctx->list); 429 hlist_del_rcu(&ctx->list);
436 /* Between hlist_del_rcu() and dropping the initial ref */
437 synchronize_rcu();
438 430
439 /* 431 /*
440 * We can't punt to workqueue here because put_ioctx() -> 432 * It'd be more correct to do this in free_ioctx(), after all
441 * free_ioctx() will unmap the ringbuffer, and that has to be 433 * the outstanding kiocbs have finished - but by then io_destroy
442 * done in the original process's context. kill_ioctx_rcu/work() 434 * has already returned, so io_setup() could potentially return
443 * exist for exit_aio(), as in that path free_ioctx() won't do 435 * -EAGAIN with no ioctxs actually in use (as far as userspace
444 * the unmap. 436 * could tell).
445 */ 437 */
446 kill_ioctx_work(&ctx->rcu_work); 438 spin_lock(&aio_nr_lock);
439 BUG_ON(aio_nr - ctx->max_reqs > aio_nr);
440 aio_nr -= ctx->max_reqs;
441 spin_unlock(&aio_nr_lock);
442
443 if (ctx->mmap_size)
444 vm_munmap(ctx->mmap_base, ctx->mmap_size);
445
446 /* Between hlist_del_rcu() and dropping the initial ref */
447 call_rcu(&ctx->rcu_head, kill_ioctx_rcu);
447 } 448 }
448} 449}
449 450
@@ -493,10 +494,7 @@ void exit_aio(struct mm_struct *mm)
493 */ 494 */
494 ctx->mmap_size = 0; 495 ctx->mmap_size = 0;
495 496
496 if (!atomic_xchg(&ctx->dead, 1)) { 497 kill_ioctx(ctx);
497 hlist_del_rcu(&ctx->list);
498 call_rcu(&ctx->rcu_head, kill_ioctx_rcu);
499 }
500 } 498 }
501} 499}
502 500
@@ -1299,8 +1297,7 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
1299 * < min_nr if the timeout specified by timeout has elapsed 1297 * < min_nr if the timeout specified by timeout has elapsed
1300 * before sufficient events are available, where timeout == NULL 1298 * before sufficient events are available, where timeout == NULL
1301 * specifies an infinite timeout. Note that the timeout pointed to by 1299 * specifies an infinite timeout. Note that the timeout pointed to by
1302 * timeout is relative and will be updated if not NULL and the 1300 * timeout is relative. Will fail with -ENOSYS if not implemented.
1303 * operation blocks. Will fail with -ENOSYS if not implemented.
1304 */ 1301 */
1305SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id, 1302SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
1306 long, min_nr, 1303 long, min_nr,