diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-03-05 22:53:04 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-05-06 17:32:49 -0400 |
commit | ed978a811ec528dbe40243605c3afab55892f722 (patch) | |
tree | 7b8b83a755286192b98bb7921fa4d6957709216e /mm | |
parent | 23faa7b8db9be0be4f158cfc558460bb95d9b245 (diff) |
new helper: generic_file_read_iter()
iov_iter-using variant of generic_file_aio_read(). Some callers
converted. Note that it's still not quite there for use as ->read_iter() -
we depend on having zero iter->iov_offset in O_DIRECT case. Fortunately,
that's true for all converted callers (and for generic_file_aio_read() itself).
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/filemap.c | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 866f4ae8223b..a7f79e90209c 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -1663,55 +1663,34 @@ out: | |||
1663 | return written ? written : error; | 1663 | return written ? written : error; |
1664 | } | 1664 | } |
1665 | 1665 | ||
1666 | /** | ||
1667 | * generic_file_aio_read - generic filesystem read routine | ||
1668 | * @iocb: kernel I/O control block | ||
1669 | * @iov: io vector request | ||
1670 | * @nr_segs: number of segments in the iovec | ||
1671 | * @pos: current file position | ||
1672 | * | ||
1673 | * This is the "read()" routine for all filesystems | ||
1674 | * that can use the page cache directly. | ||
1675 | */ | ||
1676 | ssize_t | 1666 | ssize_t |
1677 | generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | 1667 | generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) |
1678 | unsigned long nr_segs, loff_t pos) | ||
1679 | { | 1668 | { |
1680 | struct file *filp = iocb->ki_filp; | 1669 | struct file *file = iocb->ki_filp; |
1681 | ssize_t retval = 0; | 1670 | ssize_t retval = 0; |
1682 | size_t count; | ||
1683 | loff_t *ppos = &iocb->ki_pos; | 1671 | loff_t *ppos = &iocb->ki_pos; |
1684 | struct iov_iter i; | 1672 | loff_t pos = *ppos; |
1685 | |||
1686 | count = iov_length(iov, nr_segs); | ||
1687 | iov_iter_init(&i, iov, nr_segs, count, 0); | ||
1688 | 1673 | ||
1689 | /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ | 1674 | /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ |
1690 | if (filp->f_flags & O_DIRECT) { | 1675 | if (file->f_flags & O_DIRECT) { |
1676 | struct address_space *mapping = file->f_mapping; | ||
1677 | struct inode *inode = mapping->host; | ||
1678 | size_t count = iov_iter_count(iter); | ||
1691 | loff_t size; | 1679 | loff_t size; |
1692 | struct address_space *mapping; | ||
1693 | struct inode *inode; | ||
1694 | 1680 | ||
1695 | mapping = filp->f_mapping; | ||
1696 | inode = mapping->host; | ||
1697 | if (!count) | 1681 | if (!count) |
1698 | goto out; /* skip atime */ | 1682 | goto out; /* skip atime */ |
1699 | size = i_size_read(inode); | 1683 | size = i_size_read(inode); |
1700 | retval = filemap_write_and_wait_range(mapping, pos, | 1684 | retval = filemap_write_and_wait_range(mapping, pos, |
1701 | pos + count - 1); | 1685 | pos + count - 1); |
1702 | if (!retval) { | 1686 | if (!retval) { |
1703 | struct iov_iter data = i; | 1687 | struct iov_iter data = *iter; |
1704 | retval = mapping->a_ops->direct_IO(READ, iocb, &data, pos); | 1688 | retval = mapping->a_ops->direct_IO(READ, iocb, &data, pos); |
1705 | } | 1689 | } |
1706 | 1690 | ||
1707 | if (retval > 0) { | 1691 | if (retval > 0) { |
1708 | *ppos = pos + retval; | 1692 | *ppos = pos + retval; |
1709 | count -= retval; | 1693 | iov_iter_advance(iter, retval); |
1710 | /* | ||
1711 | * If we did a short DIO read we need to skip the | ||
1712 | * section of the iov that we've already read data into. | ||
1713 | */ | ||
1714 | iov_iter_advance(&i, retval); | ||
1715 | } | 1694 | } |
1716 | 1695 | ||
1717 | /* | 1696 | /* |
@@ -1722,16 +1701,38 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
1722 | * and return. Otherwise fallthrough to buffered io for | 1701 | * and return. Otherwise fallthrough to buffered io for |
1723 | * the rest of the read. | 1702 | * the rest of the read. |
1724 | */ | 1703 | */ |
1725 | if (retval < 0 || !count || *ppos >= size) { | 1704 | if (retval < 0 || !iov_iter_count(iter) || *ppos >= size) { |
1726 | file_accessed(filp); | 1705 | file_accessed(file); |
1727 | goto out; | 1706 | goto out; |
1728 | } | 1707 | } |
1729 | } | 1708 | } |
1730 | 1709 | ||
1731 | retval = do_generic_file_read(filp, ppos, &i, retval); | 1710 | retval = do_generic_file_read(file, ppos, iter, retval); |
1732 | out: | 1711 | out: |
1733 | return retval; | 1712 | return retval; |
1734 | } | 1713 | } |
1714 | EXPORT_SYMBOL(generic_file_read_iter); | ||
1715 | |||
1716 | /** | ||
1717 | * generic_file_aio_read - generic filesystem read routine | ||
1718 | * @iocb: kernel I/O control block | ||
1719 | * @iov: io vector request | ||
1720 | * @nr_segs: number of segments in the iovec | ||
1721 | * @pos: current file position | ||
1722 | * | ||
1723 | * This is the "read()" routine for all filesystems | ||
1724 | * that can use the page cache directly. | ||
1725 | */ | ||
1726 | ssize_t | ||
1727 | generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | ||
1728 | unsigned long nr_segs, loff_t pos) | ||
1729 | { | ||
1730 | size_t count = iov_length(iov, nr_segs); | ||
1731 | struct iov_iter i; | ||
1732 | |||
1733 | iov_iter_init(&i, iov, nr_segs, count, 0); | ||
1734 | return generic_file_read_iter(iocb, &i); | ||
1735 | } | ||
1735 | EXPORT_SYMBOL(generic_file_aio_read); | 1736 | EXPORT_SYMBOL(generic_file_aio_read); |
1736 | 1737 | ||
1737 | #ifdef CONFIG_MMU | 1738 | #ifdef CONFIG_MMU |