Code:
	From 0a9f08ed3aed64ef14097f3e18ad8641b62ef1d7 Mon Sep 17 00:00:00 2001
From: Mikhail Malygin <[email protected]>
Date: Thu, 25 Mar 2021 19:30:04 +0300
Subject: [PATCH] Implement prlfs_write_iter and prlfs_read_iter functions on
 top of prlfs_write and prlfs_read
---
 .../SharedFolders/Guest/Linux/prl_fs/file.c   | 100 +++++++++++++++++-
 1 file changed, 96 insertions(+), 4 deletions(-)
diff --git a/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.c b/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.c
index e779cf7..48537dc 100644
--- a/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.c
+++ b/prl_fs/SharedFolders/Guest/Linux/prl_fs/file.c
@@ -427,7 +427,7 @@ static ssize_t prlfs_read(struct file *filp, char *buf, size_t size,
     struct dentry *dentry = FILE_DENTRY(filp);
     struct inode *inode = dentry->d_inode;
-    return prlfs_rw(inode, buf, size, off, 0, 1, TG_REQ_COMMON);
+    return prlfs_rw(inode, buf, size, off, 0, 0, TG_REQ_COMMON);
 }
 static ssize_t prlfs_write(struct file *filp, const char *buf, size_t size,
@@ -445,7 +445,7 @@ static ssize_t prlfs_write(struct file *filp, const char *buf, size_t size,
         real_off = *off;
     prlfs_inode_lock(inode);
-    ret = prlfs_rw(inode, (char *)buf, size, &real_off, 1, 1, TG_REQ_COMMON);
+    ret = prlfs_rw(inode, (char *)buf, size, &real_off, 1, 0, TG_REQ_COMMON);
     dentry->d_time = 0;
     if (ret < 0)
         goto out;
@@ -462,6 +462,98 @@ out:
     return ret;
 }
+static ssize_t prlfs_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+{
+    ssize_t ret = 0;
+    size_t alloc_size = 512 * 1024;
+    size_t bytes_done = 0;
+
+    size_t buf_size = min_t(size_t, alloc_size, iter->count);
+    void *buf = kzalloc(buf_size, GFP_KERNEL);
+
+    if(!buf) {
+        printk("prlfs_read_iter: failed to allocate %ld bytes\n", buf_size);
+        return -ENOMEM;
+    }
+
+    DPRINTK("prlfs_read_iter: reading %ld bytes\n", iter->count);
+
+    while(iter->count) {
+        size_t to_read = min_t(size_t, alloc_size, iter->count);
+        DPRINTK("prlfs_read_iter: %ld bytes to be read from fs, remain %ld\n", to_read, iter->count);
+
+        ret = prlfs_read(iocb->ki_filp, buf, to_read, &iocb->ki_pos);
+
+        if(ret < 0) {
+            goto err;
+        }
+
+        ret = copy_to_iter(buf, ret, iter);
+
+        DPRINTK("prlfs_read_iter: %ld bytes copied to iter\n", ret);
+
+        bytes_done += ret;
+
+        if (ret == 0) {
+            break;
+        }
+    }
+
+    DPRINTK("prlfs_read_iter: %ld bytes read\n", bytes_done);
+
+
+    kfree(buf);
+    return bytes_done;
+
+err:
+    kfree(buf);
+    return ret;
+}
+
+static ssize_t prlfs_write_iter(struct kiocb *iocb, struct iov_iter *iter)
+{
+    ssize_t ret = 0;
+    size_t alloc_size = 512 * 1024;
+    size_t bytes_done = 0;
+
+    size_t buf_size = min_t(size_t, alloc_size, iter->count);
+    void *buf = kzalloc(buf_size, GFP_KERNEL);
+
+    if(!buf) {
+        printk("prlfs_write_iter: failed to allocate %ld bytes\n", buf_size);
+        return -ENOMEM;
+    }
+
+    while(iter->count) {
+        size_t bytes = copy_from_iter(buf, min_t(ssize_t, buf_size, iter->count), iter);
+        size_t written = 0;
+
+        while(written < bytes) {
+            DPRINTK("prlfs_write_iter: %ld bytes to be written to fs", bytes);
+
+            ret = prlfs_write(iocb->ki_filp, buf + written, bytes - written, &iocb->ki_pos);
+
+            if(ret < 0) {
+                goto err;
+            }
+
+            written += ret;
+            bytes_done += ret;
+        }
+
+        if (ret == 0) {
+            break;
+        }
+    }
+
+    kfree(buf);
+    return bytes_done;
+
+err:
+    kfree(buf);
+    return ret;
+}
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
 #ifdef PRL_SIMPLE_SYNC_FILE
 int simple_sync_file(struct file *filp, struct dentry *dentry, int datasync)
@@ -473,8 +565,8 @@ int simple_sync_file(struct file *filp, struct dentry *dentry, int datasync)
 struct file_operations prlfs_file_fops = {
     .open        = prlfs_open,
-    .read           = prlfs_read,
-    .write        = prlfs_write,
+    .read_iter    = prlfs_read_iter,
+    .write_iter = prlfs_write_iter,
     .llseek         = generic_file_llseek,
     .release    = prlfs_release,
     .mmap        = generic_file_mmap,
--
2.24.3 (Apple Git-128)