orangefs: make pvfs2_inode_read() take iov_iter
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 8 Oct 2015 22:31:05 +0000 (18:31 -0400)
committerMike Marshall <hubcap@omnibond.com>
Fri, 13 Nov 2015 16:36:31 +0000 (11:36 -0500)
... and make the only caller use page-backed iov_iter,
getting rid of kmap/kunmap *and* of the bug with
attempted use of iovec-backed copy_page_to_iter()
on a kernel pointer.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
fs/orangefs/file.c
fs/orangefs/inode.c
fs/orangefs/pvfs2-kernel.h

index 8dae04dc9df4c5d5ecd677001fcad95414ade149..78d296bb870e732b26c8cff69a2da8ec843d4709 100644 (file)
@@ -369,22 +369,17 @@ out:
  * Data may be placed either in a user or kernel buffer.
  */
 ssize_t pvfs2_inode_read(struct inode *inode,
-                        char __user *buf,
-                        size_t count,
+                        struct iov_iter *iter,
                         loff_t *offset,
                         loff_t readahead_size)
 {
        struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
+       size_t count = iov_iter_count(iter);
        size_t bufmap_size;
-       struct iovec vec;
-       struct iov_iter iter;
        ssize_t ret = -EINVAL;
 
        g_pvfs2_stats.reads++;
 
-       vec.iov_base = buf;
-       vec.iov_len = count;
-
        bufmap_size = pvfs_bufmap_size_query();
        if (count > bufmap_size) {
                gossip_debug(GOSSIP_FILE_DEBUG,
@@ -400,8 +395,7 @@ ssize_t pvfs2_inode_read(struct inode *inode,
                     count,
                     llu(*offset));
 
-       iov_iter_init(&iter, READ, &vec, 1, count);
-       ret = wait_for_direct_io(PVFS_IO_READ, inode, offset, &iter,
+       ret = wait_for_direct_io(PVFS_IO_READ, inode, offset, iter,
                        count, readahead_size);
        if (ret > 0)
                *offset += ret;
index 4f7c45a44c1f4e7d29d9b62cb218c134fbfd6dc7..70d1c1925ea3ea4f1c4a3f10bd90517d557d5ee7 100644 (file)
 
 static int read_one_page(struct page *page)
 {
-       void *page_data;
        int ret;
        int max_block;
        ssize_t bytes_read = 0;
        struct inode *inode = page->mapping->host;
        const __u32 blocksize = PAGE_CACHE_SIZE;        /* inode->i_blksize */
        const __u32 blockbits = PAGE_CACHE_SHIFT;       /* inode->i_blkbits */
+       struct iov_iter to;
+       struct bio_vec bv = {.bv_page = page, .bv_len = PAGE_SIZE};
+
+       iov_iter_bvec(&to, ITER_BVEC | READ, &bv, 1, PAGE_SIZE);
 
        gossip_debug(GOSSIP_INODE_DEBUG,
                    "pvfs2_readpage called with page %p\n",
                     page);
-       page_data = pvfs2_kmap(page);
 
        max_block = ((inode->i_size / blocksize) + 1);
 
@@ -33,16 +35,12 @@ static int read_one_page(struct page *page)
                loff_t blockptr_offset = (((loff_t) page->index) << blockbits);
 
                bytes_read = pvfs2_inode_read(inode,
-                                             (char __user *) page_data,
-                                             blocksize,
+                                             &to,
                                              &blockptr_offset,
                                              inode->i_size);
        }
-       /* only zero remaining unread portions of the page data */
-       if (bytes_read > 0)
-               memset(page_data + bytes_read, 0, blocksize - bytes_read);
-       else
-               memset(page_data, 0, blocksize);
+       /* this will only zero remaining unread portions of the page data */
+       iov_iter_zero(~0U, &to);
        /* takes care of potential aliasing */
        flush_dcache_page(page);
        if (bytes_read < 0) {
@@ -54,7 +52,6 @@ static int read_one_page(struct page *page)
                        ClearPageError(page);
                ret = 0;
        }
-       pvfs2_kunmap(page);
        /* unlock the page after the ->readpage() routine completes */
        unlock_page(page);
        return ret;
index 29b4a48b3a25be74fd0de68c8943e77043339f5c..916a3551341995d25da488d43bf53f7683a33e17 100644 (file)
@@ -605,8 +605,7 @@ struct inode *pvfs2_iget(struct super_block *sb,
                         struct pvfs2_object_kref *ref);
 
 ssize_t pvfs2_inode_read(struct inode *inode,
-                        char __user *buf,
-                        size_t count,
+                        struct iov_iter *iter,
                         loff_t *offset,
                         loff_t readahead_size);