[PATCH 096/437] mm: convert to read/write iterators

From: Jens Axboe
Date: Thu Apr 11 2024 - 12:01:47 EST


Signed-off-by: Jens Axboe <axboe@xxxxxxxxx>
---
mm/damon/dbgfs.c | 84 ++++++++++++++++++++++++---------------------
mm/huge_memory.c | 10 +++---
mm/kmemleak.c | 5 +--
mm/page_owner.c | 5 +--
mm/shrinker_debug.c | 12 +++----
mm/slub.c | 2 +-
mm/vmscan.c | 14 ++++----
7 files changed, 69 insertions(+), 63 deletions(-)

diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c
index 2461cfe2e968..1ee9d28ded80 100644
--- a/mm/damon/dbgfs.c
+++ b/mm/damon/dbgfs.c
@@ -56,10 +56,9 @@ static char *user_input_str(const char __user *buf, size_t count, loff_t *ppos)
return kbuf;
}

-static ssize_t dbgfs_attrs_read(struct file *file,
- char __user *buf, size_t count, loff_t *ppos)
+static ssize_t dbgfs_attrs_read(struct kiocb *iocb, struct iov_iter *to)
{
- struct damon_ctx *ctx = file->private_data;
+ struct damon_ctx *ctx = iocb->ki_filp->private_data;
char kbuf[128];
int ret;

@@ -70,7 +69,7 @@ static ssize_t dbgfs_attrs_read(struct file *file,
ctx->attrs.min_nr_regions, ctx->attrs.max_nr_regions);
mutex_unlock(&ctx->kdamond_lock);

- return simple_read_from_buffer(buf, count, ppos, kbuf, ret);
+ return simple_copy_to_iter(kbuf, &iocb->ki_pos, ret, to);
}

