[PATCH RFC 09/16] seq_file: add seq_preallocate()
From: Christian Brauner
Date: Mon Nov 02 2026 - 10:19:12 EST
single_open_size() allocates the buffer itself because it does the
single_open() too. A file whose seq_file is opened by somebody else,
like procfs does now, needs to do that after the fact. Add
seq_preallocate() for that and use it in single_open_size().
No functional changes.
Signed-off-by: Christian Brauner (Amutable) <brauner@xxxxxxxxxx>
---
fs/seq_file.c | 36 ++++++++++++++++++++++++++++--------
include/linux/seq_file.h | 1 +
2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 456c78719fd0..a4644cdda7e6 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -590,21 +590,41 @@ int single_open(struct file *file, int (*show)(struct seq_file *, void *),
}
EXPORT_SYMBOL(single_open);
-int single_open_size(struct file *file, int (*show)(struct seq_file *, void *),
- void *data, size_t size)
+/**
+ * seq_preallocate - start out with a buffer of @size
+ * @m: the seq_file, before it is first read
+ * @size: the size of the buffer
+ *
+ * For files whose records don't fit into a page, so that the first read
+ * doesn't have to work its way up to the right buffer size.
+ */
+int seq_preallocate(struct seq_file *m, size_t size)
{
char *buf = seq_buf_alloc(size);
- int ret;
+
if (!buf)
return -ENOMEM;
+ kvfree(m->buf);
+ m->buf = buf;
+ m->size = size;
+ return 0;
+}
+EXPORT_SYMBOL(seq_preallocate);
+
+int single_open_size(struct file *file, int (*show)(struct seq_file *, void *),
+ void *data, size_t size)
+{
+ int ret;
+
ret = single_open(file, show, data);
- if (ret) {
- kvfree(buf);
+ if (ret)
return ret;
+ ret = seq_preallocate(file->private_data, size);
+ if (ret) {
+ single_release(file_inode(file), file);
+ file->private_data = NULL;
}
- ((struct seq_file *)file->private_data)->buf = buf;
- ((struct seq_file *)file->private_data)->size = size;
- return 0;
+ return ret;
}
EXPORT_SYMBOL(single_open_size);
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index b813b7e63d89..834daff48b7d 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -175,6 +175,7 @@ int seq_path_root(struct seq_file *m, const struct path *path,
void *single_start(struct seq_file *, loff_t *);
int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
int single_open_size(struct file *, int (*)(struct seq_file *, void *), void *, size_t);
+int seq_preallocate(struct seq_file *m, size_t size);
int single_release(struct inode *, struct file *);
void *__seq_open_private(struct file *, const struct seq_operations *, int);
int seq_open_private(struct file *, const struct seq_operations *, int);
--
2.53.0