diff options
Diffstat (limited to 'fs/aio.c')
-rw-r--r-- | fs/aio.c | 43 |
1 files changed, 20 insertions, 23 deletions
@@ -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 | */ |
1305 | SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id, | 1302 | SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id, |
1306 | long, min_nr, | 1303 | long, min_nr, |