lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250210052039.144513-4-me@davidreaver.com>
Date: Sun,  9 Feb 2025 21:20:23 -0800
From: David Reaver <me@...idreaver.com>
To: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
	"Rafael J . Wysocki" <rafael@...nel.org>,
	Danilo Krummrich <dakr@...nel.org>
Cc: David Reaver <me@...idreaver.com>,
	Steven Rostedt <rostedt@...dmis.org>,
	Christian Brauner <brauner@...nel.org>,
	Alexander Viro <viro@...iv.linux.org.uk>,
	linux-fsdevel@...r.kernel.org,
	cocci@...ia.fr,
	linux-kernel@...r.kernel.org
Subject: [RFC PATCH 3/6] relay: Replace dentry with debugfs_node

Although the relay documentation suggests support for multiple filesystems,
in practice all existing users rely on debugfs. This commit updates the
relay API and documentation to use debugfs_node instead of dentry, making
the subsequent migration of relay users to debugfs_node smoother.

Signed-off-by: David Reaver <me@...idreaver.com>
---
 Documentation/filesystems/relay.rst | 32 +++++------
 include/linux/relay.h               | 19 ++++---
 kernel/relay.c                      | 88 ++++++++++++++---------------
 3 files changed, 69 insertions(+), 70 deletions(-)

diff --git a/Documentation/filesystems/relay.rst b/Documentation/filesystems/relay.rst
index 04ad083cfe62..b0ee7dcab8e7 100644
--- a/Documentation/filesystems/relay.rst
+++ b/Documentation/filesystems/relay.rst
@@ -15,8 +15,8 @@ clients write into the channel buffers using efficient write
 functions; these automatically log into the current cpu's channel
 buffer.  User space applications mmap() or read() from the relay files
 and retrieve the data as it becomes available.  The relay files
-themselves are files created in a host filesystem, e.g. debugfs, and
-are associated with the channel buffers using the API described below.
+themselves are files created in debugfs and are associated with the
+channel buffers using the API described below.
 
 The format of the data logged into the channel buffers is completely
 up to the kernel client; the relay interface does however provide
@@ -185,7 +185,7 @@ TBD(curr. line MT:/API/)
     buf_mapped(buf, filp)
     buf_unmapped(buf, filp)
     create_buf_file(filename, parent, mode, buf, is_global)
-    remove_buf_file(dentry)
+    remove_buf_file(node)
 
   helper functions::
 
@@ -203,12 +203,10 @@ read from in user space.  The files are named basename0...basenameN-1
 where N is the number of online cpus, and by default will be created
 in the root of the filesystem (if the parent param is NULL).  If you
 want a directory structure to contain your relay files, you should
-create it using the host filesystem's directory creation function,
-e.g. debugfs_create_dir(), and pass the parent directory to
+create it using debugfs_create_dir(), and pass the parent directory to
 relay_open().  Users are responsible for cleaning up any directory
-structure they create, when the channel is closed - again the host
-filesystem's directory removal functions should be used for that,
-e.g. debugfs_remove().
+structure they create, when the channel is closed with
+debugfs_remove().
 
 In order for a channel to be created and the host filesystem's files
 associated with its channel buffers, the user must provide definitions
@@ -216,7 +214,7 @@ for two callback functions, create_buf_file() and remove_buf_file().
 create_buf_file() is called once for each per-cpu buffer from
 relay_open() and allows the user to create the file which will be used
 to represent the corresponding channel buffer.  The callback should
-return the dentry of the file created to represent the channel buffer.
+return the node of the file created to represent the channel buffer.
 remove_buf_file() must also be defined; it's responsible for deleting
 the file(s) created in create_buf_file() and is called during
 relay_close().
@@ -227,22 +225,22 @@ using debugfs::
     /*
     * create_buf_file() callback.  Creates relay file in debugfs.
     */
-    static struct dentry *create_buf_file_handler(const char *filename,
-						struct dentry *parent,
-						umode_t mode,
-						struct rchan_buf *buf,
-						int *is_global)
+    static struct debugfs_node *create_buf_file_handler(const char *filename,
+							struct debugfs_node *parent,
+							umode_t mode,
+							struct rchan_buf *buf,
+							int *is_global)
     {
 	    return debugfs_create_file(filename, mode, parent, buf,
-				    &relay_file_operations);
+				       &relay_file_operations);
     }
 
     /*
     * remove_buf_file() callback.  Removes relay file from debugfs.
     */
