diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-12 05:29:51 +0300 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-12 05:29:51 +0300 |
commit | dfea934575164497a9e36074ebce606a1a278ed9 (patch) | |
tree | b39ec564ae5a84956af80ae43de24c4f91720519 /fs/aio.c | |
parent | 165f1a6e300d5a1ffb57cf9a9c8762de731228f2 (diff) | |
parent | 64b4e2526d1cf6e6a4db6213d6e2b6e6ab59479a (diff) | |
download | linux-dfea934575164497a9e36074ebce606a1a278ed9.tar.xz |
Merge branch 'for-linus' into for-next
Diffstat (limited to 'fs/aio.c')
-rw-r--r-- | fs/aio.c | 20 |
1 files changed, 14 insertions, 6 deletions
@@ -310,11 +310,11 @@ static int aio_ring_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -static void aio_ring_remap(struct file *file, struct vm_area_struct *vma) +static int aio_ring_remap(struct file *file, struct vm_area_struct *vma) { struct mm_struct *mm = vma->vm_mm; struct kioctx_table *table; - int i; + int i, res = -EINVAL; spin_lock(&mm->ioctx_lock); rcu_read_lock(); @@ -324,13 +324,17 @@ static void aio_ring_remap(struct file *file, struct vm_area_struct *vma) ctx = table->table[i]; if (ctx && ctx->aio_ring_file == file) { - ctx->user_id = ctx->mmap_base = vma->vm_start; + if (!atomic_read(&ctx->dead)) { + ctx->user_id = ctx->mmap_base = vma->vm_start; + res = 0; + } break; } } rcu_read_unlock(); spin_unlock(&mm->ioctx_lock); + return res; } static const struct file_operations aio_ring_fops = { @@ -759,6 +763,9 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) err_cleanup: aio_nr_sub(ctx->max_reqs); err_ctx: + atomic_set(&ctx->dead, 1); + if (ctx->mmap_size) + vm_munmap(ctx->mmap_base, ctx->mmap_size); aio_free_ring(ctx); err: mutex_unlock(&ctx->ring_lock); @@ -780,11 +787,12 @@ static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx, { struct kioctx_table *table; - if (atomic_xchg(&ctx->dead, 1)) + spin_lock(&mm->ioctx_lock); + if (atomic_xchg(&ctx->dead, 1)) { + spin_unlock(&mm->ioctx_lock); return -EINVAL; + } - - spin_lock(&mm->ioctx_lock); table = rcu_dereference_raw(mm->ioctx_table); WARN_ON(ctx != table->table[ctx->id]); table->table[ctx->id] = NULL; |