Loading fs/aio.c +14 −6 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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) { 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 = { Loading Loading @@ -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); Loading @@ -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; Loading fs/ocfs2/file.c +11 −6 Original line number Diff line number Diff line Loading @@ -2391,7 +2391,6 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, /* * for completing the rest of the request. */ *ppos += written; count -= written; written_buffered = generic_perform_write(file, from, *ppos); /* Loading @@ -2406,7 +2405,6 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, goto out_dio; } iocb->ki_pos = *ppos + written_buffered; /* We need to ensure that the page cache pages are written to * disk and invalidated to preserve the expected O_DIRECT * semantics. Loading @@ -2415,6 +2413,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, ret = filemap_write_and_wait_range(file->f_mapping, *ppos, endbyte); if (ret == 0) { iocb->ki_pos = *ppos + written_buffered; written += written_buffered; invalidate_mapping_pages(mapping, *ppos >> PAGE_CACHE_SHIFT, Loading @@ -2437,10 +2436,14 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, /* buffered aio wouldn't have proper lock coverage today */ BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); if (unlikely(written <= 0)) goto no_sync; if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || ((file->f_flags & O_DIRECT) && !direct_io)) { ret = filemap_fdatawrite_range(file->f_mapping, *ppos, *ppos + count - 1); ret = filemap_fdatawrite_range(file->f_mapping, iocb->ki_pos - written, iocb->ki_pos - 1); if (ret < 0) written = ret; Loading @@ -2451,10 +2454,12 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, } if (!ret) ret = filemap_fdatawait_range(file->f_mapping, *ppos, *ppos + count - 1); ret = filemap_fdatawait_range(file->f_mapping, iocb->ki_pos - written, iocb->ki_pos - 1); } no_sync: /* * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io * function pointer which is called when o_direct io completes so that Loading include/linux/fs.h +1 −1 Original line number Diff line number Diff line Loading @@ -1569,7 +1569,7 @@ struct file_operations { long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); void (*mremap)(struct file *, struct vm_area_struct *); int (*mremap)(struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); Loading mm/mremap.c +8 −2 Original line number Diff line number Diff line Loading @@ -286,8 +286,14 @@ static unsigned long move_vma(struct vm_area_struct *vma, old_len = new_len; old_addr = new_addr; 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); } else if (vma->vm_file && vma->vm_file->f_op->mremap) { err = vma->vm_file->f_op->mremap(vma->vm_file, new_vma); if (err < 0) { move_page_tables(new_vma, new_addr, vma, old_addr, moved_len, true); return err; } } /* Conceal VM_ACCOUNT so old reservation is not undone */ if (vm_flags & VM_ACCOUNT) { Loading Loading
fs/aio.c +14 −6 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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) { 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 = { Loading Loading @@ -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); Loading @@ -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; Loading
fs/ocfs2/file.c +11 −6 Original line number Diff line number Diff line Loading @@ -2391,7 +2391,6 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, /* * for completing the rest of the request. */ *ppos += written; count -= written; written_buffered = generic_perform_write(file, from, *ppos); /* Loading @@ -2406,7 +2405,6 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, goto out_dio; } iocb->ki_pos = *ppos + written_buffered; /* We need to ensure that the page cache pages are written to * disk and invalidated to preserve the expected O_DIRECT * semantics. Loading @@ -2415,6 +2413,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, ret = filemap_write_and_wait_range(file->f_mapping, *ppos, endbyte); if (ret == 0) { iocb->ki_pos = *ppos + written_buffered; written += written_buffered; invalidate_mapping_pages(mapping, *ppos >> PAGE_CACHE_SHIFT, Loading @@ -2437,10 +2436,14 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, /* buffered aio wouldn't have proper lock coverage today */ BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); if (unlikely(written <= 0)) goto no_sync; if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || ((file->f_flags & O_DIRECT) && !direct_io)) { ret = filemap_fdatawrite_range(file->f_mapping, *ppos, *ppos + count - 1); ret = filemap_fdatawrite_range(file->f_mapping, iocb->ki_pos - written, iocb->ki_pos - 1); if (ret < 0) written = ret; Loading @@ -2451,10 +2454,12 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, } if (!ret) ret = filemap_fdatawait_range(file->f_mapping, *ppos, *ppos + count - 1); ret = filemap_fdatawait_range(file->f_mapping, iocb->ki_pos - written, iocb->ki_pos - 1); } no_sync: /* * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io * function pointer which is called when o_direct io completes so that Loading
include/linux/fs.h +1 −1 Original line number Diff line number Diff line Loading @@ -1569,7 +1569,7 @@ struct file_operations { long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); void (*mremap)(struct file *, struct vm_area_struct *); int (*mremap)(struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); Loading
mm/mremap.c +8 −2 Original line number Diff line number Diff line Loading @@ -286,8 +286,14 @@ static unsigned long move_vma(struct vm_area_struct *vma, old_len = new_len; old_addr = new_addr; 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); } else if (vma->vm_file && vma->vm_file->f_op->mremap) { err = vma->vm_file->f_op->mremap(vma->vm_file, new_vma); if (err < 0) { move_page_tables(new_vma, new_addr, vma, old_addr, moved_len, true); return err; } } /* Conceal VM_ACCOUNT so old reservation is not undone */ if (vm_flags & VM_ACCOUNT) { Loading