-    static int remove_buf_file_handler(struct dentry *dentry)
+    static int remove_buf_file_handler(struct debugfs_node *node)
     {
-	    debugfs_remove(dentry);
+	    debugfs_remove(node);
 
 	    return 0;
     }
diff --git a/include/linux/relay.h b/include/linux/relay.h
index 72b876dd5cb8..75d5a147ea9e 100644
--- a/include/linux/relay.h
+++ b/include/linux/relay.h
@@ -22,6 +22,7 @@
 #include <linux/poll.h>
 #include <linux/kref.h>
 #include <linux/percpu.h>
+#include <linux/debugfs.h>
 
 /*
  * Tracks changes to rchan/rchan_buf structs
@@ -41,7 +42,7 @@ struct rchan_buf
 	struct rchan *chan;		/* associated channel */
 	wait_queue_head_t read_wait;	/* reader wait queue */
 	struct irq_work wakeup_work;	/* reader wakeup */
-	struct dentry *dentry;		/* channel file dentry */
+	struct debugfs_node *node;	/* channel file node */
 	struct kref kref;		/* channel buffer refcount */
 	struct page **page_array;	/* array of current buffer pages */
 	unsigned int page_count;	/* number of current buffer pages */
@@ -69,7 +70,7 @@ struct rchan
 	struct rchan_buf * __percpu *buf; /* per-cpu channel buffers */
 	int is_global;			/* One global buffer ? */
 	struct list_head list;		/* for channel list */
-	struct dentry *parent;		/* parent dentry passed to open */
+	struct debugfs_node *parent;	/* parent node passed to open */
 	int has_base_filename;		/* has a filename associated? */
 	char base_filename[NAME_MAX];	/* saved base filename */
 };
@@ -117,7 +118,7 @@ struct rchan_callbacks
 	 * created outside of relay, the parent must also exist in
 	 * that filesystem.
 	 *
-	 * The callback should return the dentry of the file created
+	 * The callback should return the debugfs_node of the file created
 	 * to represent the relay buffer.
 	 *
 	 * Setting the is_global outparam to a non-zero value will
@@ -128,15 +129,15 @@ struct rchan_callbacks
 	 *
 	 * See Documentation/filesystems/relay.rst for more info.
 	 */
-	struct dentry *(*create_buf_file)(const char *filename,
-					  struct dentry *parent,
+	struct debugfs_node *(*create_buf_file)(const char *filename,
+					  struct debugfs_node *parent,
 					  umode_t mode,
 					  struct rchan_buf *buf,
 					  int *is_global);
 
 	/*
 	 * remove_buf_file - remove file representing a relay channel buffer
-	 * @dentry: the dentry of the file to remove
+	 * @node: the debugfs_node of the file to remove
 	 *
 	 * Called during relay_close(), once for each per-cpu buffer,
 	 * to allow the client to remove a file used to represent a
@@ -146,7 +147,7 @@ struct rchan_callbacks
 	 *
 	 * This callback is mandatory.
 	 */
-	int (*remove_buf_file)(struct dentry *dentry);
+	int (*remove_buf_file)(struct debugfs_node *node);
 };
 
 /*
@@ -154,14 +155,14 @@ struct rchan_callbacks
  */
 
 struct rchan *relay_open(const char *base_filename,
-			 struct dentry *parent,
+			 struct debugfs_node *parent,
 			 size_t subbuf_size,
 			 size_t n_subbufs,
 			 const struct rchan_callbacks *cb,
 			 void *private_data);
 extern int relay_late_setup_files(struct rchan *chan,
 				  const char *base_filename,
-				  struct dentry *parent);
+				  struct debugfs_node *parent);
 extern void relay_close(struct rchan *chan);
 extern void relay_flush(struct rchan *chan);
 extern void relay_subbufs_consumed(struct rchan *chan,
diff --git a/kernel/relay.c b/kernel/relay.c
index a8ae436dc77e..16cf9098d697 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -337,18 +337,18 @@ void relay_reset(struct rchan *chan)
 }
 EXPORT_SYMBOL_GPL(relay_reset);
 
