[PATCH 024/437] char/mem: convert to read/write iterators

Jens Axboe
2024-04-11T15:32:10Z

drivers/char/mem.c | 106 ++++++++++++---------------------------------
1 file changed, 27 insertions(+), 79 deletions(-)

diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 3c6670cf905f..00ab09ad98e6 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -183,16 +183,17 @@ static ssize_t read_mem(struct file *file, char __user *buf,
kfree(bounce);
return err;
}
+FOPS_READ_ITER_HELPER(read_mem);

-static ssize_t write_mem(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t write_mem(struct kiocb *iocb, struct iov_iter *from)
{
- phys_addr_t p = *ppos;
+ size_t count = iov_iter_count(from);
+ phys_addr_t p = iocb->ki_pos;
ssize_t written, sz;
unsigned long copied;
void *ptr;

- if (p != *ppos)
+ if (p != iocb->ki_pos)
return -EFBIG;

if (!valid_phys_addr_range(p, count))
@@ -235,7 +236,7 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
return -EFAULT;
}

- copied = copy_from_user(ptr, buf, sz);
+ copied = copy_from_iter(ptr, sz, from);
unxlate_dev_mem_ptr(p, ptr);
if (copied) {
written += sz - copied;
@@ -245,7 +246,6 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
}
}

- buf += sz;
p += sz;
count -= sz;
written += sz;
@@ -253,7 +253,7 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
break;
}

- *ppos += written;
+ iocb->ki_pos += written;
return written;
}

@@ -383,58 +383,39 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma)
return 0;
}

-static ssize_t read_port(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t read_port(struct kiocb *iocb, struct iov_iter *to)
{
- unsigned long i = *ppos;
- char __user *tmp = buf;
+ unsigned long i = iocb->ki_pos, org_i = i;
+ size_t count = iov_iter_count(to);

- if (!access_ok(buf, count))
- return -EFAULT;
while (count-- > 0 && i < 65536) {
- if (__put_user(inb(i), tmp) < 0)
+ char val = inb(i);
+ if (put_iter(val, to))
return -EFAULT;
i++;
- tmp++;
}
- *ppos = i;
- return tmp-buf;
+ iocb->ki_pos = i;
+ return i - org_i;
}

-static ssize_t write_port(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t write_port(struct kiocb *iocb, struct iov_iter *from)
{
- unsigned long i = *ppos;
- const char __user *tmp = buf;
+ unsigned long i = iocb->ki_pos, org_i = i;
+ size_t count = iov_iter_count(from);

- if (!access_ok(buf, count))
- return -EFAULT;
while (count-- > 0 && i < 65536) {
char c;

- if (__get_user(c, tmp)) {
- if (tmp > buf)
+ if (get_iter(c, from)) {
+ if (i != org_i)
break;
return -EFAULT;
}
outb(c, i);
i++;
- tmp++;
}
- *ppos = i;
- return tmp-buf;
-}
-
-static ssize_t read_null(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-
-static ssize_t write_null(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- return count;
+ iocb->ki_pos = i;
+ return i - org_i;
}

static ssize_t read_iter_null(struct kiocb *iocb, struct iov_iter *to)
@@ -490,33 +471,6 @@ static ssize_t read_iter_zero(struct kiocb *iocb, struct iov_iter *iter)
return written;
}

-static ssize_t read_zero(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- size_t cleared = 0;
-
- while (count) {
- size_t chunk = min_t(size_t, count, PAGE_SIZE);
- size_t left;
-
- left = clear_user(buf + cleared, chunk);
- if (unlikely(left)) {
- cleared += (chunk - left);
- if (!cleared)
- return -EFAULT;
- break;
- }
- cleared += chunk;
- count -= chunk;
-
- if (signal_pending(current))
- break;
- cond_resched();
- }
-
- return cleared;
-}
-
static int mmap_zero(struct file *file, struct vm_area_struct *vma)
{
#ifndef CONFIG_MMU
@@ -550,8 +504,7 @@ static unsigned long get_unmapped_area_zero(struct file *file,
#endif
}

-static ssize_t write_full(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t write_full_iter(struct kiocb *iocb, struct iov_iter *from)
{
return -ENOSPC;
}
@@ -626,15 +579,14 @@ static int open_port(struct inode *inode, struct file *filp)

#define zero_lseek null_lseek
#define full_lseek null_lseek
-#define write_zero write_null
#define write_iter_zero write_iter_null
#define splice_write_zero splice_write_null
#define open_mem open_port

static const struct file_operations __maybe_unused mem_fops = {
.llseek = memory_lseek,
- .read = read_mem,
- .write = write_mem,
+ .read_iter = read_mem_iter,
+ .write_iter = write_mem,
.mmap = mmap_mem,
.open = open_mem,
#ifndef CONFIG_MMU
@@ -645,8 +597,6 @@ static const struct file_operations __maybe_unused mem_fops = {

static const struct file_operations null_fops = {
.llseek = null_lseek,
- .read = read_null,
- .write = write_null,
.read_iter = read_iter_null,
.write_iter = write_iter_null,
.splice_write = splice_write_null,
@@ -655,16 +605,14 @@ static const struct file_operations null_fops = {

static const struct file_operations __maybe_unused port_fops = {
.llseek = memory_lseek,
- .read = read_port,
- .write = write_port,
+ .read_iter = read_port,
+ .write_iter = write_port,
.open = open_port,
};

static const struct file_operations zero_fops = {
.llseek = zero_lseek,
- .write = write_zero,
.read_iter = read_iter_zero,
- .read = read_zero,
.write_iter = write_iter_zero,
.splice_read = copy_splice_read,
.splice_write = splice_write_zero,
@@ -678,7 +626,7 @@ static const struct file_operations zero_fops = {
static const struct file_operations full_fops = {
.llseek = full_lseek,
.read_iter = read_iter_zero,
- .write = write_full,
+ .write_iter = write_full_iter,
.splice_read = copy_splice_read,
};

--
2.43.0