Explorar o código

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
Linus Torvalds %!s(int64=10) %!d(string=hai) anos
pai
achega
7d22286ff7
Modificáronse 3 ficheiros con 34 adicións e 3 borrados
  1. 31 2
      fs/aio.c
  2. 1 0
      include/linux/fs.h
  3. 2 1
      mm/mremap.c

+ 31 - 2
fs/aio.c

@@ -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)
 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;
 	vma->vm_ops = &generic_file_vm_ops;
 	return 0;
 	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 = {
 static const struct file_operations aio_ring_fops = {
 	.mmap = aio_ring_mmap,
 	.mmap = aio_ring_mmap,
+	.mremap = aio_ring_remap,
 };
 };
 
 
 #if IS_ENABLED(CONFIG_MIGRATION)
 #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
 	 * the ringbuffer empty. So in practice we should be ok, but it's
 	 * something to be aware of when touching this code.
 	 * 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))
 	if (!ret && signal_pending(current))
 		ret = -EINTR;
 		ret = -EINTR;

+ 1 - 0
include/linux/fs.h

@@ -1518,6 +1518,7 @@ struct file_operations {
 	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
 	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
 	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
 	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
 	int (*mmap) (struct file *, struct vm_area_struct *);
 	int (*mmap) (struct file *, struct vm_area_struct *);
+	void (*mremap)(struct file *, struct vm_area_struct *);
 	int (*open) (struct inode *, struct file *);
 	int (*open) (struct inode *, struct file *);
 	int (*flush) (struct file *, fl_owner_t id);
 	int (*flush) (struct file *, fl_owner_t id);
 	int (*release) (struct inode *, struct file *);
 	int (*release) (struct inode *, struct file *);

+ 2 - 1
mm/mremap.c

@@ -288,7 +288,8 @@ static unsigned long move_vma(struct vm_area_struct *vma,
 		old_len = new_len;
 		old_len = new_len;
 		old_addr = new_addr;
 		old_addr = new_addr;
 		new_addr = -ENOMEM;
 		new_addr = -ENOMEM;
-	}
+	} else if (vma->vm_file && vma->vm_file->f_op->mremap)
+		vma->vm_file->f_op->mremap(vma->vm_file, new_vma);
 
 
 	/* Conceal VM_ACCOUNT so old reservation is not undone */
 	/* Conceal VM_ACCOUNT so old reservation is not undone */
 	if (vm_flags & VM_ACCOUNT) {
 	if (vm_flags & VM_ACCOUNT) {