-static inline void relay_set_buf_dentry(struct rchan_buf *buf,
-					struct dentry *dentry)
+static inline void relay_set_buf_node(struct rchan_buf *buf,
+				      struct debugfs_node *node)
 {
-	buf->dentry = dentry;
-	d_inode(buf->dentry)->i_size = buf->early_bytes;
+	buf->node = node;
+	debugfs_node_inode(buf->node)->i_size = buf->early_bytes;
 }
 
-static struct dentry *relay_create_buf_file(struct rchan *chan,
-					    struct rchan_buf *buf,
-					    unsigned int cpu)
+static struct debugfs_node *relay_create_buf_file(struct rchan *chan,
+						  struct rchan_buf *buf,
+						  unsigned int cpu)
 {
-	struct dentry *dentry;
+	struct debugfs_node *node;
 	char *tmpname;
 
 	tmpname = kzalloc(NAME_MAX + 1, GFP_KERNEL);
@@ -357,15 +357,15 @@ static struct dentry *relay_create_buf_file(struct rchan *chan,
 	snprintf(tmpname, NAME_MAX, "%s%d", chan->base_filename, cpu);
 
 	/* Create file in fs */
-	dentry = chan->cb->create_buf_file(tmpname, chan->parent,
-					   S_IRUSR, buf,
-					   &chan->is_global);
-	if (IS_ERR(dentry))
-		dentry = NULL;
+	node = chan->cb->create_buf_file(tmpname, chan->parent,
+					 S_IRUSR, buf,
+					 &chan->is_global);
+	if (IS_ERR(node))
+		node = NULL;
 
 	kfree(tmpname);
 
-	return dentry;
+	return node;
 }
 
 /*
@@ -376,7 +376,7 @@ static struct dentry *relay_create_buf_file(struct rchan *chan,
 static struct rchan_buf *relay_open_buf(struct rchan *chan, unsigned int cpu)
 {
 	struct rchan_buf *buf;
-	struct dentry *dentry;
+	struct debugfs_node *node;
 
  	if (chan->is_global)
 		return *per_cpu_ptr(chan->buf, 0);
@@ -386,16 +386,16 @@ static struct rchan_buf *relay_open_buf(struct rchan *chan, unsigned int cpu)
 		return NULL;
 
 	if (chan->has_base_filename) {
-		dentry = relay_create_buf_file(chan, buf, cpu);
-		if (!dentry)
+		node = relay_create_buf_file(chan, buf, cpu);
+		if (!node)
 			goto free_buf;
-		relay_set_buf_dentry(buf, dentry);
+		relay_set_buf_node(buf, node);
 	} else {
 		/* Only retrieve global info, nothing more, nothing less */
-		dentry = chan->cb->create_buf_file(NULL, NULL,
-						   S_IRUSR, buf,
-						   &chan->is_global);
-		if (IS_ERR_OR_NULL(dentry))
+		node = chan->cb->create_buf_file(NULL, NULL,
+						 S_IRUSR, buf,
+						 &chan->is_global);
+		if (IS_ERR_OR_NULL(node))
 			goto free_buf;
 	}
 
@@ -426,7 +426,7 @@ static void relay_close_buf(struct rchan_buf *buf)
 {
 	buf->finalized = 1;
 	irq_work_sync(&buf->wakeup_work);
-	buf->chan->cb->remove_buf_file(buf->dentry);
+	buf->chan->cb->remove_buf_file(buf->node);
 	kref_put(&buf->kref, relay_remove_buf);
 }
 
