[PATCH RFC 4/5] proc: rename ->proc_read() and ->proc_read_iter()

Christian Brauner brauner at kernel.org
Mon Nov 2 07:15:57 PST 2026


Only entries that are never removed may implement ->proc_read() or
->proc_read_iter() now, and PROC_ENTRY_PERMANENT is 0 in modules. But a
module that sets one of them still builds fine and only finds out when
registering its entry fails with a warning.

So rename them to ->proc_permanent_read() and
->proc_permanent_read_iter(). A module that sets one of them doesn't
build anymore and the name says which entries may use them. Hiding the
members from modules behind #ifdef MODULE instead would give modules a
different layout of struct proc_ops than the rest of the kernel.

While at it, rename PROC_ENTRY_proc_read_iter and
pde_has_proc_read_iter() to match.

No functional changes.

Signed-off-by: Christian Brauner (Amutable) <brauner at kernel.org>
---
 fs/proc/generic.c       | 15 +++++++++------
 fs/proc/inode.c         |  9 +++++----
 fs/proc/internal.h      |  5 +++--
 fs/proc/kcore.c         |  2 +-
 fs/proc/kmsg.c          |  2 +-
 fs/proc/page.c          |  6 +++---
 include/linux/proc_fs.h | 10 ++++++----
 kernel/profile.c        |  2 +-
 8 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 7c8def4ed9fc..4bcec5a29b5f 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -444,7 +444,8 @@ static int pde_set_flags(struct proc_dir_entry *pde)
 	if (proc_ops->proc_flags & PROC_ENTRY_PERMANENT)
 		pde->flags |= PROC_ENTRY_PERMANENT;
 	/* These copy to userspace and only an entry that can't go away may. */
