aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-04-03 03:17:43 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-05-06 17:38:00 -0400
commit8174202b34c30e0c07231bf63f18ab29af634f0b (patch)
treed4d3549db384ef26f5f5c7834a66fd3caa77fa5e /mm
parent3644424dc6309439c4c8d97590cdac4100376255 (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.c61
-rw-r--r--mm/shmem.c4
-rw-r--r--mm/vmscan.c2
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:
2542EXPORT_SYMBOL(generic_perform_write); 2542EXPORT_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 */
2562ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 2561ssize_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}
2646EXPORT_SYMBOL(__generic_file_write_iter);
2647
2648ssize_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}
2652EXPORT_SYMBOL(__generic_file_aio_write); 2657EXPORT_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 */
2665ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 2668ssize_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}
2687EXPORT_SYMBOL(generic_file_write_iter);
2688
2689ssize_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}
2687EXPORT_SYMBOL(generic_file_aio_write); 2700EXPORT_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 *