@@ -454,7 +454,7 @@ int relay_prepare_cpu(unsigned int cpu)
 /**
  *	relay_open - create a new relay channel
  *	@base_filename: base name of files to create, %NULL for buffering only
- *	@parent: dentry of parent directory, %NULL for root directory or buffer
+ *	@parent: node of parent directory, %NULL for root directory or buffer
  *	@subbuf_size: size of sub-buffers
  *	@n_subbufs: number of sub-buffers
  *	@cb: client callback functions
@@ -468,11 +468,11 @@ int relay_prepare_cpu(unsigned int cpu)
  *	permissions will be %S_IRUSR.
  *
  *	If opening a buffer (@parent = NULL) that you later wish to register
- *	in a filesystem, call relay_late_setup_files() once the @parent dentry
+ *	in a filesystem, call relay_late_setup_files() once the @parent node
  *	is available.
  */
 struct rchan *relay_open(const char *base_filename,
-			 struct dentry *parent,
+			 struct debugfs_node *parent,
 			 size_t subbuf_size,
 			 size_t n_subbufs,
 			 const struct rchan_callbacks *cb,
@@ -538,40 +538,40 @@ EXPORT_SYMBOL_GPL(relay_open);
 
 struct rchan_percpu_buf_dispatcher {
 	struct rchan_buf *buf;
-	struct dentry *dentry;
+	struct debugfs_node *node;
 };
 
 /* Called in atomic context. */
-static void __relay_set_buf_dentry(void *info)
+static void __relay_set_buf_node(void *info)
 {
 	struct rchan_percpu_buf_dispatcher *p = info;
 
-	relay_set_buf_dentry(p->buf, p->dentry);
+	relay_set_buf_node(p->buf, p->node);
 }
 
 /**
  *	relay_late_setup_files - triggers file creation
  *	@chan: channel to operate on
  *	@base_filename: base name of files to create
- *	@parent: dentry of parent directory, %NULL for root directory
+ *	@parent: node of parent directory, %NULL for root directory
  *
  *	Returns 0 if successful, non-zero otherwise.
  *
  *	Use to setup files for a previously buffer-only channel created
- *	by relay_open() with a NULL parent dentry.
+ *	by relay_open() with a NULL parent node.
  *
  *	For example, this is useful for perfomring early tracing in kernel,
- *	before VFS is up and then exposing the early results once the dentry
+ *	before VFS is up and then exposing the early results once the node
  *	is available.
  */
 int relay_late_setup_files(struct rchan *chan,
 			   const char *base_filename,
-			   struct dentry *parent)
+			   struct debugfs_node *parent)
 {
 	int err = 0;
 	unsigned int i, curr_cpu;
 	unsigned long flags;
-	struct dentry *dentry;
+	struct debugfs_node *node;
 	struct rchan_buf *buf;
 	struct rchan_percpu_buf_dispatcher disp;
 
@@ -593,9 +593,9 @@ int relay_late_setup_files(struct rchan *chan,
 		err = -EINVAL;
 		buf = *per_cpu_ptr(chan->buf, 0);
 		if (!WARN_ON_ONCE(!buf)) {
-			dentry = relay_create_buf_file(chan, buf, 0);
-			if (dentry && !WARN_ON_ONCE(!chan->is_global)) {
-				relay_set_buf_dentry(buf, dentry);
+			node = relay_create_buf_file(chan, buf, 0);
+			if (node && !WARN_ON_ONCE(!chan->is_global)) {
+				relay_set_buf_node(buf, node);
 				err = 0;
 			}
 		}
@@ -617,23 +617,23 @@ int relay_late_setup_files(struct rchan *chan,
 			break;
 		}
 
-		dentry = relay_create_buf_file(chan, buf, i);
-		if (unlikely(!dentry)) {
+		node = relay_create_buf_file(chan, buf, i);
+		if (unlikely(!node)) {
 			err = -EINVAL;
 			break;
 		}
 
 		if (curr_cpu == i) {
 			local_irq_save(flags);
-			relay_set_buf_dentry(buf, dentry);
+			relay_set_buf_node(buf, node);
 			local_irq_restore(flags);
 		} else {
 			disp.buf = buf;
-			disp.dentry = dentry;
+			disp.node = node;
 			smp_mb();
 			/* relay_channels_mutex must be held, so wait. */
 			err = smp_call_function_single(i,
-						       __relay_set_buf_dentry,
+						       __relay_set_buf_node,
 						       &disp, 1);
 		}
 		if (unlikely(err))
@@ -669,8 +669,8 @@ size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length)
 		old_subbuf = buf->subbufs_produced % buf->chan->n_subbufs;
 		buf->padding[old_subbuf] = buf->prev_padding;
 		buf->subbufs_produced++;
-		if (buf->dentry)
-			d_inode(buf->dentry)->i_size +=
+		if (buf->node)
+			debugfs_node_inode(buf->node)->i_size +=
 				buf->chan->subbuf_size -
 				buf->padding[old_subbuf];
 		else

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