Merge branch 'for-linus' into for-next
This commit is contained in:
commit
dfea934575
4 changed files with 35 additions and 16 deletions
22
fs/aio.c
22
fs/aio.c
|
@ -310,11 +310,11 @@ static int aio_ring_mmap(struct file *file, struct vm_area_struct *vma)
|
||||||
return 0;
|
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 mm_struct *mm = vma->vm_mm;
|
||||||
struct kioctx_table *table;
|
struct kioctx_table *table;
|
||||||
int i;
|
int i, res = -EINVAL;
|
||||||
|
|
||||||
spin_lock(&mm->ioctx_lock);
|
spin_lock(&mm->ioctx_lock);
|
||||||
rcu_read_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];
|
ctx = table->table[i];
|
||||||
if (ctx && ctx->aio_ring_file == file) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
spin_unlock(&mm->ioctx_lock);
|
spin_unlock(&mm->ioctx_lock);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations aio_ring_fops = {
|
static const struct file_operations aio_ring_fops = {
|
||||||
|
@ -759,6 +763,9 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
|
||||||
err_cleanup:
|
err_cleanup:
|
||||||
aio_nr_sub(ctx->max_reqs);
|
aio_nr_sub(ctx->max_reqs);
|
||||||
err_ctx:
|
err_ctx:
|
||||||
|
atomic_set(&ctx->dead, 1);
|
||||||
|
if (ctx->mmap_size)
|
||||||
|
vm_munmap(ctx->mmap_base, ctx->mmap_size);
|
||||||
aio_free_ring(ctx);
|
aio_free_ring(ctx);
|
||||||
err:
|
err:
|
||||||
mutex_unlock(&ctx->ring_lock);
|
mutex_unlock(&ctx->ring_lock);
|
||||||
|
@ -780,11 +787,12 @@ static int kill_ioctx(struct mm_struct *mm, struct kioctx *ctx,
|
||||||
{
|
{
|
||||||
struct kioctx_table *table;
|
struct kioctx_table *table;
|
||||||
|
|
||||||
if (atomic_xchg(&ctx->dead, 1))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
|
|
||||||
spin_lock(&mm->ioctx_lock);
|
spin_lock(&mm->ioctx_lock);
|
||||||
|
if (atomic_xchg(&ctx->dead, 1)) {
|
||||||
|
spin_unlock(&mm->ioctx_lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
table = rcu_dereference_raw(mm->ioctx_table);
|
table = rcu_dereference_raw(mm->ioctx_table);
|
||||||
WARN_ON(ctx != table->table[ctx->id]);
|
WARN_ON(ctx != table->table[ctx->id]);
|
||||||
table->table[ctx->id] = NULL;
|
table->table[ctx->id] = NULL;
|
||||||
|
|
|
@ -2391,7 +2391,6 @@ relock:
|
||||||
/*
|
/*
|
||||||
* for completing the rest of the request.
|
* for completing the rest of the request.
|
||||||
*/
|
*/
|
||||||
*ppos += written;
|
|
||||||
count -= written;
|
count -= written;
|
||||||
written_buffered = generic_perform_write(file, from, *ppos);
|
written_buffered = generic_perform_write(file, from, *ppos);
|
||||||
/*
|
/*
|
||||||
|
@ -2406,7 +2405,6 @@ relock:
|
||||||
goto out_dio;
|
goto out_dio;
|
||||||
}
|
}
|
||||||
|
|
||||||
iocb->ki_pos = *ppos + written_buffered;
|
|
||||||
/* We need to ensure that the page cache pages are written to
|
/* We need to ensure that the page cache pages are written to
|
||||||
* disk and invalidated to preserve the expected O_DIRECT
|
* disk and invalidated to preserve the expected O_DIRECT
|
||||||
* semantics.
|
* semantics.
|
||||||
|
@ -2415,6 +2413,7 @@ relock:
|
||||||
ret = filemap_write_and_wait_range(file->f_mapping, *ppos,
|
ret = filemap_write_and_wait_range(file->f_mapping, *ppos,
|
||||||
endbyte);
|
endbyte);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
iocb->ki_pos = *ppos + written_buffered;
|
||||||
written += written_buffered;
|
written += written_buffered;
|
||||||
invalidate_mapping_pages(mapping,
|
invalidate_mapping_pages(mapping,
|
||||||
*ppos >> PAGE_CACHE_SHIFT,
|
*ppos >> PAGE_CACHE_SHIFT,
|
||||||
|
@ -2437,10 +2436,14 @@ out_dio:
|
||||||
/* buffered aio wouldn't have proper lock coverage today */
|
/* buffered aio wouldn't have proper lock coverage today */
|
||||||
BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT));
|
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) ||
|
if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) ||
|
||||||
((file->f_flags & O_DIRECT) && !direct_io)) {
|
((file->f_flags & O_DIRECT) && !direct_io)) {
|
||||||
ret = filemap_fdatawrite_range(file->f_mapping, *ppos,
|
ret = filemap_fdatawrite_range(file->f_mapping,
|
||||||
*ppos + count - 1);
|
iocb->ki_pos - written,
|
||||||
|
iocb->ki_pos - 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
written = ret;
|
written = ret;
|
||||||
|
|
||||||
|
@ -2451,10 +2454,12 @@ out_dio:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = filemap_fdatawait_range(file->f_mapping, *ppos,
|
ret = filemap_fdatawait_range(file->f_mapping,
|
||||||
*ppos + count - 1);
|
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
|
* 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
|
* function pointer which is called when o_direct io completes so that
|
||||||
|
|
|
@ -1569,7 +1569,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 (*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 *);
|
||||||
|
|
10
mm/mremap.c
10
mm/mremap.c
|
@ -286,8 +286,14 @@ 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)
|
} else if (vma->vm_file && vma->vm_file->f_op->mremap) {
|
||||||
vma->vm_file->f_op->mremap(vma->vm_file, new_vma);
|
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 */
|
/* Conceal VM_ACCOUNT so old reservation is not undone */
|
||||||
if (vm_flags & VM_ACCOUNT) {
|
if (vm_flags & VM_ACCOUNT) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue