diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-15 00:36:57 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-15 00:36:57 +0300 |
commit | 7d22286ff757586f3cdbd70ded88b98250285ec5 (patch) | |
tree | cf49b699584653535e460d5250ffe8d47712ec14 /fs | |
parent | 96895199c8648db475b38aac5fe6a04ec14a49c4 (diff) | |
parent | 5f785de588735306ec4d7c875caf9d28481c8b21 (diff) | |
download | linux-7d22286ff757586f3cdbd70ded88b98250285ec5.tar.xz |
Merge git://git.kvack.org/~bcrl/aio-next
Pull aio updates from Benjamin LaHaise.
* git://git.kvack.org/~bcrl/aio-next:
aio: Skip timer for io_getevents if timeout=0
aio: Make it possible to remap aio ring
Diffstat (limited to 'fs')
-rw-r--r-- | fs/aio.c | 33 |
1 files changed, 31 insertions, 2 deletions
@@ -286,12 +286,37 @@ static void aio_free_ring(struct kioctx *ctx) static int aio_ring_mmap(struct file *file, struct vm_area_struct *vma) { + vma->vm_flags |= VM_DONTEXPAND; vma->vm_ops = &generic_file_vm_ops; return 0; } +static void aio_ring_remap(struct file *file, struct vm_area_struct *vma) +{ + struct mm_struct *mm = vma->vm_mm; + struct kioctx_table *table; + int i; + + spin_lock(&mm->ioctx_lock); + rcu_read_lock(); + table = rcu_dereference(mm->ioctx_table); + for (i = 0; i < table->nr; i++) { + struct kioctx *ctx; + + ctx = table->table[i]; + if (ctx && ctx->aio_ring_file == file) { + ctx->user_id = ctx->mmap_base = vma->vm_start; + break; + } + } + + rcu_read_unlock(); + spin_unlock(&mm->ioctx_lock); +} + static const struct file_operations aio_ring_fops = { .mmap = aio_ring_mmap, + .mremap = aio_ring_remap, }; #if IS_ENABLED(CONFIG_MIGRATION) @@ -1228,8 +1253,12 @@ static long read_events(struct kioctx *ctx, long min_nr, long nr, * the ringbuffer empty. So in practice we should be ok, but it's * something to be aware of when touching this code. */ - wait_event_interruptible_hrtimeout(ctx->wait, - aio_read_events(ctx, min_nr, nr, event, &ret), until); + if (until.tv64 == 0) + aio_read_events(ctx, min_nr, nr, event, &ret); + else + wait_event_interruptible_hrtimeout(ctx->wait, + aio_read_events(ctx, min_nr, nr, event, &ret), + until); if (!ret && signal_pending(current)) ret = -EINTR; |