static ssize_t dbgfs_attrs_write(struct file *file,
@@ -109,6 +108,7 @@ static ssize_t dbgfs_attrs_write(struct file *file,
kfree(kbuf);
return ret;
}
+FOPS_WRITE_ITER_HELPER(dbgfs_attrs_write);

/*
* Return corresponding dbgfs' scheme action value (int) for the given
@@ -169,10 +169,10 @@ static ssize_t sprint_schemes(struct damon_ctx *c, char *buf, ssize_t len)
return written;
}

-static ssize_t dbgfs_schemes_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t dbgfs_schemes_read(struct kiocb *iocb, struct iov_iter *to)
{
- struct damon_ctx *ctx = file->private_data;
+ struct damon_ctx *ctx = iocb->ki_filp->private_data;
+ size_t count = iov_iter_count(to);
char *kbuf;
ssize_t len;

@@ -185,7 +185,7 @@ static ssize_t dbgfs_schemes_read(struct file *file, char __user *buf,
mutex_unlock(&ctx->kdamond_lock);
if (len < 0)
goto out;
- len = simple_read_from_buffer(buf, count, ppos, kbuf, len);
+ len = simple_copy_to_iter(kbuf, &iocb->ki_pos, len, to);

out:
kfree(kbuf);
@@ -329,6 +329,7 @@ static ssize_t dbgfs_schemes_write(struct file *file, const char __user *buf,
kfree(kbuf);
return ret;
}
+FOPS_WRITE_ITER_HELPER(dbgfs_schemes_write);

static ssize_t sprint_target_ids(struct damon_ctx *ctx, char *buf, ssize_t len)
{
@@ -356,10 +357,9 @@ static ssize_t sprint_target_ids(struct damon_ctx *ctx, char *buf, ssize_t len)
return written;
}

-static ssize_t dbgfs_target_ids_read(struct file *file,
- char __user *buf, size_t count, loff_t *ppos)
+static ssize_t dbgfs_target_ids_read(struct kiocb *iocb, struct iov_iter *to)
{
- struct damon_ctx *ctx = file->private_data;
+ struct damon_ctx *ctx = iocb->ki_filp->private_data;
ssize_t len;
char ids_buf[320];

@@ -369,7 +369,7 @@ static ssize_t dbgfs_target_ids_read(struct file *file,
if (len < 0)
return len;

- return simple_read_from_buffer(buf, count, ppos, ids_buf, len);
+ return simple_copy_to_iter(ids_buf, &iocb->ki_pos, len, to);
}

/*
@@ -548,6 +548,7 @@ static ssize_t dbgfs_target_ids_write(struct file *file,
kfree(kbuf);
return ret;
}
+FOPS_WRITE_ITER_HELPER(dbgfs_target_ids_write);

static ssize_t sprint_init_regions(struct damon_ctx *c, char *buf, ssize_t len)
{
@@ -571,10 +572,10 @@ static ssize_t sprint_init_regions(struct damon_ctx *c, char *buf, ssize_t len)
return written;
}

-static ssize_t dbgfs_init_regions_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t dbgfs_init_regions_read(struct kiocb *iocb, struct iov_iter *to)
{
- struct damon_ctx *ctx = file->private_data;
+ struct damon_ctx *ctx = iocb->ki_filp->private_data;
+ size_t count = iov_iter_count(to);
char *kbuf;
ssize_t len;

@@ -593,7 +594,7 @@ static ssize_t dbgfs_init_regions_read(struct file *file, char __user *buf,
mutex_unlock(&ctx->kdamond_lock);
if (len < 0)
goto out;
- len = simple_read_from_buffer(buf, count, ppos, kbuf, len);
+ len = simple_copy_to_iter(kbuf, &iocb->ki_pos, len, to);

out:
kfree(kbuf);
@@ -693,11 +694,12 @@ static ssize_t dbgfs_init_regions_write(struct file *file,
kfree(kbuf);
return ret;
}
+FOPS_WRITE_ITER_HELPER(dbgfs_init_regions_write);

-static ssize_t dbgfs_kdamond_pid_read(struct file *file,
- char __user *buf, size_t count, loff_t *ppos)
+static ssize_t dbgfs_kdamond_pid_read(struct kiocb *iocb, struct iov_iter *to)
{
- struct damon_ctx *ctx = file->private_data;
+ struct damon_ctx *ctx = iocb->ki_filp->private_data;
+ size_t count = iov_iter_count(to);
char *kbuf;
ssize_t len;

@@ -713,7 +715,7 @@ static ssize_t dbgfs_kdamond_pid_read(struct file *file,
mutex_unlock(&ctx->kdamond_lock);
if (!len)
goto out;
- len = simple_read_from_buffer(buf, count, ppos, kbuf, len);
+ len = simple_copy_to_iter(kbuf, &iocb->ki_pos, len, to);

out:
kfree(kbuf);
@@ -731,31 +733,31 @@ static int damon_dbgfs_open(struct inode *inode, struct file *file)

static const struct file_operations attrs_fops = {
.open = damon_dbgfs_open,
- .read = dbgfs_attrs_read,
- .write = dbgfs_attrs_write,
+ .read_iter = dbgfs_attrs_read,
+ .write_iter = dbgfs_attrs_write_iter,
};

static const struct file_operations schemes_fops = {
.open = damon_dbgfs_open,
- .read = dbgfs_schemes_read,
- .write = dbgfs_schemes_write,
+ .read_iter = dbgfs_schemes_read,
+ .write_iter = dbgfs_schemes_write_iter,
};

static const struct file_operations target_ids_fops = {
.open = damon_dbgfs_open,
- .read = dbgfs_target_ids_read,
- .write = dbgfs_target_ids_write,
+ .read_iter = dbgfs_target_ids_read,
+ .write_iter = dbgfs_target_ids_write_iter,
};

static const struct file_operations init_regions_fops = {
.open = damon_dbgfs_open,
- .read = dbgfs_init_regions_read,
- .write = dbgfs_init_regions_write,
+ .read_iter = dbgfs_init_regions_read,
+ .write_iter = dbgfs_init_regions_write_iter,
};

static const struct file_operations kdamond_pid_fops = {
.open = damon_dbgfs_open,
- .read = dbgfs_kdamond_pid_read,
+ .read_iter = dbgfs_kdamond_pid_read,
};

static void dbgfs_fill_ctx_dir(struct dentry *dir, struct damon_ctx *ctx)
@@ -807,12 +809,12 @@ static void dbgfs_destroy_ctx(struct damon_ctx *ctx)
damon_destroy_ctx(ctx);
}

-static ssize_t damon_dbgfs_deprecated_read(struct file *file,
- char __user *buf, size_t count, loff_t *ppos)
+static ssize_t damon_dbgfs_deprecated_read(struct kiocb *iocb,
+ struct iov_iter *to)
{
static const char kbuf[512] = DAMON_DBGFS_DEPRECATION_NOTICE;

- return simple_read_from_buffer(buf, count, ppos, kbuf, strlen(kbuf));
+ return simple_copy_to_iter(kbuf, &iocb->ki_pos, strlen(kbuf), to);
}

/*
@@ -900,6 +902,7 @@ static ssize_t dbgfs_mk_context_write(struct file *file,
kfree(ctx_name);
return ret;
}
+FOPS_WRITE_ITER_HELPER(dbgfs_mk_context_write);

/*
* Remove a context of @name and its debugfs directory.
@@ -1006,9 +1009,9 @@ static ssize_t dbgfs_rm_context_write(struct file *file,
kfree(ctx_name);
return ret;
}
+FOPS_WRITE_ITER_HELPER(dbgfs_rm_context_write);

-static ssize_t dbgfs_monitor_on_read(struct file *file,
- char __user *buf, size_t count, loff_t *ppos)
+static ssize_t dbgfs_monitor_on_read(struct kiocb *iocb, struct iov_iter *to)
{
char monitor_on_buf[5];
bool monitor_on = damon_nr_running_ctxs() != 0;
@@ -1016,7 +1019,7 @@ static ssize_t dbgfs_monitor_on_read(struct file *file,

len = scnprintf(monitor_on_buf, 5, monitor_on ? "on\n" : "off\n");

- return simple_read_from_buffer(buf, count, ppos, monitor_on_buf, len);
+ return simple_copy_to_iter(monitor_on_buf, &iocb->ki_pos, len, to);
}

static ssize_t dbgfs_monitor_on_write(struct file *file,
@@ -1059,6 +1062,7 @@ static ssize_t dbgfs_monitor_on_write(struct file *file,
kfree(kbuf);
return ret;
}
+FOPS_WRITE_ITER_HELPER(dbgfs_monitor_on_write);

static int damon_dbgfs_static_file_open(struct inode *inode, struct file *file)
{
@@ -1067,23 +1071,23 @@ static int damon_dbgfs_static_file_open(struct inode *inode, struct file *file)
}

static const struct file_operations deprecated_fops = {
- .read = damon_dbgfs_deprecated_read,
+ .read_iter = damon_dbgfs_deprecated_read,
};

static const struct file_operations mk_contexts_fops = {
.open = damon_dbgfs_static_file_open,
- .write = dbgfs_mk_context_write,
+ .write_iter = dbgfs_mk_context_write_iter,
};

static const struct file_operations rm_contexts_fops = {
.open = damon_dbgfs_static_file_open,
- .write = dbgfs_rm_context_write,
+ .write_iter = dbgfs_rm_context_write_iter,
};

static const struct file_operations monitor_on_fops = {
.open = damon_dbgfs_static_file_open,
- .read = dbgfs_monitor_on_read,
- .write = dbgfs_monitor_on_write,
+ .read_iter = dbgfs_monitor_on_read,
+ .write_iter = dbgfs_monitor_on_write_iter,
};

static int __init __damon_dbgfs_init(void)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 9859aa4f7553..989847ed0f92 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3582,8 +3582,7 @@ static int split_huge_pages_in_file(const char *file_path, pgoff_t off_start,

#define MAX_INPUT_BUF_SZ 255

-static ssize_t split_huge_pages_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppops)
+static ssize_t split_huge_pages_write(struct kiocb *iocb, struct iov_iter *from)
{
static DEFINE_MUTEX(split_debug_mutex);
ssize_t ret;
@@ -3594,6 +3593,7 @@ static ssize_t split_huge_pages_write(struct file *file, const char __user *buf,
char input_buf[MAX_INPUT_BUF_SZ];
int pid;
unsigned long vaddr_start, vaddr_end;
+ size_t count = iov_iter_count(from);
unsigned int new_order = 0;

ret = mutex_lock_interruptible(&split_debug_mutex);
@@ -3603,7 +3603,8 @@ static ssize_t split_huge_pages_write(struct file *file, const char __user *buf,
ret = -EFAULT;

memset(input_buf, 0, MAX_INPUT_BUF_SZ);
- if (copy_from_user(input_buf, buf, min_t(size_t, count, MAX_INPUT_BUF_SZ)))
+ if (!copy_from_iter_full(input_buf,
+ min_t(size_t, count, MAX_INPUT_BUF_SZ), from))
goto out;

input_buf[MAX_INPUT_BUF_SZ - 1] = '\0';
@@ -3651,12 +3652,11 @@ static ssize_t split_huge_pages_write(struct file *file, const char __user *buf,
out:
mutex_unlock(&split_debug_mutex);
return ret;
-
}

static const struct file_operations split_huge_pages_fops = {
.owner = THIS_MODULE,
- .write = split_huge_pages_write,
+ .write_iter = split_huge_pages_write,
.llseek = no_llseek,
};

diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 6a540c2b27c5..3ff7dc613e70 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -2063,12 +2063,13 @@ static ssize_t kmemleak_write(struct file *file, const char __user *user_buf,
*ppos += size;
return size;
}
+FOPS_WRITE_ITER_HELPER(kmemleak_write);

static const struct file_operations kmemleak_fops = {
.owner = THIS_MODULE,
.open = kmemleak_open,
- .read = seq_read,
- .write = kmemleak_write,
+ .read_iter = seq_read_iter,
+ .write_iter = kmemleak_write_iter,
.llseek = seq_lseek,
.release = seq_release,
};
diff --git a/mm/page_owner.c b/mm/page_owner.c
index d17d1351ec84..ab5cfbc718b4 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -715,6 +715,7 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)

return 0;
}
+FOPS_READ_ITER_HELPER(read_page_owner);

static loff_t lseek_page_owner(struct file *file, loff_t offset, int orig)
{
@@ -822,7 +823,7 @@ static void init_early_allocated_pages(void)
}

static const struct file_operations proc_page_owner_operations = {
- .read = read_page_owner,
+ .read_iter = read_page_owner_iter,
.llseek = lseek_page_owner,
};

@@ -906,7 +907,7 @@ static int page_owner_stack_open(struct inode *inode, struct file *file)

static const struct file_operations page_owner_stack_operations = {
.open = page_owner_stack_open,
- .read = seq_read,
+ .read_iter = seq_read_iter,
.llseek = seq_lseek,
.release = seq_release,
};
diff --git a/mm/shrinker_debug.c b/mm/shrinker_debug.c
index 12ea5486a3e9..b3b4d5a36dc0 100644
--- a/mm/shrinker_debug.c
+++ b/mm/shrinker_debug.c
@@ -101,11 +101,11 @@ static int shrinker_debugfs_scan_open(struct inode *inode, struct file *file)
return nonseekable_open(inode, file);
}

-static ssize_t shrinker_debugfs_scan_write(struct file *file,
- const char __user *buf,
- size_t size, loff_t *pos)
+static ssize_t shrinker_debugfs_scan_write(struct kiocb *iocb,
+ struct iov_iter *from)
{
- struct shrinker *shrinker = file->private_data;
+ struct shrinker *shrinker = iocb->ki_filp->private_data;
+ size_t size = iov_iter_count(from);
unsigned long nr_to_scan = 0, ino, read_len;
struct shrink_control sc = {
.gfp_mask = GFP_KERNEL,
@@ -115,7 +115,7 @@ static ssize_t shrinker_debugfs_scan_write(struct file *file,
char kbuf[72];

read_len = size < (sizeof(kbuf) - 1) ? size : (sizeof(kbuf) - 1);
- if (copy_from_user(kbuf, buf, read_len))
+ if (!copy_from_iter_full(kbuf, read_len, from))
return -EFAULT;
kbuf[read_len] = '\0';

@@ -156,7 +156,7 @@ static ssize_t shrinker_debugfs_scan_write(struct file *file,
static const struct file_operations shrinker_debugfs_scan_fops = {
.owner = THIS_MODULE,
.open = shrinker_debugfs_scan_open,
- .write = shrinker_debugfs_scan_write,
+ .write_iter = shrinker_debugfs_scan_write,
};

int shrinker_debugfs_add(struct shrinker *shrinker)
diff --git a/mm/slub.c b/mm/slub.c
index 1bb2a93cf7b6..aff701599b6a 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -7033,7 +7033,7 @@ static int slab_debug_trace_release(struct inode *inode, struct file *file)

static const struct file_operations slab_debugfs_fops = {
.open = slab_debug_trace_open,
- .read = seq_read,
+ .read_iter = seq_read_iter,
.llseek = seq_lseek,
.release = slab_debug_trace_release,
};
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 3ef654addd44..bf6e9292aea2 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -5278,7 +5278,7 @@ static void lru_gen_seq_show_full(struct seq_file *m, struct lruvec *lruvec,
static int lru_gen_seq_show(struct seq_file *m, void *v)
{
unsigned long seq;
- bool full = !debugfs_real_fops(m->file)->write;
+ bool full = !debugfs_real_fops(m->file)->write_iter;
struct lruvec *lruvec = v;
struct lru_gen_folio *lrugen = &lruvec->lrugen;
int nid = lruvec_pgdat(lruvec)->node_id;
@@ -5434,9 +5434,9 @@ static int run_cmd(char cmd, int memcg_id, int nid, unsigned long seq,
}

/* see Documentation/admin-guide/mm/multigen_lru.rst for details */
-static ssize_t lru_gen_seq_write(struct file *file, const char __user *src,
- size_t len, loff_t *pos)
+static ssize_t lru_gen_seq_write(struct kiocb *iocb, struct iov_iter *from)
{
+ size_t len = iov_iter_count(from);
void *buf;
char *cur, *next;
unsigned int flags;
@@ -5454,7 +5454,7 @@ static ssize_t lru_gen_seq_write(struct file *file, const char __user *src,
if (!buf)
return -ENOMEM;

- if (copy_from_user(buf, src, len)) {
+ if (!copy_from_iter_full(buf, len, from)) {
kvfree(buf);
return -EFAULT;
}
@@ -5513,15 +5513,15 @@ static int lru_gen_seq_open(struct inode *inode, struct file *file)

static const struct file_operations lru_gen_rw_fops = {
.open = lru_gen_seq_open,
- .read = seq_read,
- .write = lru_gen_seq_write,
+ .read_iter = seq_read_iter,
+ .write_iter = lru_gen_seq_write,
.llseek = seq_lseek,
.release = seq_release,
};

static const struct file_operations lru_gen_ro_fops = {
.open = lru_gen_seq_open,
- .read = seq_read,
+ .read_iter = seq_read_iter,
.llseek = seq_lseek,
.release = seq_release,
};
--
2.43.0