diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/aops.c | 7 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 138 |
2 files changed, 27 insertions, 118 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index d310d12a9adc..4a231a166cf8 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -599,9 +599,8 @@ static int ocfs2_releasepage(struct page *page, gfp_t wait) | |||
599 | 599 | ||
600 | static ssize_t ocfs2_direct_IO(int rw, | 600 | static ssize_t ocfs2_direct_IO(int rw, |
601 | struct kiocb *iocb, | 601 | struct kiocb *iocb, |
602 | const struct iovec *iov, | 602 | struct iov_iter *iter, |
603 | loff_t offset, | 603 | loff_t offset) |
604 | unsigned long nr_segs) | ||
605 | { | 604 | { |
606 | struct file *file = iocb->ki_filp; | 605 | struct file *file = iocb->ki_filp; |
607 | struct inode *inode = file_inode(file)->i_mapping->host; | 606 | struct inode *inode = file_inode(file)->i_mapping->host; |
@@ -618,7 +617,7 @@ static ssize_t ocfs2_direct_IO(int rw, | |||
618 | return 0; | 617 | return 0; |
619 | 618 | ||
620 | return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, | 619 | return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, |
621 | iov, offset, nr_segs, | 620 | iter, offset, |
622 | ocfs2_direct_IO_get_blocks, | 621 | ocfs2_direct_IO_get_blocks, |
623 | ocfs2_dio_end_io, NULL, 0); | 622 | ocfs2_dio_end_io, NULL, 0); |
624 | } | 623 | } |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 8970dcf74de5..465c95016a39 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -2233,16 +2233,13 @@ out: | |||
2233 | return ret; | 2233 | return ret; |
2234 | } | 2234 | } |
2235 | 2235 | ||
2236 | static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | 2236 | static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, |
2237 | const struct iovec *iov, | 2237 | struct iov_iter *from) |
2238 | unsigned long nr_segs, | ||
2239 | loff_t pos) | ||
2240 | { | 2238 | { |
2241 | int ret, direct_io, appending, rw_level, have_alloc_sem = 0; | 2239 | int ret, direct_io, appending, rw_level, have_alloc_sem = 0; |
2242 | int can_do_direct, has_refcount = 0; | 2240 | int can_do_direct, has_refcount = 0; |
2243 | ssize_t written = 0; | 2241 | ssize_t written = 0; |
2244 | size_t ocount; /* original count */ | 2242 | size_t count = iov_iter_count(from); |
2245 | size_t count; /* after file limit checks */ | ||
2246 | loff_t old_size, *ppos = &iocb->ki_pos; | 2243 | loff_t old_size, *ppos = &iocb->ki_pos; |
2247 | u32 old_clusters; | 2244 | u32 old_clusters; |
2248 | struct file *file = iocb->ki_filp; | 2245 | struct file *file = iocb->ki_filp; |
@@ -2256,7 +2253,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
2256 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 2253 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
2257 | file->f_path.dentry->d_name.len, | 2254 | file->f_path.dentry->d_name.len, |
2258 | file->f_path.dentry->d_name.name, | 2255 | file->f_path.dentry->d_name.name, |
2259 | (unsigned int)nr_segs); | 2256 | (unsigned int)from->nr_segs); /* GRRRRR */ |
2260 | 2257 | ||
2261 | if (iocb->ki_nbytes == 0) | 2258 | if (iocb->ki_nbytes == 0) |
2262 | return 0; | 2259 | return 0; |
@@ -2354,29 +2351,21 @@ relock: | |||
2354 | /* communicate with ocfs2_dio_end_io */ | 2351 | /* communicate with ocfs2_dio_end_io */ |
2355 | ocfs2_iocb_set_rw_locked(iocb, rw_level); | 2352 | ocfs2_iocb_set_rw_locked(iocb, rw_level); |
2356 | 2353 | ||
2357 | ret = generic_segment_checks(iov, &nr_segs, &ocount, | ||
2358 | VERIFY_READ); | ||
2359 | if (ret) | ||
2360 | goto out_dio; | ||
2361 | |||
2362 | count = ocount; | ||
2363 | ret = generic_write_checks(file, ppos, &count, | 2354 | ret = generic_write_checks(file, ppos, &count, |
2364 | S_ISBLK(inode->i_mode)); | 2355 | S_ISBLK(inode->i_mode)); |
2365 | if (ret) | 2356 | if (ret) |
2366 | goto out_dio; | 2357 | goto out_dio; |
2367 | 2358 | ||
2359 | iov_iter_truncate(from, count); | ||
2368 | if (direct_io) { | 2360 | if (direct_io) { |
2369 | written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, | 2361 | written = generic_file_direct_write(iocb, from, *ppos); |
2370 | count, ocount); | ||
2371 | if (written < 0) { | 2362 | if (written < 0) { |
2372 | ret = written; | 2363 | ret = written; |
2373 | goto out_dio; | 2364 | goto out_dio; |
2374 | } | 2365 | } |
2375 | } else { | 2366 | } else { |
2376 | struct iov_iter from; | ||
2377 | iov_iter_init(&from, iov, nr_segs, count, 0); | ||
2378 | current->backing_dev_info = file->f_mapping->backing_dev_info; | 2367 | current->backing_dev_info = file->f_mapping->backing_dev_info; |
2379 | written = generic_perform_write(file, &from, *ppos); | 2368 | written = generic_perform_write(file, from, *ppos); |
2380 | if (likely(written >= 0)) | 2369 | if (likely(written >= 0)) |
2381 | iocb->ki_pos = *ppos + written; | 2370 | iocb->ki_pos = *ppos + written; |
2382 | current->backing_dev_info = NULL; | 2371 | current->backing_dev_info = NULL; |
@@ -2441,84 +2430,6 @@ out_sems: | |||
2441 | return ret; | 2430 | return ret; |
2442 | } | 2431 | } |
2443 | 2432 | ||
2444 | static int ocfs2_splice_to_file(struct pipe_inode_info *pipe, | ||
2445 | struct file *out, | ||
2446 | struct splice_desc *sd) | ||
2447 | { | ||
2448 | int ret; | ||
2449 | |||
2450 | ret = ocfs2_prepare_inode_for_write(out, &sd->pos, | ||
2451 | sd->total_len, 0, NULL, NULL); | ||
2452 | if (ret < 0) { | ||
2453 | mlog_errno(ret); | ||
2454 | return ret; | ||
2455 | } | ||
2456 | |||
2457 | return splice_from_pipe_feed(pipe, sd, pipe_to_file); | ||
2458 | } | ||
2459 | |||
2460 | static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, | ||
2461 | struct file *out, | ||
2462 | loff_t *ppos, | ||
2463 | size_t len, | ||
2464 | unsigned int flags) | ||
2465 | { | ||
2466 | int ret; | ||
2467 | struct address_space *mapping = out->f_mapping; | ||
2468 | struct inode *inode = mapping->host; | ||
2469 | struct splice_desc sd = { | ||
2470 | .total_len = len, | ||
2471 | .flags = flags, | ||
2472 | .pos = *ppos, | ||
2473 | .u.file = out, | ||
2474 | }; | ||
2475 | |||
2476 | |||
2477 | trace_ocfs2_file_splice_write(inode, out, out->f_path.dentry, | ||
2478 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | ||
2479 | out->f_path.dentry->d_name.len, | ||
2480 | out->f_path.dentry->d_name.name, len); | ||
2481 | |||
2482 | pipe_lock(pipe); | ||
2483 | |||
2484 | splice_from_pipe_begin(&sd); | ||
2485 | do { | ||
2486 | ret = splice_from_pipe_next(pipe, &sd); | ||
2487 | if (ret <= 0) | ||
2488 | break; | ||
2489 | |||
2490 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); | ||
2491 | ret = ocfs2_rw_lock(inode, 1); | ||
2492 | if (ret < 0) | ||
2493 | mlog_errno(ret); | ||
2494 | else { | ||
2495 | ret = ocfs2_splice_to_file(pipe, out, &sd); | ||
2496 | ocfs2_rw_unlock(inode, 1); | ||
2497 | } | ||
2498 | mutex_unlock(&inode->i_mutex); | ||
2499 | } while (ret > 0); | ||
2500 | splice_from_pipe_end(pipe, &sd); | ||
2501 | |||
2502 | pipe_unlock(pipe); | ||
2503 | |||
2504 | if (sd.num_spliced) | ||
2505 | ret = sd.num_spliced; | ||
2506 | |||
2507 | if (ret > 0) { | ||
2508 | int err; | ||
2509 | |||
2510 | err = generic_write_sync(out, *ppos, ret); | ||
2511 | if (err) | ||
2512 | ret = err; | ||
2513 | else | ||
2514 | *ppos += ret; | ||
2515 | |||
2516 | balance_dirty_pages_ratelimited(mapping); | ||
2517 | } | ||
2518 | |||
2519 | return ret; | ||
2520 | } | ||
2521 | |||
2522 | static ssize_t ocfs2_file_splice_read(struct file *in, | 2433 | static ssize_t ocfs2_file_splice_read(struct file *in, |
2523 | loff_t *ppos, | 2434 | loff_t *ppos, |
2524 | struct pipe_inode_info *pipe, | 2435 | struct pipe_inode_info *pipe, |
@@ -2534,7 +2445,7 @@ static ssize_t ocfs2_file_splice_read(struct file *in, | |||
2534 | in->f_path.dentry->d_name.name, len); | 2445 | in->f_path.dentry->d_name.name, len); |
2535 | 2446 | ||
2536 | /* | 2447 | /* |
2537 | * See the comment in ocfs2_file_aio_read() | 2448 | * See the comment in ocfs2_file_read_iter() |
2538 | */ | 2449 | */ |
2539 | ret = ocfs2_inode_lock_atime(inode, in->f_path.mnt, &lock_level); | 2450 | ret = ocfs2_inode_lock_atime(inode, in->f_path.mnt, &lock_level); |
2540 | if (ret < 0) { | 2451 | if (ret < 0) { |
@@ -2549,10 +2460,8 @@ bail: | |||
2549 | return ret; | 2460 | return ret; |
2550 | } | 2461 | } |
2551 | 2462 | ||
2552 | static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | 2463 | static ssize_t ocfs2_file_read_iter(struct kiocb *iocb, |
2553 | const struct iovec *iov, | 2464 | struct iov_iter *to) |
2554 | unsigned long nr_segs, | ||
2555 | loff_t pos) | ||
2556 | { | 2465 | { |
2557 | int ret = 0, rw_level = -1, have_alloc_sem = 0, lock_level = 0; | 2466 | int ret = 0, rw_level = -1, have_alloc_sem = 0, lock_level = 0; |
2558 | struct file *filp = iocb->ki_filp; | 2467 | struct file *filp = iocb->ki_filp; |
@@ -2561,7 +2470,8 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
2561 | trace_ocfs2_file_aio_read(inode, filp, filp->f_path.dentry, | 2470 | trace_ocfs2_file_aio_read(inode, filp, filp->f_path.dentry, |
2562 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 2471 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
2563 | filp->f_path.dentry->d_name.len, | 2472 | filp->f_path.dentry->d_name.len, |
2564 | filp->f_path.dentry->d_name.name, nr_segs); | 2473 | filp->f_path.dentry->d_name.name, |
2474 | to->nr_segs); /* GRRRRR */ | ||
2565 | 2475 | ||
2566 | 2476 | ||
2567 | if (!inode) { | 2477 | if (!inode) { |
@@ -2606,13 +2516,13 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
2606 | } | 2516 | } |
2607 | ocfs2_inode_unlock(inode, lock_level); | 2517 | ocfs2_inode_unlock(inode, lock_level); |
2608 | 2518 | ||
2609 | ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); | 2519 | ret = generic_file_read_iter(iocb, to); |
2610 | trace_generic_file_aio_read_ret(ret); | 2520 | trace_generic_file_aio_read_ret(ret); |
2611 | 2521 | ||
2612 | /* buffered aio wouldn't have proper lock coverage today */ | 2522 | /* buffered aio wouldn't have proper lock coverage today */ |
2613 | BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); | 2523 | BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); |
2614 | 2524 | ||
2615 | /* see ocfs2_file_aio_write */ | 2525 | /* see ocfs2_file_write_iter */ |
2616 | if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb)) { | 2526 | if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb)) { |
2617 | rw_level = -1; | 2527 | rw_level = -1; |
2618 | have_alloc_sem = 0; | 2528 | have_alloc_sem = 0; |
@@ -2705,14 +2615,14 @@ const struct inode_operations ocfs2_special_file_iops = { | |||
2705 | */ | 2615 | */ |
2706 | const struct file_operations ocfs2_fops = { | 2616 | const struct file_operations ocfs2_fops = { |
2707 | .llseek = ocfs2_file_llseek, | 2617 | .llseek = ocfs2_file_llseek, |
2708 | .read = do_sync_read, | 2618 | .read = new_sync_read, |
2709 | .write = do_sync_write, | 2619 | .write = new_sync_write, |
2710 | .mmap = ocfs2_mmap, | 2620 | .mmap = ocfs2_mmap, |
2711 | .fsync = ocfs2_sync_file, | 2621 | .fsync = ocfs2_sync_file, |
2712 | .release = ocfs2_file_release, | 2622 | .release = ocfs2_file_release, |
2713 | .open = ocfs2_file_open, | 2623 | .open = ocfs2_file_open, |
2714 | .aio_read = ocfs2_file_aio_read, | 2624 | .read_iter = ocfs2_file_read_iter, |
2715 | .aio_write = ocfs2_file_aio_write, | 2625 | .write_iter = ocfs2_file_write_iter, |
2716 | .unlocked_ioctl = ocfs2_ioctl, | 2626 | .unlocked_ioctl = ocfs2_ioctl, |
2717 | #ifdef CONFIG_COMPAT | 2627 | #ifdef CONFIG_COMPAT |
2718 | .compat_ioctl = ocfs2_compat_ioctl, | 2628 | .compat_ioctl = ocfs2_compat_ioctl, |
@@ -2720,7 +2630,7 @@ const struct file_operations ocfs2_fops = { | |||
2720 | .lock = ocfs2_lock, | 2630 | .lock = ocfs2_lock, |
2721 | .flock = ocfs2_flock, | 2631 | .flock = ocfs2_flock, |
2722 | .splice_read = ocfs2_file_splice_read, | 2632 | .splice_read = ocfs2_file_splice_read, |
2723 | .splice_write = ocfs2_file_splice_write, | 2633 | .splice_write = iter_file_splice_write, |
2724 | .fallocate = ocfs2_fallocate, | 2634 | .fallocate = ocfs2_fallocate, |
2725 | }; | 2635 | }; |
2726 | 2636 | ||
@@ -2753,21 +2663,21 @@ const struct file_operations ocfs2_dops = { | |||
2753 | */ | 2663 | */ |
2754 | const struct file_operations ocfs2_fops_no_plocks = { | 2664 | const struct file_operations ocfs2_fops_no_plocks = { |
2755 | .llseek = ocfs2_file_llseek, | 2665 | .llseek = ocfs2_file_llseek, |
2756 | .read = do_sync_read, | 2666 | .read = new_sync_read, |
2757 | .write = do_sync_write, | 2667 | .write = new_sync_write, |
2758 | .mmap = ocfs2_mmap, | 2668 | .mmap = ocfs2_mmap, |
2759 | .fsync = ocfs2_sync_file, | 2669 | .fsync = ocfs2_sync_file, |
2760 | .release = ocfs2_file_release, | 2670 | .release = ocfs2_file_release, |
2761 | .open = ocfs2_file_open, | 2671 | .open = ocfs2_file_open, |
2762 | .aio_read = ocfs2_file_aio_read, | 2672 | .read_iter = ocfs2_file_read_iter, |
2763 | .aio_write = ocfs2_file_aio_write, | 2673 | .write_iter = ocfs2_file_write_iter, |
2764 | .unlocked_ioctl = ocfs2_ioctl, | 2674 | .unlocked_ioctl = ocfs2_ioctl, |
2765 | #ifdef CONFIG_COMPAT | 2675 | #ifdef CONFIG_COMPAT |
2766 | .compat_ioctl = ocfs2_compat_ioctl, | 2676 | .compat_ioctl = ocfs2_compat_ioctl, |
2767 | #endif | 2677 | #endif |
2768 | .flock = ocfs2_flock, | 2678 | .flock = ocfs2_flock, |
2769 | .splice_read = ocfs2_file_splice_read, | 2679 | .splice_read = ocfs2_file_splice_read, |
2770 | .splice_write = ocfs2_file_splice_write, | 2680 | .splice_write = iter_file_splice_write, |
2771 | .fallocate = ocfs2_fallocate, | 2681 | .fallocate = ocfs2_fallocate, |
2772 | }; | 2682 | }; |
2773 | 2683 | ||