diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-04-03 03:17:43 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-05-06 17:38:00 -0400 |
commit | 8174202b34c30e0c07231bf63f18ab29af634f0b (patch) | |
tree | d4d3549db384ef26f5f5c7834a66fd3caa77fa5e /mm | |
parent | 3644424dc6309439c4c8d97590cdac4100376255 (diff) |
write_iter variants of {__,}generic_file_aio_write()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/filemap.c | 61 | ||||
-rw-r--r-- | mm/shmem.c | 4 | ||||
-rw-r--r-- | mm/vmscan.c | 2 |
3 files changed, 40 insertions, 27 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index c0404b763a17..d2d9eeec8bf0 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -2542,10 +2542,9 @@ again: | |||
2542 | EXPORT_SYMBOL(generic_perform_write); | 2542 | EXPORT_SYMBOL(generic_perform_write); |
2543 | 2543 | ||
2544 | /** | 2544 | /** |
2545 | * __generic_file_aio_write - write data to a file | 2545 | * __generic_file_write_iter - write data to a file |
2546 | * @iocb: IO state structure (file, offset, etc.) | 2546 | * @iocb: IO state structure (file, offset, etc.) |
2547 | * @iov: vector with data to write | 2547 | * @from: iov_iter with data to write |
2548 | * @nr_segs: number of segments in the vector | ||
2549 | * | 2548 | * |
2550 | * This function does all the work needed for actually writing data to a | 2549 | * This function does all the work needed for actually writing data to a |
2551 | * file. It does all basic checks, removes SUID from the file, updates | 2550 | * file. It does all basic checks, removes SUID from the file, updates |
@@ -2559,21 +2558,16 @@ EXPORT_SYMBOL(generic_perform_write); | |||
2559 | * A caller has to handle it. This is mainly due to the fact that we want to | 2558 | * A caller has to handle it. This is mainly due to the fact that we want to |
2560 | * avoid syncing under i_mutex. | 2559 | * avoid syncing under i_mutex. |
2561 | */ | 2560 | */ |
2562 | ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 2561 | ssize_t __generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from) |
2563 | unsigned long nr_segs) | ||
2564 | { | 2562 | { |
2565 | struct file *file = iocb->ki_filp; | 2563 | struct file *file = iocb->ki_filp; |
2566 | struct address_space * mapping = file->f_mapping; | 2564 | struct address_space * mapping = file->f_mapping; |
2567 | size_t count; /* after file limit checks */ | ||
2568 | struct inode *inode = mapping->host; | 2565 | struct inode *inode = mapping->host; |
2569 | loff_t pos = iocb->ki_pos; | 2566 | loff_t pos = iocb->ki_pos; |
2570 | ssize_t written = 0; | 2567 | ssize_t written = 0; |
2571 | ssize_t err; | 2568 | ssize_t err; |
2572 | ssize_t status; | 2569 | ssize_t status; |
2573 | struct iov_iter from; | 2570 | size_t count = iov_iter_count(from); |
2574 | |||
2575 | count = iov_length(iov, nr_segs); | ||
2576 | iov_iter_init(&from, WRITE, iov, nr_segs, count); | ||
2577 | 2571 | ||
2578 | /* We can write back this queue in page reclaim */ | 2572 | /* We can write back this queue in page reclaim */ |
2579 | current->backing_dev_info = mapping->backing_dev_info; | 2573 | current->backing_dev_info = mapping->backing_dev_info; |
@@ -2584,7 +2578,7 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2584 | if (count == 0) | 2578 | if (count == 0) |
2585 | goto out; | 2579 | goto out; |
2586 | 2580 | ||
2587 | iov_iter_truncate(&from, count); | 2581 | iov_iter_truncate(from, count); |
2588 | 2582 | ||
2589 | err = file_remove_suid(file); | 2583 | err = file_remove_suid(file); |
2590 | if (err) | 2584 | if (err) |
@@ -2598,7 +2592,7 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2598 | if (unlikely(file->f_flags & O_DIRECT)) { | 2592 | if (unlikely(file->f_flags & O_DIRECT)) { |
2599 | loff_t endbyte; | 2593 | loff_t endbyte; |
2600 | 2594 | ||
2601 | written = generic_file_direct_write(iocb, &from, pos); | 2595 | written = generic_file_direct_write(iocb, from, pos); |
2602 | if (written < 0 || written == count) | 2596 | if (written < 0 || written == count) |
2603 | goto out; | 2597 | goto out; |
2604 | 2598 | ||
@@ -2609,7 +2603,7 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2609 | pos += written; | 2603 | pos += written; |
2610 | count -= written; | 2604 | count -= written; |
2611 | 2605 | ||
2612 | status = generic_perform_write(file, &from, pos); | 2606 | status = generic_perform_write(file, from, pos); |
2613 | /* | 2607 | /* |
2614 | * If generic_perform_write() returned a synchronous error | 2608 | * If generic_perform_write() returned a synchronous error |
2615 | * then we want to return the number of bytes which were | 2609 | * then we want to return the number of bytes which were |
@@ -2641,7 +2635,7 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2641 | */ | 2635 | */ |
2642 | } | 2636 | } |
2643 | } else { | 2637 | } else { |
2644 | written = generic_perform_write(file, &from, pos); | 2638 | written = generic_perform_write(file, from, pos); |
2645 | if (likely(written >= 0)) | 2639 | if (likely(written >= 0)) |
2646 | iocb->ki_pos = pos + written; | 2640 | iocb->ki_pos = pos + written; |
2647 | } | 2641 | } |
@@ -2649,30 +2643,36 @@ out: | |||
2649 | current->backing_dev_info = NULL; | 2643 | current->backing_dev_info = NULL; |
2650 | return written ? written : err; | 2644 | return written ? written : err; |
2651 | } | 2645 | } |
2646 | EXPORT_SYMBOL(__generic_file_write_iter); | ||
2647 | |||
2648 | ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | ||
2649 | unsigned long nr_segs) | ||
2650 | { | ||
2651 | size_t count = iov_length(iov, nr_segs); | ||
2652 | struct iov_iter from; | ||
2653 | |||
2654 | iov_iter_init(&from, WRITE, iov, nr_segs, count); | ||
2655 | return __generic_file_write_iter(iocb, &from); | ||
2656 | } | ||
2652 | EXPORT_SYMBOL(__generic_file_aio_write); | 2657 | EXPORT_SYMBOL(__generic_file_aio_write); |
2653 | 2658 | ||
2654 | /** | 2659 | /** |
2655 | * generic_file_aio_write - write data to a file | 2660 | * generic_file_write_iter - write data to a file |
2656 | * @iocb: IO state structure | 2661 | * @iocb: IO state structure |
2657 | * @iov: vector with data to write | 2662 | * @from: iov_iter with data to write |
2658 | * @nr_segs: number of segments in the vector | ||
2659 | * @pos: position in file where to write | ||
2660 | * | 2663 | * |
2661 | * This is a wrapper around __generic_file_aio_write() to be used by most | 2664 | * This is a wrapper around __generic_file_write_iter() to be used by most |
2662 | * filesystems. It takes care of syncing the file in case of O_SYNC file | 2665 | * filesystems. It takes care of syncing the file in case of O_SYNC file |
2663 | * and acquires i_mutex as needed. | 2666 | * and acquires i_mutex as needed. |
2664 | */ | 2667 | */ |
2665 | ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 2668 | ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from) |
2666 | unsigned long nr_segs, loff_t pos) | ||
2667 | { | 2669 | { |
2668 | struct file *file = iocb->ki_filp; | 2670 | struct file *file = iocb->ki_filp; |
2669 | struct inode *inode = file->f_mapping->host; | 2671 | struct inode *inode = file->f_mapping->host; |
2670 | ssize_t ret; | 2672 | ssize_t ret; |
2671 | 2673 | ||
2672 | BUG_ON(iocb->ki_pos != pos); | ||
2673 | |||
2674 | mutex_lock(&inode->i_mutex); | 2674 | mutex_lock(&inode->i_mutex); |
2675 | ret = __generic_file_aio_write(iocb, iov, nr_segs); | 2675 | ret = __generic_file_write_iter(iocb, from); |
2676 | mutex_unlock(&inode->i_mutex); | 2676 | mutex_unlock(&inode->i_mutex); |
2677 | 2677 | ||
2678 | if (ret > 0) { | 2678 | if (ret > 0) { |
@@ -2684,6 +2684,19 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
2684 | } | 2684 | } |
2685 | return ret; | 2685 | return ret; |
2686 | } | 2686 | } |
2687 | EXPORT_SYMBOL(generic_file_write_iter); | ||
2688 | |||
2689 | ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | ||
2690 | unsigned long nr_segs, loff_t pos) | ||
2691 | { | ||
2692 | size_t count = iov_length(iov, nr_segs); | ||
2693 | struct iov_iter from; | ||
2694 | |||
2695 | BUG_ON(iocb->ki_pos != pos); | ||
2696 | |||
2697 | iov_iter_init(&from, WRITE, iov, nr_segs, count); | ||
2698 | return generic_file_write_iter(iocb, &from); | ||
2699 | } | ||
2687 | EXPORT_SYMBOL(generic_file_aio_write); | 2700 | EXPORT_SYMBOL(generic_file_aio_write); |
2688 | 2701 | ||
2689 | /** | 2702 | /** |
diff --git a/mm/shmem.c b/mm/shmem.c index edc6c7e817e9..d3e5c6fc313c 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -2618,9 +2618,9 @@ static const struct file_operations shmem_file_operations = { | |||
2618 | #ifdef CONFIG_TMPFS | 2618 | #ifdef CONFIG_TMPFS |
2619 | .llseek = shmem_file_llseek, | 2619 | .llseek = shmem_file_llseek, |
2620 | .read = new_sync_read, | 2620 | .read = new_sync_read, |
2621 | .write = do_sync_write, | 2621 | .write = new_sync_write, |
2622 | .read_iter = shmem_file_read_iter, | 2622 | .read_iter = shmem_file_read_iter, |
2623 | .aio_write = generic_file_aio_write, | 2623 | .write_iter = generic_file_write_iter, |
2624 | .fsync = noop_fsync, | 2624 | .fsync = noop_fsync, |
2625 | .splice_read = shmem_file_splice_read, | 2625 | .splice_read = shmem_file_splice_read, |
2626 | .splice_write = generic_file_splice_write, | 2626 | .splice_write = generic_file_splice_write, |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 32c661d66a45..9c2dba6ac685 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -458,7 +458,7 @@ static pageout_t pageout(struct page *page, struct address_space *mapping, | |||
458 | * stalls if we need to run get_block(). We could test | 458 | * stalls if we need to run get_block(). We could test |
459 | * PagePrivate for that. | 459 | * PagePrivate for that. |
460 | * | 460 | * |
461 | * If this process is currently in __generic_file_aio_write() against | 461 | * If this process is currently in __generic_file_write_iter() against |
462 | * this page's queue, we can perform writeback even if that | 462 | * this page's queue, we can perform writeback even if that |
463 | * will block. | 463 | * will block. |
464 | * | 464 | * |