Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' into for-next

Al Viro dfea9345 165f1a6e

+35 -16
+15 -7
fs/aio.c
··· 310 310 return 0; 311 311 } 312 312 313 - static void aio_ring_remap(struct file *file, struct vm_area_struct *vma) 313 + static int aio_ring_remap(struct file *file, struct vm_area_struct *vma) 314 314 { 315 315 struct mm_struct *mm = vma->vm_mm; 316 316 struct kioctx_table *table; 317 - int i; 317 + int i, res = -EINVAL; 318 318 319 319 spin_lock(&mm->ioctx_lock); 320 320 rcu_read_lock(); ··· 324 324 325 325 ctx = table->table[i]; 326 326 if (ctx && ctx->aio_ring_file == file) { 327 - ctx->user_id = ctx->mmap_base = vma->vm_start; 327 + if (!atomic_read(&ctx->dead)) { 328 + ctx->user_id = ctx->mmap_base = vma->vm_start; 329 + res = 0; 330 + } 328 331 break; 329 332 } 330 333 } 331 334 332 335 rcu_read_unlock(); 333 336 spin_unlock(&mm->ioctx_lock); 337 + return res; 334 338 } 335 339 336 340 static const struct file_operations aio_ring_fops = { ··· 763 759 err_cleanup: 764 760 aio_nr_sub(ctx->max_reqs); 765 761 err_ctx: 762 + atomic_set(&ctx->dead, 1); 763 + if (ctx->mmap_size) 764 + vm_munmap(ctx->mmap_base, ctx->mmap_size); 766 765 aio_free_ring(ctx); 767 766 err: 768 767 mutex_unlock(&ctx->ring_lock); ··· 787 780 { 788 781 struct kioctx_table *table; 789 782 790 - if (atomic_xchg(&ctx->dead, 1)) 791 - return -EINVAL; 792 - 793 - 794 783 spin_lock(&mm->ioctx_lock); 784 + if (atomic_xchg(&ctx->dead, 1)) { 785 + spin_unlock(&mm->ioctx_lock); 786 + return -EINVAL; 787 + } 788 + 795 789 table = rcu_dereference_raw(mm->ioctx_table); 796 790 WARN_ON(ctx != table->table[ctx->id]); 797 791 table->table[ctx->id] = NULL;
+11 -6
fs/ocfs2/file.c
··· 2391 2391 /* 2392 2392 * for completing the rest of the request. 2393 2393 */ 2394 - *ppos += written; 2395 2394 count -= written; 2396 2395 written_buffered = generic_perform_write(file, from, *ppos); 2397 2396 /* ··· 2405 2406 goto out_dio; 2406 2407 } 2407 2408 2408 - iocb->ki_pos = *ppos + written_buffered; 2409 2409 /* We need to ensure that the page cache pages are written to 2410 2410 * disk and invalidated to preserve the expected O_DIRECT 2411 2411 * semantics. ··· 2413 2415 ret = filemap_write_and_wait_range(file->f_mapping, *ppos, 2414 2416 endbyte); 2415 2417 if (ret == 0) { 2418 + iocb->ki_pos = *ppos + written_buffered; 2416 2419 written += written_buffered; 2417 2420 invalidate_mapping_pages(mapping, 2418 2421 *ppos >> PAGE_CACHE_SHIFT, ··· 2436 2437 /* buffered aio wouldn't have proper lock coverage today */ 2437 2438 BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); 2438 2439 2440 + if (unlikely(written <= 0)) 2441 + goto no_sync; 2442 + 2439 2443 if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || 2440 2444 ((file->f_flags & O_DIRECT) && !direct_io)) { 2441 - ret = filemap_fdatawrite_range(file->f_mapping, *ppos, 2442 - *ppos + count - 1); 2445 + ret = filemap_fdatawrite_range(file->f_mapping, 2446 + iocb->ki_pos - written, 2447 + iocb->ki_pos - 1); 2443 2448 if (ret < 0) 2444 2449 written = ret; 2445 2450 ··· 2454 2451 } 2455 2452 2456 2453 if (!ret) 2457 - ret = filemap_fdatawait_range(file->f_mapping, *ppos, 2458 - *ppos + count - 1); 2454 + ret = filemap_fdatawait_range(file->f_mapping, 2455 + iocb->ki_pos - written, 2456 + iocb->ki_pos - 1); 2459 2457 } 2460 2458 2459 + no_sync: 2461 2460 /* 2462 2461 * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io 2463 2462 * function pointer which is called when o_direct io completes so that
+1 -1
include/linux/fs.h
··· 1569 1569 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); 1570 1570 long (*compat_ioctl) (struct file *, unsigned int, unsigned long); 1571 1571 int (*mmap) (struct file *, struct vm_area_struct *); 1572 - void (*mremap)(struct file *, struct vm_area_struct *); 1572 + int (*mremap)(struct file *, struct vm_area_struct *); 1573 1573 int (*open) (struct inode *, struct file *); 1574 1574 int (*flush) (struct file *, fl_owner_t id); 1575 1575 int (*release) (struct inode *, struct file *);
+8 -2
mm/mremap.c
··· 286 286 old_len = new_len; 287 287 old_addr = new_addr; 288 288 new_addr = -ENOMEM; 289 - } else if (vma->vm_file && vma->vm_file->f_op->mremap) 290 - vma->vm_file->f_op->mremap(vma->vm_file, new_vma); 289 + } else if (vma->vm_file && vma->vm_file->f_op->mremap) { 290 + err = vma->vm_file->f_op->mremap(vma->vm_file, new_vma); 291 + if (err < 0) { 292 + move_page_tables(new_vma, new_addr, vma, old_addr, 293 + moved_len, true); 294 + return err; 295 + } 296 + } 291 297 292 298 /* Conceal VM_ACCOUNT so old reservation is not undone */ 293 299 if (vm_flags & VM_ACCOUNT) {