-	if (WARN_ON_ONCE((proc_ops->proc_read || proc_ops->proc_read_iter) &&
+	if (WARN_ON_ONCE((proc_ops->proc_permanent_read ||
+			  proc_ops->proc_permanent_read_iter) &&
 			 !pde_is_permanent(pde)))
 		return -EINVAL;
 	if (proc_ops->proc_seq_ops) {
@@ -457,7 +458,8 @@ static int pde_set_flags(struct proc_dir_entry *pde)
 	}
 	if (pde_is_seq_file(pde)) {
 		/* procfs reads and seeks through the seq_file itself */
-		if (WARN_ON_ONCE(proc_ops->proc_read || proc_ops->proc_read_iter ||
+		if (WARN_ON_ONCE(proc_ops->proc_permanent_read ||
+				 proc_ops->proc_permanent_read_iter ||
 				 proc_ops->proc_lseek))
 			return -EINVAL;
 		/* and frees it, see pde_seq_release() */
@@ -467,8 +469,8 @@ static int pde_set_flags(struct proc_dir_entry *pde)
 			return -EINVAL;
 		pde->flags |= PROC_ENTRY_proc_lseek;
 	} else {
-		if (proc_ops->proc_read_iter)
-			pde->flags |= PROC_ENTRY_proc_read_iter;
+		if (proc_ops->proc_permanent_read_iter)
+			pde->flags |= PROC_ENTRY_proc_permanent_read_iter;
 		if (proc_ops->proc_lseek)
 			pde->flags |= PROC_ENTRY_proc_lseek;
 	}
@@ -479,8 +481,9 @@ static int pde_set_flags(struct proc_dir_entry *pde)
 			pde->flags |= PROC_ENTRY_SHORT_WRITES;
 	}
 	if (proc_ops->proc_read_buf) {
-		if (WARN_ON_ONCE(pde_is_seq_file(pde) || proc_ops->proc_read ||
-				 proc_ops->proc_read_iter))
+		if (WARN_ON_ONCE(pde_is_seq_file(pde) ||
+				 proc_ops->proc_permanent_read ||
+				 proc_ops->proc_permanent_read_iter))
 			return -EINVAL;
 		pde->flags |= PROC_ENTRY_proc_read_buf;
 		pde->read_size = proc_ops->proc_read_size ?: PAGE_SIZE;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index a7f8818b0b74..16d8f00bfc26 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -464,7 +464,7 @@ static ssize_t proc_reg_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 	if (pde_has_proc_read_buf(pde))
 		return pde_read_buf(pde, iocb, iter);
 	/* only permanent entries have one, see pde_set_flags() */
-	return pde->proc_ops->proc_read_iter(iocb, iter);
+	return pde->proc_ops->proc_permanent_read_iter(iocb, iter);
 }
 
 static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
@@ -475,9 +475,9 @@ static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count,
 	 * Only permanent entries have one, see pde_set_flags(). Anything else
 	 * might be gone along with its ->proc_ops.
 	 */
-	if (!pde_is_permanent(pde) || !pde->proc_ops->proc_read)
+	if (!pde_is_permanent(pde) || !pde->proc_ops->proc_permanent_read)
 		return -EIO;
-	return pde->proc_ops->proc_read(file, buf, count, ppos);
+	return pde->proc_ops->proc_permanent_read(file, buf, count, ppos);
 }
 
 /*
@@ -880,7 +880,8 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
 		inode->i_op = de->proc_iops;
 		if (pde_is_seq_file(de))
 			inode->i_fop = &proc_seq_file_ops;
-		else if (pde_has_proc_read_iter(de) || pde_has_proc_read_buf(de))
+		else if (pde_has_proc_permanent_read_iter(de) ||
+			 pde_has_proc_read_buf(de))
 			inode->i_fop = &proc_iter_file_ops;
 		else
 			inode->i_fop = &proc_reg_file_ops;
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 93d20995b6fe..f4677815ebfa 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -89,9 +89,10 @@ static inline void pde_make_permanent(struct proc_dir_entry *pde)
 	pde->flags |= PROC_ENTRY_PERMANENT;
 }
 
-static inline bool pde_has_proc_read_iter(const struct proc_dir_entry *pde)
+static inline bool
+pde_has_proc_permanent_read_iter(const struct proc_dir_entry *pde)
 {
-	return pde->flags & PROC_ENTRY_proc_read_iter;
+	return pde->flags & PROC_ENTRY_proc_permanent_read_iter;
 }
 
 static inline bool pde_has_proc_lseek(const struct proc_dir_entry *pde)
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 390547b992ac..5584b2642f2f 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -664,7 +664,7 @@ static int release_kcore(struct inode *inode, struct file *file)
 
 static const struct proc_ops kcore_proc_ops = {
 	.proc_flags	= PROC_ENTRY_PERMANENT,
-	.proc_read_iter	= read_kcore_iter,
+	.proc_permanent_read_iter = read_kcore_iter,
 	.proc_open	= open_kcore,
 	.proc_release	= release_kcore,
 	.proc_lseek	= default_llseek,
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 2fc92a13f9f8..28b40ffccdfb 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -48,7 +48,7 @@ static __poll_t kmsg_poll(struct file *file, poll_table *wait)
 
 static const struct proc_ops kmsg_proc_ops = {
 	.proc_flags	= PROC_ENTRY_PERMANENT,
-	.proc_read	= kmsg_read,
+	.proc_permanent_read = kmsg_read,
 	.proc_poll	= kmsg_poll,
 	.proc_open	= kmsg_open,
 	.proc_release	= kmsg_release,
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 6aa99e42ec22..6a68f392453c 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -133,7 +133,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
 static const struct proc_ops kpagecount_proc_ops = {
 	.proc_flags	= PROC_ENTRY_PERMANENT,
 	.proc_lseek	= mem_lseek,
-	.proc_read	= kpagecount_read,
+	.proc_permanent_read = kpagecount_read,
 };
 
 
@@ -259,7 +259,7 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf,
 static const struct proc_ops kpageflags_proc_ops = {
 	.proc_flags	= PROC_ENTRY_PERMANENT,
 	.proc_lseek	= mem_lseek,
-	.proc_read	= kpageflags_read,
+	.proc_permanent_read = kpageflags_read,
 };
 
 #ifdef CONFIG_MEMCG
@@ -271,7 +271,7 @@ static ssize_t kpagecgroup_read(struct file *file, char __user *buf,
 static const struct proc_ops kpagecgroup_proc_ops = {
 	.proc_flags	= PROC_ENTRY_PERMANENT,
 	.proc_lseek	= mem_lseek,
-	.proc_read	= kpagecgroup_read,
+	.proc_permanent_read = kpagecgroup_read,
 };
 #endif /* CONFIG_MEMCG */
 
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 17516b064922..4db79f1ab97e 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -18,7 +18,8 @@ enum {
 	/*
 	 * All /proc entries using this ->proc_ops instance are never removed.
 	 * procfs calls into them without pinning them, so they may copy to
-	 * userspace themselves through ->proc_read() or ->proc_read_iter().
+	 * userspace themselves through ->proc_permanent_read() or
+	 * ->proc_permanent_read_iter().
 	 *
 	 * If in doubt, ignore this flag.
 	 */
@@ -28,7 +29,7 @@ enum {
 	PROC_ENTRY_PERMANENT		= 1U << 0,
 #endif
 
-	PROC_ENTRY_proc_read_iter	= 1U << 1,
+	PROC_ENTRY_proc_permanent_read_iter = 1U << 1,
 	PROC_ENTRY_proc_lseek		= 1U << 3,
 	PROC_ENTRY_proc_seq_ops		= 1U << 4,
 	PROC_ENTRY_proc_show		= 1U << 5,
@@ -78,8 +79,9 @@ struct proc_ops {
 	 * These two are only for PROC_ENTRY_PERMANENT entries. Everything else
 	 * uses ->proc_read_buf().
 	 */
-	ssize_t	(*proc_read)(struct file *, char __user *, size_t, loff_t *);
-	ssize_t (*proc_read_iter)(struct kiocb *, struct iov_iter *);
+	ssize_t	(*proc_permanent_read)(struct file *, char __user *, size_t,
+				       loff_t *);
+	ssize_t (*proc_permanent_read_iter)(struct kiocb *, struct iov_iter *);
 	/*
 	 * mandatory unless nonseekable_open() or equivalent is used, procfs
 	 * seeks seq_file entries itself
diff --git a/kernel/profile.c b/kernel/profile.c
index 6f2441dd4a00..72e30bb30396 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -207,7 +207,7 @@ static ssize_t write_profile(struct file *file, char *buf, size_t count,
 
 static const struct proc_ops profile_proc_ops = {
 	.proc_flags	= PROC_ENTRY_PERMANENT,
-	.proc_read	= read_profile,
+	.proc_permanent_read = read_profile,
 	.proc_write_buf	= write_profile,
 	.proc_lseek	= default_llseek,
 };

-- 
2.53.0




More information about the linux-um mailing list