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@xxxxxxxxxxxxxxx> --- 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