[RFC PATCH 3/6] relay: Replace dentry with debugfs_node

David Reaver posted 6 patches 12 months ago
[RFC PATCH 3/6] relay: Replace dentry with debugfs_node
Posted by David Reaver 12 months ago
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@davidreaver.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