linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH DRAFT 0/4] : Port tracefs to kernfs
@ 2024-01-31 13:36 Christian Brauner
  2024-01-31 13:36 ` [PATCH DRAFT 1/4] : tracefs: port " Christian Brauner
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Christian Brauner @ 2024-01-31 13:36 UTC (permalink / raw)
  To: Steven Rostedt, Linus Torvalds, Amir Goldstein,
	Greg Kroah-Hartman
  Cc: lsf-pc, linux-fsdevel, Al Viro, Matthew Wilcox, Christian Brauner

Back in 2022 we already had a session at LSFMM where we talked about
eventfs and we said that it should be based on kernfs and any missing
functionality be implemented in kernfs. Instead we've gotten a
hand-rolled version of similar functionality and 100+ mails exchanges
over the last weeks to fix bugs in there binding people's time.

All we've heard so far were either claims that it would be too difficult
to port tracefs to kernfs or that it somehow wouldn't work but we've
never heard why and it's never been demonstrated why.

So I went and started a draft for porting all of tracefs to kernfs in
the hopes that someone picks this up and finishes the work. I've gotten
the core of it done and it's pretty easy to do logical copy-pasta to
port this to eventfs as well.

I want to see tracefs and eventfs ported to kernfs and get rid of the
hand-rolled implementation. I don't see the value in any additional
talks about why eventfs is special until we've seen an implementation of
tracefs on kernfs.

I'm pretty certain that we have capable people that can and want to
finish the port (I frankly don't have time for this unless I drop all
reviews.). I've started just jotting down the basics yesterday evening
and came to the conclusion that:

* It'll get rid of pointless dentry pinning in various places that is
  currently done in the first place. Instead only a kernfs root and a
  kernfs node need to be stashed. Dentries and inodes are added
  on-demand.

* It'll make _all of_ tracefs capable of on-demand dentry and inode
  creation.

* Quoting [1]:

  > The biggest savings in eventfs is the fact that it has no meta data for
  > files. All the directories in eventfs has a fixed number of files when they
  > are created. The creating of a directory passes in an array that has a list
  > of names and callbacks to call when the file needs to be accessed. Note,
  > this array is static for all events. That is, there's one array for all
  > event files, and one array for all event systems, they are not allocated per
  > directory.

  This is all possible with kernfs.

* All ownership information (mode, uid, gid) is stashed and kept
  kernfs_node->iattrs. So the parent kernfs_node's ownership can be used
  to set the child's ownership information. This will allow to get rid
  of any custom permission checking and ->getattr() and ->setattr()
  calls.

* Private tracefs data that was stashed in inode->i_private is stashed
  in kernfs_node->priv. That's always accessible in kernfs->open() calls
  via kernfs_open_file->kn->priv but it could also be transferred to
  kernfs_open_file->priv. In any case, it makes it a lot easier to
  handle private data than tracefs does it now.

* It'll make maintenance of tracefs easier in the long run because new
  functionality and improvements get added to kernfs including better
  integration with namespaces (I've had patchsets for kernfs a while ago
  to unlock additional namespaces.)

* There's no need for separate i_ops for "instances" and regular tracefs
  directories. Simply compare the stashed kernfs_node of the "instances"
  directory against the current kernfs_node passed to ->mkdir() or
  ->rmdir() whether the directory creation or deletion is allowed.

* Frankly, another big reason to do it is simply maintenance. All of the
  maintenance burden neeeds to be shifted to the generic kernfs
  implementation which is maintained by people familar with filesystem
  details. I'm willing to support it too.

  No shade, but currently I don't see how eventfs can be maintained
  without the involvement of others. Maintainability alone should be a
  sufficient reason to move all of this to kernfs and add any missing
  functionality.

* If we have a session about this at LSFMM and I want to see a POC of
  tracefs and eventfs built on top of kernfs. I'm tired of talking about
  a private implementation of functionality that already exists.
  Otherwise, this is just wasting everyone's time and eventfs as it is
  will not become common infrastructure.

* Yes, debugfs could or should be ported as well but it's almost
  irrelevant for debugfs. It's a debugging filesystem. If you enable it
  on a production workload then you have bigger problems to worry about
  than wasted memory. So I don't consider that urgent. But tracefs is
  causing us headaches right now and I'm weary of cementing a
  hand-rolled implementation.

So really, please let's move this to kernfs, fix any things that aren't
supported in kernfs (I haven't seen any) and get rid of all the custom
functionality. Part of the work is moving tracefs to the new mount api
(which should've been done anyway).

The fs/tracefs/ part already compiles. The rest I haven't finished
converting. All the file_operations need to be moved to kernfs_ops which
shouldn't be too difficult.

To: Steven Rostedt <rostedt@goodmis.org>
To: Linus Torvalds <torvalds@linux-foundation.org>
To: Amir Goldstein <amir73il@gmail.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: lsf-pc@lists.linux-foundation.org,
Cc: linux-fsdevel@vger.kernel.org
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Matthew Wilcox <willy@infradead.org>

Link: https://lore.kernel.org/r/20240129105726.2c2f77f0@gandalf.local.home [1]
Link: https://lore.kernel.org/r/20240129105726.2c2f77f0@gandalf.local.home
---
Christian Brauner (4):
      [DRAFT]: tracefs: port to kernfs
      [DRAFT]: trace: stash kernfs_node instead of dentries
      [DRAFT]: hwlat: port struct file_operations thread_mode_fops to struct kernfs_ops
      [DRAFT]: trace: illustrate how to convert basic open functions

 fs/kernfs/mount.c                 |  10 +
 fs/tracefs/inode.c                | 649 +++++++++++++-------------------------
 include/linux/kernfs.h            |   3 +
 include/linux/tracefs.h           |  18 +-
 kernel/trace/trace.c              |  22 +-
 kernel/trace/trace.h              |   4 +-
 kernel/trace/trace_events_synth.c |   4 +-
 kernel/trace/trace_events_user.c  |   2 +-
 kernel/trace/trace_hwlat.c        |  45 +--
 9 files changed, 270 insertions(+), 487 deletions(-)
---
base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
change-id: 20240131-tracefs-kernfs-3f2def6eab11


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH DRAFT 1/4] : tracefs: port to kernfs
  2024-01-31 13:36 [PATCH DRAFT 0/4] : Port tracefs to kernfs Christian Brauner
@ 2024-01-31 13:36 ` Christian Brauner
  2024-02-01  0:37   ` kernel test robot
                     ` (2 more replies)
  2024-01-31 13:36 ` [PATCH DRAFT 2/4] : trace: stash kernfs_node instead of dentries Christian Brauner
                   ` (4 subsequent siblings)
  5 siblings, 3 replies; 12+ messages in thread
From: Christian Brauner @ 2024-01-31 13:36 UTC (permalink / raw)
  To: Steven Rostedt, Linus Torvalds, Amir Goldstein,
	Greg Kroah-Hartman
  Cc: lsf-pc, linux-fsdevel, Al Viro, Matthew Wilcox, Christian Brauner

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 fs/kernfs/mount.c       |  10 +
 fs/tracefs/inode.c      | 649 ++++++++++++++++--------------------------------
 include/linux/kernfs.h  |   3 +
 include/linux/tracefs.h |  18 +-
 kernel/trace/trace.c    |   6 +-
 5 files changed, 244 insertions(+), 442 deletions(-)

diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c
index 0c93cad0f0ac..68907c9f9377 100644
--- a/fs/kernfs/mount.c
+++ b/fs/kernfs/mount.c
@@ -243,6 +243,16 @@ struct dentry *kernfs_node_dentry(struct kernfs_node *kn,
 	} while (true);
 }
 
+kuid_t kernfs_node_owner(struct kernfs_node *kn)
+{
+	return kn->iattrs->ia_uid;
+}
+
+kuid_t kernfs_node_group(struct kernfs_node *kn)
+{
+	return kn->iattrs->ia_gid;
+}
+
 static int kernfs_fill_super(struct super_block *sb, struct kernfs_fs_context *kfc)
 {
 	struct kernfs_super_info *info = kernfs_info(sb);
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index e1b172c0e091..944a95ff8b48 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/fs_parser.h>
 #include <linux/mount.h>
 #include <linux/kobject.h>
 #include <linux/namei.h>
@@ -24,47 +25,41 @@
 #include "internal.h"
 
 #define TRACEFS_DEFAULT_MODE	0700
-static struct kmem_cache *tracefs_inode_cachep __ro_after_init;
+static struct kernfs_root *trace_fs_root;
+static struct kernfs_node *trace_kfs_root_node;
 
 static struct vfsmount *tracefs_mount;
 static int tracefs_mount_count;
 static bool tracefs_registered;
 
-static struct inode *tracefs_alloc_inode(struct super_block *sb)
+static ssize_t trace_fs_kf_read(struct kernfs_open_file *of, char *buf,
+				size_t count, loff_t pos)
 {
-	struct tracefs_inode *ti;
-
-	ti = kmem_cache_alloc(tracefs_inode_cachep, GFP_KERNEL);
-	if (!ti)
-		return NULL;
-
-	ti->flags = 0;
-
-	return &ti->vfs_inode;
+	return 0;
 }
 
-static void tracefs_free_inode(struct inode *inode)
+static ssize_t trace_fs_kf_write(struct kernfs_open_file *of, char *buf,
+				 size_t count, loff_t pos)
 {
-	kmem_cache_free(tracefs_inode_cachep, get_tracefs(inode));
+	return 0;
 }
 
-static ssize_t default_read_file(struct file *file, char __user *buf,
-				 size_t count, loff_t *ppos)
+static loff_t trace_fs_kf_llseek(struct kernfs_open_file *of, loff_t offset,
+				 int whence)
 {
-	return 0;
+	return noop_llseek(of->file, offset, whence);
 }
 
-static ssize_t default_write_file(struct file *file, const char __user *buf,
-				   size_t count, loff_t *ppos)
+static int trace_fs_kf_open(struct kernfs_open_file *of)
 {
-	return count;
+	return 0;
 }
 
-static const struct file_operations tracefs_file_operations = {
-	.read =		default_read_file,
-	.write =	default_write_file,
-	.open =		simple_open,
-	.llseek =	noop_llseek,
+static const struct kernfs_ops tracefs_file_kfops = {
+	.read		= trace_fs_kf_read,
+	.write		= trace_fs_kf_write,
+	.open		= trace_fs_kf_open,
+	.llseek		= trace_fs_kf_llseek,
 };
 
 static struct tracefs_dir_ops {
@@ -72,157 +67,6 @@ static struct tracefs_dir_ops {
 	int (*rmdir)(const char *name);
 } tracefs_ops __ro_after_init;
 
-static char *get_dname(struct dentry *dentry)
-{
-	const char *dname;
-	char *name;
-	int len = dentry->d_name.len;
-
-	dname = dentry->d_name.name;
-	name = kmalloc(len + 1, GFP_KERNEL);
-	if (!name)
-		return NULL;
-	memcpy(name, dname, len);
-	name[len] = 0;
-	return name;
-}
-
-static int tracefs_syscall_mkdir(struct mnt_idmap *idmap,
-				 struct inode *inode, struct dentry *dentry,
-				 umode_t mode)
-{
-	struct tracefs_inode *ti;
-	char *name;
-	int ret;
-
-	name = get_dname(dentry);
-	if (!name)
-		return -ENOMEM;
-
-	/*
-	 * This is a new directory that does not take the default of
-	 * the rootfs. It becomes the default permissions for all the
-	 * files and directories underneath it.
-	 */
-	ti = get_tracefs(inode);
-	ti->flags |= TRACEFS_INSTANCE_INODE;
-	ti->private = inode;
-
-	/*
-	 * The mkdir call can call the generic functions that create
-	 * the files within the tracefs system. It is up to the individual
-	 * mkdir routine to handle races.
-	 */
-	inode_unlock(inode);
-	ret = tracefs_ops.mkdir(name);
-	inode_lock(inode);
-
-	kfree(name);
-
-	return ret;
-}
-
-static int tracefs_syscall_rmdir(struct inode *inode, struct dentry *dentry)
-{
-	char *name;
-	int ret;
-
-	name = get_dname(dentry);
-	if (!name)
-		return -ENOMEM;
-
-	/*
-	 * The rmdir call can call the generic functions that create
-	 * the files within the tracefs system. It is up to the individual
-	 * rmdir routine to handle races.
-	 * This time we need to unlock not only the parent (inode) but
-	 * also the directory that is being deleted.
-	 */
-	inode_unlock(inode);
-	inode_unlock(d_inode(dentry));
-
-	ret = tracefs_ops.rmdir(name);
-
-	inode_lock_nested(inode, I_MUTEX_PARENT);
-	inode_lock(d_inode(dentry));
-
-	kfree(name);
-
-	return ret;
-}
-
-static void set_tracefs_inode_owner(struct inode *inode)
-{
-	struct tracefs_inode *ti = get_tracefs(inode);
-	struct inode *root_inode = ti->private;
-
-	/*
-	 * If this inode has never been referenced, then update
-	 * the permissions to the superblock.
-	 */
-	if (!(ti->flags & TRACEFS_UID_PERM_SET))
-		inode->i_uid = root_inode->i_uid;
-
-	if (!(ti->flags & TRACEFS_GID_PERM_SET))
-		inode->i_gid = root_inode->i_gid;
-}
-
-static int tracefs_permission(struct mnt_idmap *idmap,
-			      struct inode *inode, int mask)
-{
-	set_tracefs_inode_owner(inode);
-	return generic_permission(idmap, inode, mask);
-}
-
-static int tracefs_getattr(struct mnt_idmap *idmap,
-			   const struct path *path, struct kstat *stat,
-			   u32 request_mask, unsigned int flags)
-{
-	struct inode *inode = d_backing_inode(path->dentry);
-
-	set_tracefs_inode_owner(inode);
-	generic_fillattr(idmap, request_mask, inode, stat);
-	return 0;
-}
-
-static int tracefs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
-			   struct iattr *attr)
-{
-	unsigned int ia_valid = attr->ia_valid;
-	struct inode *inode = d_inode(dentry);
-	struct tracefs_inode *ti = get_tracefs(inode);
-
-	if (ia_valid & ATTR_UID)
-		ti->flags |= TRACEFS_UID_PERM_SET;
-
-	if (ia_valid & ATTR_GID)
-		ti->flags |= TRACEFS_GID_PERM_SET;
-
-	return simple_setattr(idmap, dentry, attr);
-}
-
-static const struct inode_operations tracefs_instance_dir_inode_operations = {
-	.lookup		= simple_lookup,
-	.mkdir		= tracefs_syscall_mkdir,
-	.rmdir		= tracefs_syscall_rmdir,
-	.permission	= tracefs_permission,
-	.getattr	= tracefs_getattr,
-	.setattr	= tracefs_setattr,
-};
-
-static const struct inode_operations tracefs_dir_inode_operations = {
-	.lookup		= simple_lookup,
-	.permission	= tracefs_permission,
-	.getattr	= tracefs_getattr,
-	.setattr	= tracefs_setattr,
-};
-
-static const struct inode_operations tracefs_file_inode_operations = {
-	.permission	= tracefs_permission,
-	.getattr	= tracefs_getattr,
-	.setattr	= tracefs_setattr,
-};
-
 struct inode *tracefs_get_inode(struct super_block *sb)
 {
 	struct inode *inode = new_inode(sb);
@@ -241,80 +85,101 @@ struct tracefs_mount_opts {
 	unsigned int opts;
 };
 
-enum {
+struct tracefs_mount_opts global_opts = {
+	.mode	= TRACEFS_DEFAULT_MODE,
+	.uid	= GLOBAL_ROOT_UID,
+	.gid	= GLOBAL_ROOT_GID,
+	.opts	= 0,
+};
+
+enum trace_fs_param {
 	Opt_uid,
 	Opt_gid,
 	Opt_mode,
-	Opt_err
 };
 
-static const match_table_t tokens = {
-	{Opt_uid, "uid=%u"},
-	{Opt_gid, "gid=%u"},
-	{Opt_mode, "mode=%o"},
-	{Opt_err, NULL}
+static const struct fs_parameter_spec trace_fs_parameters[] = {
+	fsparam_u32   ("gid",		Opt_gid),
+	fsparam_u32oct("mode",		Opt_mode),
+	fsparam_u32   ("uid",		Opt_uid),
+	{}
 };
 
-struct tracefs_fs_info {
+struct trace_fs_context {
+	struct kernfs_fs_context kfc;
 	struct tracefs_mount_opts mount_opts;
 };
 
-static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
+static inline struct trace_fs_context *trace_fc2context(struct fs_context *fc)
 {
-	substring_t args[MAX_OPT_ARGS];
-	int option;
-	int token;
-	kuid_t uid;
-	kgid_t gid;
-	char *p;
-
-	opts->opts = 0;
-	opts->mode = TRACEFS_DEFAULT_MODE;
-
-	while ((p = strsep(&data, ",")) != NULL) {
-		if (!*p)
-			continue;
-
-		token = match_token(p, tokens, args);
-		switch (token) {
-		case Opt_uid:
-			if (match_int(&args[0], &option))
-				return -EINVAL;
-			uid = make_kuid(current_user_ns(), option);
-			if (!uid_valid(uid))
-				return -EINVAL;
-			opts->uid = uid;
-			break;
-		case Opt_gid:
-			if (match_int(&args[0], &option))
-				return -EINVAL;
-			gid = make_kgid(current_user_ns(), option);
-			if (!gid_valid(gid))
-				return -EINVAL;
-			opts->gid = gid;
-			break;
-		case Opt_mode:
-			if (match_octal(&args[0], &option))
-				return -EINVAL;
-			opts->mode = option & S_IALLUGO;
-			break;
+	struct kernfs_fs_context *kfc = fc->fs_private;
+
+	return container_of(kfc, struct trace_fs_context, kfc);
+}
+
+static int trace_fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
+{
+	struct trace_fs_context *ctx = trace_fc2context(fc);
+	struct tracefs_mount_opts *mount_opts = &ctx->mount_opts;
+	struct fs_parse_result result;
+	int opt;
+	kuid_t kuid;
+	kgid_t kgid;
+
+	opt = fs_parse(fc, trace_fs_parameters, param, &result);
+	if (opt < 0)
+		return opt;
+
+	switch (opt) {
+	case Opt_mode:
+		mount_opts->mode = result.uint_32 & 07777;
+		mount_opts->opts |= BIT(Opt_mode);
+		break;
+	case Opt_uid:
+		kuid = make_kuid(current_user_ns(), result.uint_32);
+		if (!uid_valid(kuid))
+			goto bad_value;
+
 		/*
-		 * We might like to report bad mount options here;
-		 * but traditionally tracefs has ignored all mount options
+		 * The requested uid must be representable in the
+		 * filesystem's idmapping.
 		 */
-		}
+		if (!kuid_has_mapping(fc->user_ns, kuid))
+			goto bad_value;
+
+		mount_opts->uid = kuid;
+		mount_opts->opts |= BIT(Opt_uid);
+		break;
+	case Opt_gid:
+		kgid = make_kgid(current_user_ns(), result.uint_32);
+		if (!gid_valid(kgid))
+			goto bad_value;
 
-		opts->opts |= BIT(token);
+		/*
+		 * The requested gid must be representable in the
+		 * filesystem's idmapping.
+		 */
+		if (!kgid_has_mapping(fc->user_ns, kgid))
+			goto bad_value;
+
+		mount_opts->gid = kgid;
+		mount_opts->opts |= BIT(Opt_gid);
+		break;
+	default:
+		return invalfc(fc, "Unsupported parameter '%s'", param->key);
 	}
 
-	return 0;
+bad_value:
+	return invalfc(fc, "Bad value for '%s'", param->key);
 }
 
 static int tracefs_apply_options(struct super_block *sb, bool remount)
 {
-	struct tracefs_fs_info *fsi = sb->s_fs_info;
 	struct inode *inode = d_inode(sb->s_root);
-	struct tracefs_mount_opts *opts = &fsi->mount_opts;
+	kuid_t kuid = global_opts.uid;
+	kgid_t kgid = global_opts.gid;
+	umode_t mode = global_opts.mode;
+	unsigned int opts = global_opts.opts;
 	umode_t tmp_mode;
 
 	/*
@@ -322,126 +187,126 @@ static int tracefs_apply_options(struct super_block *sb, bool remount)
 	 * options.
 	 */
 
-	if (!remount || opts->opts & BIT(Opt_mode)) {
+	if (!remount || opts & BIT(Opt_mode)) {
 		tmp_mode = READ_ONCE(inode->i_mode) & ~S_IALLUGO;
-		tmp_mode |= opts->mode;
+		tmp_mode |= mode;
 		WRITE_ONCE(inode->i_mode, tmp_mode);
 	}
 
-	if (!remount || opts->opts & BIT(Opt_uid))
-		inode->i_uid = opts->uid;
+	if (!remount || opts & BIT(Opt_uid))
+		inode->i_uid = kuid;
 
-	if (!remount || opts->opts & BIT(Opt_gid))
-		inode->i_gid = opts->gid;
+	if (!remount || opts & BIT(Opt_gid))
+		inode->i_gid = kgid;
 
 	return 0;
 }
 
-static int tracefs_remount(struct super_block *sb, int *flags, char *data)
+static int trace_fs_reconfigure(struct fs_context *fc)
 {
-	int err;
-	struct tracefs_fs_info *fsi = sb->s_fs_info;
+	tracefs_apply_options(fc->root->d_sb, true);
+	return 0;
+}
 
-	sync_filesystem(sb);
-	err = tracefs_parse_options(data, &fsi->mount_opts);
-	if (err)
-		goto fail;
+static int trace_fs_show_options(struct seq_file *seq, struct kernfs_root *kf_root)
+{
+	kuid_t kuid = global_opts.uid;
+	kgid_t kgid = global_opts.gid;
+	umode_t mode = global_opts.mode;
 
-	tracefs_apply_options(sb, true);
+	if (!uid_eq(kuid, GLOBAL_ROOT_UID))
+		seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, kuid));
+	if (!gid_eq(kgid, GLOBAL_ROOT_GID))
+		seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, kgid));
+	if (mode != TRACEFS_DEFAULT_MODE)
+		seq_printf(seq, ",mode=%o", mode);
 
-fail:
-	return err;
+	return 0;
 }
 
-static int tracefs_show_options(struct seq_file *m, struct dentry *root)
+static int trace_fs_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode)
 {
-	struct tracefs_fs_info *fsi = root->d_sb->s_fs_info;
-	struct tracefs_mount_opts *opts = &fsi->mount_opts;
-
-	if (!uid_eq(opts->uid, GLOBAL_ROOT_UID))
-		seq_printf(m, ",uid=%u",
-			   from_kuid_munged(&init_user_ns, opts->uid));
-	if (!gid_eq(opts->gid, GLOBAL_ROOT_GID))
-		seq_printf(m, ",gid=%u",
-			   from_kgid_munged(&init_user_ns, opts->gid));
-	if (opts->mode != TRACEFS_DEFAULT_MODE)
-		seq_printf(m, ",mode=%o", opts->mode);
+	int ret;
+	struct kernfs_node *kn;
 
-	return 0;
-}
+	if (parent_kn != trace_instance_dir)
+		return -EPERM;
 
-static const struct super_operations tracefs_super_operations = {
-	.alloc_inode    = tracefs_alloc_inode,
-	.free_inode     = tracefs_free_inode,
-	.drop_inode     = generic_delete_inode,
-	.statfs		= simple_statfs,
-	.remount_fs	= tracefs_remount,
-	.show_options	= tracefs_show_options,
-};
+	kn = tracefs_create_dir(name, parent_kn);
+	if (IS_ERR(kn))
+		return PTR_ERR(kn);
+
+	ret = tracefs_ops.mkdir(name);
+	if (ret)
+		kernfs_remove(kn);
+	return ret;
+}
 
-static void tracefs_dentry_iput(struct dentry *dentry, struct inode *inode)
+static int trace_fs_rmdir(struct kernfs_node *kn)
 {
-	struct tracefs_inode *ti;
+	int ret;
 
-	if (!dentry || !inode)
-		return;
+	if (kn != trace_instance_dir)
+		return -EPERM;
+
+ 	ret = tracefs_ops.rmdir(kn->name);
+	if (!ret)
+		kernfs_remove(kn);
 
-	ti = get_tracefs(inode);
-	if (ti && ti->flags & TRACEFS_EVENT_INODE)
-		eventfs_set_ei_status_free(ti, dentry);
-	iput(inode);
+	return ret;
 }
 
-static const struct dentry_operations tracefs_dentry_operations = {
-	.d_iput = tracefs_dentry_iput,
+static struct kernfs_syscall_ops trace_fs_kf_syscall_ops = {
+	.show_options		= trace_fs_show_options,
+	.mkdir			= trace_fs_mkdir,
+	.rmdir			= trace_fs_rmdir,
 };
 
-static int trace_fill_super(struct super_block *sb, void *data, int silent)
+static int trace_fs_get_tree(struct fs_context *fc)
 {
-	static const struct tree_descr trace_files[] = {{""}};
-	struct tracefs_fs_info *fsi;
-	int err;
-
-	fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL);
-	sb->s_fs_info = fsi;
-	if (!fsi) {
-		err = -ENOMEM;
-		goto fail;
-	}
-
-	err = tracefs_parse_options(data, &fsi->mount_opts);
-	if (err)
-		goto fail;
+	int ret;
 
-	err  =  simple_fill_super(sb, TRACEFS_MAGIC, trace_files);
-	if (err)
-		goto fail;
+	ret = kernfs_get_tree(fc);
+	if (!ret)
+		tracefs_apply_options(fc->root->d_sb, false);
+	return ret;
+}
 
-	sb->s_op = &tracefs_super_operations;
-	sb->s_d_op = &tracefs_dentry_operations;
+static void trace_fs_context_free(struct fs_context *fc)
+{
+	struct trace_fs_context *ctx = trace_fc2context(fc);
+	kernfs_free_fs_context(fc);
+	kfree(ctx);
+}
 
-	tracefs_apply_options(sb, false);
+static const struct fs_context_operations trace_fs_context_ops = {
+	.free		= trace_fs_context_free,
+	.parse_param	= trace_fs_parse_param,
+	.get_tree	= trace_fs_get_tree,
+	.reconfigure	= trace_fs_reconfigure,
+};
 
-	return 0;
+static int trace_fs_init_fs_context(struct fs_context *fc)
+{
+	struct trace_fs_context *ctx;
 
-fail:
-	kfree(fsi);
-	sb->s_fs_info = NULL;
-	return err;
-}
+	ctx = kzalloc(sizeof(struct trace_fs_context), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
 
-static struct dentry *trace_mount(struct file_system_type *fs_type,
-			int flags, const char *dev_name,
-			void *data)
-{
-	return mount_single(fs_type, flags, data, trace_fill_super);
+	ctx->kfc.magic = TRACEFS_MAGIC;
+	ctx->mount_opts.mode = TRACEFS_DEFAULT_MODE;
+	fc->fs_private = &ctx->kfc;
+	fc->global = true;
+	fc->ops = &trace_fs_context_ops;
+	return 0;
 }
 
 static struct file_system_type trace_fs_type = {
-	.owner =	THIS_MODULE,
-	.name =		"tracefs",
-	.mount =	trace_mount,
-	.kill_sb =	kill_litter_super,
+	.name			= "tracefs",
+	.init_fs_context	= trace_fs_init_fs_context,
+	.parameters		= trace_fs_parameters,
+	.kill_sb		= kill_litter_super,
 };
 MODULE_ALIAS_FS("tracefs");
 
@@ -566,26 +431,6 @@ struct dentry *eventfs_end_creating(struct dentry *dentry)
 	return dentry;
 }
 
-/* Find the inode that this will use for default */
-static struct inode *instance_inode(struct dentry *parent, struct inode *inode)
-{
-	struct tracefs_inode *ti;
-
-	/* If parent is NULL then use root inode */
-	if (!parent)
-		return d_inode(inode->i_sb->s_root);
-
-	/* Find the inode that is flagged as an instance or the root inode */
-	while (!IS_ROOT(parent)) {
-		ti = get_tracefs(d_inode(parent));
-		if (ti->flags & TRACEFS_INSTANCE_INODE)
-			break;
-		parent = parent->d_parent;
-	}
-
-	return d_inode(parent);
-}
-
 /**
  * tracefs_create_file - create a file in the tracefs filesystem
  * @name: a pointer to a string containing the name of the file to create.
@@ -612,73 +457,24 @@ static struct inode *instance_inode(struct dentry *parent, struct inode *inode)
  * If tracefs is not enabled in the kernel, the value -%ENODEV will be
  * returned.
  */
-struct dentry *tracefs_create_file(const char *name, umode_t mode,
-				   struct dentry *parent, void *data,
-				   const struct file_operations *fops)
+struct kernfs_node *tracefs_create_file(const char *name, umode_t mode,
+					struct kernfs_node *parent, void *data,
+					const struct kernfs_ops *ops)
 {
-	struct tracefs_inode *ti;
-	struct dentry *dentry;
-	struct inode *inode;
-
 	if (security_locked_down(LOCKDOWN_TRACEFS))
 		return NULL;
 
 	if (!(mode & S_IFMT))
 		mode |= S_IFREG;
 	BUG_ON(!S_ISREG(mode));
-	dentry = tracefs_start_creating(name, parent);
 
-	if (IS_ERR(dentry))
-		return NULL;
+	// inode->i_op = &tracefs_file_inode_operations;
 
-	inode = tracefs_get_inode(dentry->d_sb);
-	if (unlikely(!inode))
-		return tracefs_failed_creating(dentry);
-
-	ti = get_tracefs(inode);
-	ti->private = instance_inode(parent, inode);
-
-	inode->i_mode = mode;
-	inode->i_op = &tracefs_file_inode_operations;
-	inode->i_fop = fops ? fops : &tracefs_file_operations;
-	inode->i_private = data;
-	inode->i_uid = d_inode(dentry->d_parent)->i_uid;
-	inode->i_gid = d_inode(dentry->d_parent)->i_gid;
-	d_instantiate(dentry, inode);
-	fsnotify_create(d_inode(dentry->d_parent), dentry);
-	return tracefs_end_creating(dentry);
-}
-
-static struct dentry *__create_dir(const char *name, struct dentry *parent,
-				   const struct inode_operations *ops)
-{
-	struct tracefs_inode *ti;
-	struct dentry *dentry = tracefs_start_creating(name, parent);
-	struct inode *inode;
-
-	if (IS_ERR(dentry))
-		return NULL;
-
-	inode = tracefs_get_inode(dentry->d_sb);
-	if (unlikely(!inode))
-		return tracefs_failed_creating(dentry);
-
-	/* Do not set bits for OTH */
-	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUSR| S_IRGRP | S_IXUSR | S_IXGRP;
-	inode->i_op = ops;
-	inode->i_fop = &simple_dir_operations;
-	inode->i_uid = d_inode(dentry->d_parent)->i_uid;
-	inode->i_gid = d_inode(dentry->d_parent)->i_gid;
-
-	ti = get_tracefs(inode);
-	ti->private = instance_inode(parent, inode);
-
-	/* directory inodes start off with i_nlink == 2 (for "." entry) */
-	inc_nlink(inode);
-	d_instantiate(dentry, inode);
-	inc_nlink(d_inode(dentry->d_parent));
-	fsnotify_mkdir(d_inode(dentry->d_parent), dentry);
-	return tracefs_end_creating(dentry);
+	return __kernfs_create_file(parent ?: trace_kfs_root_node, name, mode,
+				    kernfs_node_owner(parent),
+				    kernfs_node_group(parent), PAGE_SIZE,
+				    ops ? : &tracefs_file_kfops, data, NULL,
+				    NULL);
 }
 
 /**
@@ -698,12 +494,17 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent,
  * If tracing is not enabled in the kernel, the value -%ENODEV will be
  * returned.
  */
-struct dentry *tracefs_create_dir(const char *name, struct dentry *parent)
+struct kernfs_node *tracefs_create_dir(const char *name,
+				       struct kernfs_node *parent)
 {
 	if (security_locked_down(LOCKDOWN_TRACEFS))
-		return NULL;
+		return ERR_PTR(-EINVAL);
 
-	return __create_dir(name, parent, &tracefs_dir_inode_operations);
+	return kernfs_create_dir_ns(parent ?: trace_kfs_root_node, name,
+				  S_IFDIR | S_IRWXU | S_IRUSR | S_IRGRP |
+				  S_IXUSR | S_IXGRP,
+				  kernfs_node_owner(parent),
+				  kernfs_node_group(parent), NULL, NULL);
 }
 
 /**
@@ -723,30 +524,23 @@ struct dentry *tracefs_create_dir(const char *name, struct dentry *parent)
  *
  * Returns the dentry of the instances directory.
  */
-__init struct dentry *tracefs_create_instance_dir(const char *name,
-					  struct dentry *parent,
-					  int (*mkdir)(const char *name),
-					  int (*rmdir)(const char *name))
+__init struct kernfs_node *
+tracefs_create_instance_dir(int (*mkdir)(const char *name),
+			    int (*rmdir)(const char *name))
 {
-	struct dentry *dentry;
+	struct kernfs_node *kn;
 
 	/* Only allow one instance of the instances directory. */
 	if (WARN_ON(tracefs_ops.mkdir || tracefs_ops.rmdir))
-		return NULL;
+		return ERR_PTR(-EINVAL);
 
-	dentry = __create_dir(name, parent, &tracefs_instance_dir_inode_operations);
-	if (!dentry)
-		return NULL;
+	kn = tracefs_create_dir("instances", trace_kfs_root_node);
+	if (IS_ERR(kn))
+		return kn;
 
 	tracefs_ops.mkdir = mkdir;
 	tracefs_ops.rmdir = rmdir;
-
-	return dentry;
-}
-
-static void remove_one(struct dentry *victim)
-{
-	simple_release_fs(&tracefs_mount, &tracefs_mount_count);
+	return kn;
 }
 
 /**
@@ -757,14 +551,12 @@ static void remove_one(struct dentry *victim)
  * was previously created with a call to another tracefs function
  * (like tracefs_create_file() or variants thereof.)
  */
-void tracefs_remove(struct dentry *dentry)
+void tracefs_remove(struct kernfs_node *kn)
 {
-	if (IS_ERR_OR_NULL(dentry))
+	if (IS_ERR_OR_NULL(kn))
 		return;
 
-	simple_pin_fs(&trace_fs_type, &tracefs_mount, &tracefs_mount_count);
-	simple_recursive_removal(dentry, remove_one);
-	simple_release_fs(&tracefs_mount, &tracefs_mount_count);
+	kernfs_remove(kn);
 }
 
 /**
@@ -775,33 +567,30 @@ bool tracefs_initialized(void)
 	return tracefs_registered;
 }
 
-static void init_once(void *foo)
-{
-	struct tracefs_inode *ti = (struct tracefs_inode *) foo;
-
-	inode_init_once(&ti->vfs_inode);
-}
-
 static int __init tracefs_init(void)
 {
 	int retval;
+	struct kernfs_root *kfs_root;
 
-	tracefs_inode_cachep = kmem_cache_create("tracefs_inode_cache",
-						 sizeof(struct tracefs_inode),
-						 0, (SLAB_RECLAIM_ACCOUNT|
-						     SLAB_MEM_SPREAD|
-						     SLAB_ACCOUNT),
-						 init_once);
-	if (!tracefs_inode_cachep)
-		return -ENOMEM;
+	kfs_root = kernfs_create_root(&trace_fs_kf_syscall_ops,
+				      KERNFS_ROOT_CREATE_DEACTIVATED, NULL);
+	if (IS_ERR(kfs_root))
+                return PTR_ERR(kfs_root);
 
 	retval = sysfs_create_mount_point(kernel_kobj, "tracing");
-	if (retval)
+	if (retval) {
+		kernfs_destroy_root(kfs_root);
 		return -EINVAL;
+	}
 
 	retval = register_filesystem(&trace_fs_type);
 	if (!retval)
 		tracefs_registered = true;
+	else
+		kernfs_destroy_root(kfs_root);
+
+	trace_fs_root = kfs_root;
+	trace_kfs_root_node = kernfs_root_to_node(kfs_root);
 
 	return retval;
 }
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 99aaa050ccb7..50b84a82595f 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -244,6 +244,9 @@ struct kernfs_syscall_ops {
 			 struct kernfs_root *root);
 };
 
+kuid_t kernfs_node_owner(struct kernfs_node *kn);
+kgid_t kernfs_node_group(struct kernfs_node *kn);
+
 struct kernfs_node *kernfs_root_to_node(struct kernfs_root *root);
 
 struct kernfs_open_file {
diff --git a/include/linux/tracefs.h b/include/linux/tracefs.h
index 7a5fe17b6bf9..83f6658e1875 100644
--- a/include/linux/tracefs.h
+++ b/include/linux/tracefs.h
@@ -14,6 +14,7 @@
 
 #include <linux/fs.h>
 #include <linux/seq_file.h>
+#include <linux/kernfs.h>
 
 #include <linux/types.h>
 
@@ -22,6 +23,7 @@ struct file_operations;
 #ifdef CONFIG_TRACING
 
 struct eventfs_file;
+extern struct kernfs_node *trace_instance_dir;
 
 /**
  * eventfs_callback - A callback function to create dynamic files in eventfs
@@ -87,17 +89,17 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode
 void eventfs_remove_events_dir(struct eventfs_inode *ei);
 void eventfs_remove_dir(struct eventfs_inode *ei);
 
-struct dentry *tracefs_create_file(const char *name, umode_t mode,
-				   struct dentry *parent, void *data,
-				   const struct file_operations *fops);
+struct kernfs_node *tracefs_create_file(const char *name, umode_t mode,
+					struct kernfs_node *parent, void *data,
+					const struct kernfs_ops *ops);
 
-struct dentry *tracefs_create_dir(const char *name, struct dentry *parent);
+struct kernfs_node *tracefs_create_dir(const char *name,
+				       struct kernfs_node *parent);
 
-void tracefs_remove(struct dentry *dentry);
+void tracefs_remove(struct kernfs_node *kn);
 
-struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent,
-					   int (*mkdir)(const char *name),
-					   int (*rmdir)(const char *name));
+struct kernfs_node *tracefs_create_instance_dir(int (*mkdir)(const char *name),
+						int (*rmdir)(const char *name));
 
 bool tracefs_initialized(void);
 
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 2a7c6fd934e9..3afc2dd51233 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -9494,7 +9494,7 @@ static const struct file_operations buffer_subbuf_size_fops = {
 	.llseek		= default_llseek,
 };
 
-static struct dentry *trace_instance_dir;
+struct kernfs_node *trace_instance_dir;
 
 static void
 init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer);
@@ -9885,9 +9885,7 @@ static __init void create_trace_instances(struct dentry *d_tracer)
 {
 	struct trace_array *tr;
 
-	trace_instance_dir = tracefs_create_instance_dir("instances", d_tracer,
-							 instance_mkdir,
-							 instance_rmdir);
+	trace_instance_dir = tracefs_create_instance_dir(instance_mkdir, instance_rmdir);
 	if (MEM_FAIL(!trace_instance_dir, "Failed to create instances directory\n"))
 		return;
 

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH DRAFT 2/4] : trace: stash kernfs_node instead of dentries
  2024-01-31 13:36 [PATCH DRAFT 0/4] : Port tracefs to kernfs Christian Brauner
  2024-01-31 13:36 ` [PATCH DRAFT 1/4] : tracefs: port " Christian Brauner
@ 2024-01-31 13:36 ` Christian Brauner
  2024-01-31 13:36 ` [PATCH DRAFT 3/4] : hwlat: port struct file_operations thread_mode_fops to struct kernfs_ops Christian Brauner
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Christian Brauner @ 2024-01-31 13:36 UTC (permalink / raw)
  To: Steven Rostedt, Linus Torvalds, Amir Goldstein,
	Greg Kroah-Hartman
  Cc: lsf-pc, linux-fsdevel, Al Viro, Matthew Wilcox, Christian Brauner

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 kernel/trace/trace_events_synth.c | 4 ++--
 kernel/trace/trace_events_user.c  | 2 +-
 kernel/trace/trace_hwlat.c        | 8 ++++----
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index e7af286af4f1..4fe196effada 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -2312,7 +2312,7 @@ core_initcall(trace_events_synth_init_early);
 
 static __init int trace_events_synth_init(void)
 {
-	struct dentry *entry = NULL;
+	struct kernfs_node *entry = NULL;
 	int err = 0;
 	err = tracing_init_dentry();
 	if (err)
@@ -2320,7 +2320,7 @@ static __init int trace_events_synth_init(void)
 
 	entry = tracefs_create_file("synthetic_events", TRACE_MODE_WRITE,
 				    NULL, NULL, &synth_events_fops);
-	if (!entry) {
+	if (IS_ERR(entry)) {
 		err = -ENODEV;
 		goto err;
 	}
diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
index e76f5e1efdf2..d461b2c5bd41 100644
--- a/kernel/trace/trace_events_user.c
+++ b/kernel/trace/trace_events_user.c
@@ -2698,7 +2698,7 @@ static const struct file_operations user_status_fops = {
  */
 static int create_user_tracefs(void)
 {
-	struct dentry *edata, *emmap;
+	struct kernfs_node *edata, *emmap;
 
 	edata = tracefs_create_file("user_events_data", TRACE_MODE_WRITE,
 				    NULL, NULL, &user_data_fops);
diff --git a/kernel/trace/trace_hwlat.c b/kernel/trace/trace_hwlat.c
index b791524a6536..11b9f98b8d75 100644
--- a/kernel/trace/trace_hwlat.c
+++ b/kernel/trace/trace_hwlat.c
@@ -54,9 +54,9 @@ static struct trace_array	*hwlat_trace;
 #define DEFAULT_SAMPLE_WIDTH	500000			/* 0.5s */
 #define DEFAULT_LAT_THRESHOLD	10			/* 10us */
 
-static struct dentry *hwlat_sample_width;	/* sample width us */
-static struct dentry *hwlat_sample_window;	/* sample window us */
-static struct dentry *hwlat_thread_mode;	/* hwlat thread mode */
+static struct kernfs_node *hwlat_sample_width;	/* sample width us */
+static struct kernfs_node *hwlat_sample_window;	/* sample window us */
+static struct kernfs_node *hwlat_thread_mode;	/* hwlat thread mode */
 
 enum {
 	MODE_NONE = 0,
@@ -769,7 +769,7 @@ static const struct file_operations thread_mode_fops = {
 static int init_tracefs(void)
 {
 	int ret;
-	struct dentry *top_dir;
+	struct kernfs_node *top_dir;
 
 	ret = tracing_init_dentry();
 	if (ret)

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH DRAFT 3/4] : hwlat: port struct file_operations thread_mode_fops to struct kernfs_ops
  2024-01-31 13:36 [PATCH DRAFT 0/4] : Port tracefs to kernfs Christian Brauner
  2024-01-31 13:36 ` [PATCH DRAFT 1/4] : tracefs: port " Christian Brauner
  2024-01-31 13:36 ` [PATCH DRAFT 2/4] : trace: stash kernfs_node instead of dentries Christian Brauner
@ 2024-01-31 13:36 ` Christian Brauner
  2024-02-01  3:30   ` kernel test robot
  2024-01-31 13:36 ` [PATCH DRAFT 4/4] : trace: illustrate how to convert basic open functions Christian Brauner
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Christian Brauner @ 2024-01-31 13:36 UTC (permalink / raw)
  To: Steven Rostedt, Linus Torvalds, Amir Goldstein,
	Greg Kroah-Hartman
  Cc: lsf-pc, linux-fsdevel, Al Viro, Matthew Wilcox, Christian Brauner

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 kernel/trace/trace_hwlat.c | 37 +++++++++----------------------------
 1 file changed, 9 insertions(+), 28 deletions(-)

diff --git a/kernel/trace/trace_hwlat.c b/kernel/trace/trace_hwlat.c
index 11b9f98b8d75..97f118575816 100644
--- a/kernel/trace/trace_hwlat.c
+++ b/kernel/trace/trace_hwlat.c
@@ -647,25 +647,12 @@ static void s_mode_stop(struct seq_file *s, void *v)
 	mutex_unlock(&hwlat_data.lock);
 }
 
-static const struct seq_operations thread_mode_seq_ops = {
-	.start		= s_mode_start,
-	.next		= s_mode_next,
-	.show		= s_mode_show,
-	.stop		= s_mode_stop
-};
-
-static int hwlat_mode_open(struct inode *inode, struct file *file)
-{
-	return seq_open(file, &thread_mode_seq_ops);
-};
-
 static void hwlat_tracer_start(struct trace_array *tr);
 static void hwlat_tracer_stop(struct trace_array *tr);
 
 /**
  * hwlat_mode_write - Write function for "mode" entry
  * @filp: The active open file structure
- * @ubuf: The user buffer that contains the value to write
  * @cnt: The maximum number of bytes to write to "file"
  * @ppos: The current position in @file
  *
@@ -677,8 +664,8 @@ static void hwlat_tracer_stop(struct trace_array *tr);
  * among the allowed CPUs in a round-robin fashion. The "per-cpu" mode
  * creates one hwlatd thread per allowed CPU.
  */
-static ssize_t hwlat_mode_write(struct file *filp, const char __user *ubuf,
-				 size_t cnt, loff_t *ppos)
+static ssize_t hwlat_mode_write(struct kernfs_open_file *of, char *buf,
+				size_t cnt, loff_t ppos)
 {
 	struct trace_array *tr = hwlat_trace;
 	const char *mode;
@@ -688,9 +675,6 @@ static ssize_t hwlat_mode_write(struct file *filp, const char __user *ubuf,
 	if (cnt >= sizeof(buf))
 		return -EINVAL;
 
-	if (copy_from_user(buf, ubuf, cnt))
-		return -EFAULT;
-
 	buf[cnt] = 0;
 
 	mode = strstrip(buf);
@@ -720,10 +704,6 @@ static ssize_t hwlat_mode_write(struct file *filp, const char __user *ubuf,
 		hwlat_tracer_start(tr);
 	mutex_unlock(&trace_types_lock);
 
-	*ppos += cnt;
-
-
-
 	return ret;
 }
 
@@ -751,12 +731,13 @@ static struct trace_min_max_param hwlat_window = {
 	.min		= &hwlat_data.sample_width,
 };
 
-static const struct file_operations thread_mode_fops = {
-	.open		= hwlat_mode_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= seq_release,
-	.write		= hwlat_mode_write
+static const struct kernfs_ops thread_mode_fops = {
+	.atomic_write_len	= PAGE_SIZE,
+	.start			= s_mode_start,
+	.next			= s_mode_next,
+	.show			= s_mode_show,
+	.stop			= s_mode_stop,
+	.write			= hwlat_mode_write,
 };
 /**
  * init_tracefs - A function to initialize the tracefs interface files

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH DRAFT 4/4] : trace: illustrate how to convert basic open functions
  2024-01-31 13:36 [PATCH DRAFT 0/4] : Port tracefs to kernfs Christian Brauner
                   ` (2 preceding siblings ...)
  2024-01-31 13:36 ` [PATCH DRAFT 3/4] : hwlat: port struct file_operations thread_mode_fops to struct kernfs_ops Christian Brauner
@ 2024-01-31 13:36 ` Christian Brauner
  2024-01-31 14:41 ` [PATCH DRAFT 0/4] : Port tracefs to kernfs Steven Rostedt
  2024-01-31 14:59 ` James Bottomley
  5 siblings, 0 replies; 12+ messages in thread
From: Christian Brauner @ 2024-01-31 13:36 UTC (permalink / raw)
  To: Steven Rostedt, Linus Torvalds, Amir Goldstein,
	Greg Kroah-Hartman
  Cc: lsf-pc, linux-fsdevel, Al Viro, Matthew Wilcox, Christian Brauner

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 kernel/trace/trace.c | 16 ++++++++--------
 kernel/trace/trace.h |  4 ++--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 3afc2dd51233..b700feada3e0 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4913,7 +4913,7 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot)
 	return ERR_PTR(-ENOMEM);
 }
 
-int tracing_open_generic(struct inode *inode, struct file *filp)
+int tracing_open_generic(struct kernfs_open_file *of)
 {
 	int ret;
 
@@ -4921,7 +4921,7 @@ int tracing_open_generic(struct inode *inode, struct file *filp)
 	if (ret)
 		return ret;
 
-	filp->private_data = inode->i_private;
+	of->priv = of->kn->priv;
 	return 0;
 }
 
@@ -4934,17 +4934,16 @@ bool tracing_is_disabled(void)
  * Open and update trace_array ref count.
  * Must have the current trace_array passed to it.
  */
-int tracing_open_generic_tr(struct inode *inode, struct file *filp)
+int tracing_open_generic_tr(struct kernfs_open_file *of)
 {
-	struct trace_array *tr = inode->i_private;
+	struct trace_array *tr = of->kn->priv;
 	int ret;
 
 	ret = tracing_check_open_get_tr(tr);
 	if (ret)
 		return ret;
 
-	filp->private_data = inode->i_private;
-
+	of->priv = of->kn->priv;
 	return 0;
 }
 
@@ -5057,9 +5056,10 @@ static int tracing_single_release_tr(struct inode *inode, struct file *file)
 	return single_release(inode, file);
 }
 
-static int tracing_open(struct inode *inode, struct file *file)
+static int tracing_open(struct kernfs_open_file *of)
 {
-	struct trace_array *tr = inode->i_private;
+	struct trace_array *tr = of->kn->priv;
+	struct file *filp = of->file;
 	struct trace_iterator *iter;
 	int ret;
 
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 00f873910c5d..d91420a6c2e8 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -614,8 +614,8 @@ int tracing_is_enabled(void);
 void tracing_reset_online_cpus(struct array_buffer *buf);
 void tracing_reset_all_online_cpus(void);
 void tracing_reset_all_online_cpus_unlocked(void);
-int tracing_open_generic(struct inode *inode, struct file *filp);
-int tracing_open_generic_tr(struct inode *inode, struct file *filp);
+int tracing_open_generic(struct kernfs_open_file *of);
+int tracing_open_generic_tr(struct kernfs_open_file *of);
 int tracing_release_generic_tr(struct inode *inode, struct file *file);
 int tracing_open_file_tr(struct inode *inode, struct file *filp);
 int tracing_release_file_tr(struct inode *inode, struct file *filp);

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH DRAFT 0/4] : Port tracefs to kernfs
  2024-01-31 13:36 [PATCH DRAFT 0/4] : Port tracefs to kernfs Christian Brauner
                   ` (3 preceding siblings ...)
  2024-01-31 13:36 ` [PATCH DRAFT 4/4] : trace: illustrate how to convert basic open functions Christian Brauner
@ 2024-01-31 14:41 ` Steven Rostedt
  2024-01-31 15:28   ` Steven Rostedt
  2024-01-31 14:59 ` James Bottomley
  5 siblings, 1 reply; 12+ messages in thread
From: Steven Rostedt @ 2024-01-31 14:41 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Linus Torvalds, Amir Goldstein, Greg Kroah-Hartman, lsf-pc,
	linux-fsdevel, Al Viro, Matthew Wilcox

On Wed, 31 Jan 2024 14:36:37 +0100
Christian Brauner <brauner@kernel.org> wrote:

> Back in 2022 we already had a session at LSFMM where we talked about
> eventfs and we said that it should be based on kernfs and any missing
> functionality be implemented in kernfs. Instead we've gotten a
> hand-rolled version of similar functionality and 100+ mails exchanges
> over the last weeks to fix bugs in there binding people's time.

Note, tracefs was written way before that. This was only about eventfs.

> 
> All we've heard so far were either claims that it would be too difficult
> to port tracefs to kernfs or that it somehow wouldn't work but we've
> never heard why and it's never been demonstrated why.

Well, because mainly lack of documentation.

> 
> So I went and started a draft for porting all of tracefs to kernfs in
> the hopes that someone picks this up and finishes the work. I've gotten
> the core of it done and it's pretty easy to do logical copy-pasta to
> port this to eventfs as well.

tracefs yes, but I'm not so sure about eventfs.

> 
> I want to see tracefs and eventfs ported to kernfs and get rid of the
> hand-rolled implementation. I don't see the value in any additional
> talks about why eventfs is special until we've seen an implementation of
> tracefs on kernfs.
> 
> I'm pretty certain that we have capable people that can and want to
> finish the port (I frankly don't have time for this unless I drop all
> reviews.). I've started just jotting down the basics yesterday evening
> and came to the conclusion that:

I don't have the time either. But if someone else wants to, I'm fine with
that. I was supposed to be done with my eventfs work by December. It's
almost already February. It put me behind so much I worked throughout the
entire time between Christmas and New Years, including the weekends :-p, I
haven't stopped and I'm really starting to feel burnt.

All I ask is to keep the requirement in eventfs not to allocate anything
for files on creation (see below).

> 
> * It'll get rid of pointless dentry pinning in various places that is
>   currently done in the first place. Instead only a kernfs root and a
>   kernfs node need to be stashed. Dentries and inodes are added
>   on-demand.
> 
> * It'll make _all of_ tracefs capable of on-demand dentry and inode
>   creation.
> 
> * Quoting [1]:
> 
>   > The biggest savings in eventfs is the fact that it has no meta data for
>   > files. All the directories in eventfs has a fixed number of files when they
>   > are created. The creating of a directory passes in an array that has a list
>   > of names and callbacks to call when the file needs to be accessed. Note,
>   > this array is static for all events. That is, there's one array for all
>   > event files, and one array for all event systems, they are not allocated per
>   > directory.  
> 
>   This is all possible with kernfs.

Is it? Let me explain how eventfs files are created, and then you can tell
me how to do this with kernfs. Maybe it is possible.

There's only three types of directories in eventfs.

1) the "events" directory. This is the top node and is created in
   /sys/kernel/tracing/events as well as in /sys/kernel/tracing/instances/<instance>/events

2) The system directory. This is the events/<system>

3) The event directory. This is the events/<system>/<event>

Each of these directories have the exact same files for their type. For the
"events" directory at the top instance, or each created instance, it has
the same files (although they all have different state). All <system>
directories have the same files, and all the <event> directories have the
same files.

When one of these directories is created, it is passed a static array that
contains the name and a callback function for each of these files. That
means, for the three types of directories, there is only three arrays that
represent all files in eventfs.

Let's look at the events directory:

	ei = eventfs_create_dir(name, e_events, event_entries, nr_entries, file);

Where it passes the "name" of the event directory, the parent eventfs_inode
(e_events), a static array of the files within this directory
(event_entries) along with he size of that array (nr_entries), and finally
it passes the default data for all of the files (file) that is passed to
the callbacks and the callbacks can override the data to add to the
inode->i_private.

Let's look at that event_entries:

	static struct eventfs_entry event_entries[] = {
		{
			.name		= "enable",
			.callback	= event_callback,
		},
		{
			.name		= "filter",
			.callback	= event_callback,
		},
		{
			.name		= "trigger",
			.callback	= event_callback,
		},
		{
			.name		= "format",
			.callback	= event_callback,
		},
#ifdef CONFIG_PERF_EVENTS
		{
			.name		= "id",
			.callback	= event_callback,
		},
#endif
#ifdef CONFIG_HIST_TRIGGERS
		{
			.name		= "hist",
			.callback	= event_callback,
		},
#endif
#ifdef CONFIG_HIST_TRIGGERS_DEBUG
		{
			.name		= "hist_debug",
			.callback	= event_callback,
		},
#endif
#ifdef CONFIG_TRACE_EVENT_INJECT
		{
			.name		= "inject",
			.callback	= event_callback,
		},
#endif
	};

Notice the "static" in front. That means, *all* event directories use the
same array. There is zero allocation for any file within each of these
directories. The only exception for allocation is if the attrs change. Then
we need to allocate an array in the directory to handle that. But that too
is only allocated when referenced.

And there's a lot of those directories:

  # ls -d events/*/* |wc -l
2212

The dentry and inode are only created on lookup in the lookup code:

	for (int i = 0; i < ei->nr_entries; i++) {
		void *data;
		umode_t mode;
		const struct file_operations *fops;
		const struct eventfs_entry *entry = &ei->entries[i];

		if (strcmp(name, entry->name) != 0)
			continue;

		data = ei->data;
		if (entry->callback(name, &mode, &data, &fops) <= 0)
			goto enoent;

		result = lookup_file_dentry(dentry, ei, i, mode, data, fops);
		goto out;
	}

The ei represents the events directory (or a system directory or even the
"events" directory). It loops that static array looking for a matching
name (if needed, I have thought about requiring it to be sorted, to do a
binary search instead). If it finds one, it then calls the callback
function, as some event directories do not have all the files, the callback
can inform the lookup that "no, this directory doesn't get this file". For
example, the internal ftrace events (like what is used for function
tracing) doesn't have an "enable" or "filter" file as you can't enable
those events, the callback will inform the lookup about that.

	if (!(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) {
		if (call->class->reg && strcmp(name, "enable") == 0) {
			*mode = TRACE_MODE_WRITE;
			*fops = &ftrace_enable_fops;
			return 1;
		}

		if (strcmp(name, "filter") == 0) {
			*mode = TRACE_MODE_WRITE;
			*fops = &ftrace_event_filter_fops;
			return 1;
		}
	}
	[..]
	return 0;

 # ls events/sched/sched_switch/
enable  filter  format  hist  hist_debug  id  inject  trigge

 # ls events/ftrace/function/
format  hist  hist_debug  id  inject

My point being, that eventfs doesn't allocate any resources for the files.
Well, you could say it does allocate the ei->entries pointer that points to
the static array.

tracefs has tracefs_create_file() but evenfs does not. What is the
equivalent to that in kernfs?

  # ls -d events/*/*/* |wc -l
15819

I do not want to allocate 15 thousand kernfs_node's for this.

Perhaps kernfs has a way to do the same, or maybe it's trivial to make it
do it? I don't know.

> 
> * All ownership information (mode, uid, gid) is stashed and kept
>   kernfs_node->iattrs. So the parent kernfs_node's ownership can be used
>   to set the child's ownership information. This will allow to get rid
>   of any custom permission checking and ->getattr() and ->setattr()
>   calls.
> 
> * Private tracefs data that was stashed in inode->i_private is stashed
>   in kernfs_node->priv. That's always accessible in kernfs->open() calls
>   via kernfs_open_file->kn->priv but it could also be transferred to
>   kernfs_open_file->priv. In any case, it makes it a lot easier to
>   handle private data than tracefs does it now.
> 
> * It'll make maintenance of tracefs easier in the long run because new
>   functionality and improvements get added to kernfs including better
>   integration with namespaces (I've had patchsets for kernfs a while ago
>   to unlock additional namespaces.)
> 
> * There's no need for separate i_ops for "instances" and regular tracefs
>   directories. Simply compare the stashed kernfs_node of the "instances"
>   directory against the current kernfs_node passed to ->mkdir() or
>   ->rmdir() whether the directory creation or deletion is allowed.  
> 
> * Frankly, another big reason to do it is simply maintenance. All of the
>   maintenance burden neeeds to be shifted to the generic kernfs
>   implementation which is maintained by people familar with filesystem
>   details. I'm willing to support it too.
> 
>   No shade, but currently I don't see how eventfs can be maintained
>   without the involvement of others. Maintainability alone should be a
>   sufficient reason to move all of this to kernfs and add any missing
>   functionality.
> 
> * If we have a session about this at LSFMM and I want to see a POC of
>   tracefs and eventfs built on top of kernfs. I'm tired of talking about
>   a private implementation of functionality that already exists.
>   Otherwise, this is just wasting everyone's time and eventfs as it is
>   will not become common infrastructure.

That was never the point. I believe the point was how do we make it easier
to not have this situation happen again. I don't want eventfs to be the
standard way of doing things. I'm looking at this as more of a post-mortem
session than "let's do it this way" one.

-- Steve

> 
> * Yes, debugfs could or should be ported as well but it's almost
>   irrelevant for debugfs. It's a debugging filesystem. If you enable it
>   on a production workload then you have bigger problems to worry about
>   than wasted memory. So I don't consider that urgent. But tracefs is
>   causing us headaches right now and I'm weary of cementing a
>   hand-rolled implementation.
> 
> So really, please let's move this to kernfs, fix any things that aren't
> supported in kernfs (I haven't seen any) and get rid of all the custom
> functionality. Part of the work is moving tracefs to the new mount api
> (which should've been done anyway).
> 
> The fs/tracefs/ part already compiles. The rest I haven't finished
> converting. All the file_operations need to be moved to kernfs_ops which
> shouldn't be too difficult.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH DRAFT 0/4] : Port tracefs to kernfs
  2024-01-31 13:36 [PATCH DRAFT 0/4] : Port tracefs to kernfs Christian Brauner
                   ` (4 preceding siblings ...)
  2024-01-31 14:41 ` [PATCH DRAFT 0/4] : Port tracefs to kernfs Steven Rostedt
@ 2024-01-31 14:59 ` James Bottomley
  5 siblings, 0 replies; 12+ messages in thread
From: James Bottomley @ 2024-01-31 14:59 UTC (permalink / raw)
  To: Christian Brauner, Steven Rostedt, Linus Torvalds, Amir Goldstein,
	Greg Kroah-Hartman
  Cc: lsf-pc, linux-fsdevel, Al Viro, Matthew Wilcox

On Wed, 2024-01-31 at 14:36 +0100, Christian Brauner wrote:
> * If we have a session about this at LSFMM and I want to see a POC of
>   tracefs and eventfs built on top of kernfs. I'm tired of talking
> about
>   a private implementation of functionality that already exists.
>   Otherwise, this is just wasting everyone's time and eventfs as it
> is
>   will not become common infrastructure.

Note: I asked for this to be updated to be a "how do we prevent this
happening again" type session.  I believe you took this as "the VFS is
insufficiently documented" but that wasn't my intent.  There's clearly
something missing that should give people looking to do filesystems
like this a clear direction on how to start, where to look and what vfs
properties are required, which properties break some tools if not
implemented (which may or may not be important to the use case) and
which are nice to have.  When I did shiftfs, my biggest problem was
actually getting configfs to work for it due to being unable to operate
without a superblock, so learning all the VFS intricacies came in
second to that.  I did think at the time I should do a talk more
focussed on what I learned about the basics of the VFS for psuedo
filesystems, but that got lost in the need to push shiftfs itself. 
After that most of my subsequent talks were about extending configfs
because that was the area I had the most problems ...

James


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH DRAFT 0/4] : Port tracefs to kernfs
  2024-01-31 14:41 ` [PATCH DRAFT 0/4] : Port tracefs to kernfs Steven Rostedt
@ 2024-01-31 15:28   ` Steven Rostedt
  0 siblings, 0 replies; 12+ messages in thread
From: Steven Rostedt @ 2024-01-31 15:28 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Linus Torvalds, Amir Goldstein, Greg Kroah-Hartman, lsf-pc,
	linux-fsdevel, Al Viro, Matthew Wilcox

On Wed, 31 Jan 2024 09:41:17 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:

> > So I went and started a draft for porting all of tracefs to kernfs in
> > the hopes that someone picks this up and finishes the work. I've gotten
> > the core of it done and it's pretty easy to do logical copy-pasta to
> > port this to eventfs as well.  
> 
> tracefs yes, but I'm not so sure about eventfs.

BTW, I do want to thank you for doing this. I would *love* to have
tracefs switched over to kernfs. Unfortunately, I have no time to do
it. I also don't want to lose the memory savings that is done in
eventfs.

Even if kernfs couldn't do what is needed in eventfs, I'd still be
happy if just the tracefs portion was converted over to kernfs, as long
as it treated the eventfs the same as tracefs does today.

I never really wanted to be the tracefs/eventfs maintainer. I just
needed the interface for tracing. The more generic code it can use, the
better. This is why I'm ecstatic for the simplification changes that
Linus is making.

-- Steve

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH DRAFT 1/4] : tracefs: port to kernfs
  2024-01-31 13:36 ` [PATCH DRAFT 1/4] : tracefs: port " Christian Brauner
  2024-02-01  0:37   ` kernel test robot
@ 2024-02-01  0:37   ` kernel test robot
  2024-02-01  7:01   ` kernel test robot
  2 siblings, 0 replies; 12+ messages in thread
From: kernel test robot @ 2024-02-01  0:37 UTC (permalink / raw)
  To: Christian Brauner, Steven Rostedt, Linus Torvalds, Amir Goldstein,
	Greg Kroah-Hartman
  Cc: oe-kbuild-all, LKML, lsf-pc, linux-fsdevel, Al Viro,
	Matthew Wilcox, Christian Brauner

Hi Christian,

kernel test robot noticed the following build errors:

[auto build test ERROR on 41bccc98fb7931d63d03f326a746ac4d429c1dd3]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Brauner/tracefs-port-to-kernfs/20240131-214120
base:   41bccc98fb7931d63d03f326a746ac4d429c1dd3
patch link:    https://lore.kernel.org/r/20240131-tracefs-kernfs-v1-1-f20e2e9a8d61%40kernel.org
patch subject: [PATCH DRAFT 1/4] : tracefs: port to kernfs
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20240201/202402010828.cl2RunjG-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240201/202402010828.cl2RunjG-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402010828.cl2RunjG-lkp@intel.com/

All errors (new ones prefixed by >>):

   fs/kernfs/mount.c: In function 'kernfs_node_owner':
>> fs/kernfs/mount.c:248:20: error: 'struct kernfs_node' has no member named 'iattrs'; did you mean 'iattr'?
     248 |         return kn->iattrs->ia_uid;
         |                    ^~~~~~
         |                    iattr
   fs/kernfs/mount.c: At top level:
>> fs/kernfs/mount.c:251:8: error: conflicting types for 'kernfs_node_group'; have 'kuid_t(struct kernfs_node *)'
     251 | kuid_t kernfs_node_group(struct kernfs_node *kn)
         |        ^~~~~~~~~~~~~~~~~
   In file included from fs/kernfs/kernfs-internal.h:19,
                    from fs/kernfs/mount.c:22:
   include/linux/kernfs.h:248:8: note: previous declaration of 'kernfs_node_group' with type 'kgid_t(struct kernfs_node *)'
     248 | kgid_t kernfs_node_group(struct kernfs_node *kn);
         |        ^~~~~~~~~~~~~~~~~
   fs/kernfs/mount.c: In function 'kernfs_node_group':
   fs/kernfs/mount.c:253:20: error: 'struct kernfs_node' has no member named 'iattrs'; did you mean 'iattr'?
     253 |         return kn->iattrs->ia_gid;
         |                    ^~~~~~
         |                    iattr
   fs/kernfs/mount.c: In function 'kernfs_node_owner':
   fs/kernfs/mount.c:249:1: warning: control reaches end of non-void function [-Wreturn-type]
     249 | }
         | ^
   fs/kernfs/mount.c: In function 'kernfs_node_group':
   fs/kernfs/mount.c:254:1: warning: control reaches end of non-void function [-Wreturn-type]
     254 | }
         | ^
--
   kernel/trace/trace.c: In function 'tracing_dentry_percpu':
>> kernel/trace/trace.c:8916:56: error: passing argument 2 of 'tracefs_create_dir' from incompatible pointer type [-Werror=incompatible-pointer-types]
    8916 |         tr->percpu_dir = tracefs_create_dir("per_cpu", d_tracer);
         |                                                        ^~~~~~~~
         |                                                        |
         |                                                        struct dentry *
   In file included from kernel/trace/trace.c:24:
   include/linux/tracefs.h:97:60: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      97 |                                        struct kernfs_node *parent);
         |                                        ~~~~~~~~~~~~~~~~~~~~^~~~~~
>> kernel/trace/trace.c:8916:24: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    8916 |         tr->percpu_dir = tracefs_create_dir("per_cpu", d_tracer);
         |                        ^
   kernel/trace/trace.c: In function 'tracing_init_tracefs_percpu':
   kernel/trace/trace.c:8946:45: error: passing argument 2 of 'tracefs_create_dir' from incompatible pointer type [-Werror=incompatible-pointer-types]
    8946 |         d_cpu = tracefs_create_dir(cpu_dir, d_percpu);
         |                                             ^~~~~~~~
         |                                             |
         |                                             struct dentry *
   include/linux/tracefs.h:97:60: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      97 |                                        struct kernfs_node *parent);
         |                                        ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace.c:8946:15: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    8946 |         d_cpu = tracefs_create_dir(cpu_dir, d_percpu);
         |               ^
   kernel/trace/trace.c: In function 'trace_create_file':
>> kernel/trace/trace.c:9156:47: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    9156 |         ret = tracefs_create_file(name, mode, parent, data, fops);
         |                                               ^~~~~~
         |                                               |
         |                                               struct dentry *
   include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      93 |                                         struct kernfs_node *parent, void *data,
         |                                         ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace.c:9156:61: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    9156 |         ret = tracefs_create_file(name, mode, parent, data, fops);
         |                                                             ^~~~
         |                                                             |
         |                                                             const struct file_operations *
   include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *'
      94 |                                         const struct kernfs_ops *ops);
         |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
   kernel/trace/trace.c:9156:13: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    9156 |         ret = tracefs_create_file(name, mode, parent, data, fops);
         |             ^
   kernel/trace/trace.c: In function 'trace_options_init_dentry':
   kernel/trace/trace.c:9175:53: error: passing argument 2 of 'tracefs_create_dir' from incompatible pointer type [-Werror=incompatible-pointer-types]
    9175 |         tr->options = tracefs_create_dir("options", d_tracer);
         |                                                     ^~~~~~~~
         |                                                     |
         |                                                     struct dentry *
   include/linux/tracefs.h:97:60: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      97 |                                        struct kernfs_node *parent);
         |                                        ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace.c:9175:21: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    9175 |         tr->options = tracefs_create_dir("options", d_tracer);
         |                     ^
   kernel/trace/trace.c: In function 'trace_array_create_dir':
   kernel/trace/trace.c:9631:17: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    9631 |         tr->dir = tracefs_create_dir(tr->name, trace_instance_dir);
         |                 ^
>> kernel/trace/trace.c:9637:34: error: passing argument 1 of 'tracefs_remove' from incompatible pointer type [-Werror=incompatible-pointer-types]
    9637 |                 tracefs_remove(tr->dir);
         |                                ~~^~~~~
         |                                  |
         |                                  struct dentry *
   include/linux/tracefs.h:99:41: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      99 | void tracefs_remove(struct kernfs_node *kn);
         |                     ~~~~~~~~~~~~~~~~~~~~^~
   kernel/trace/trace.c: In function '__remove_instance':
   kernel/trace/trace.c:9818:26: error: passing argument 1 of 'tracefs_remove' from incompatible pointer type [-Werror=incompatible-pointer-types]
    9818 |         tracefs_remove(tr->dir);
         |                        ~~^~~~~
         |                          |
         |                          struct dentry *
   include/linux/tracefs.h:99:41: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      99 | void tracefs_remove(struct kernfs_node *kn);
         |                     ~~~~~~~~~~~~~~~~~~~~^~
   cc1: some warnings being treated as errors
--
   kernel/trace/trace_stat.c: In function 'destroy_session':
>> kernel/trace/trace_stat.c:69:31: error: passing argument 1 of 'tracefs_remove' from incompatible pointer type [-Werror=incompatible-pointer-types]
      69 |         tracefs_remove(session->file);
         |                        ~~~~~~~^~~~~~
         |                               |
         |                               struct dentry *
   In file included from kernel/trace/trace_stat.c:16:
   include/linux/tracefs.h:99:41: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      99 | void tracefs_remove(struct kernfs_node *kn);
         |                     ~~~~~~~~~~~~~~~~~~~~^~
   kernel/trace/trace_stat.c: In function 'tracing_stat_init':
>> kernel/trace/trace_stat.c:285:18: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
     285 |         stat_dir = tracefs_create_dir("trace_stat", NULL);
         |                  ^
   kernel/trace/trace_stat.c: In function 'init_stat_file':
>> kernel/trace/trace_stat.c:301:45: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
     301 |                                             stat_dir, session,
         |                                             ^~~~~~~~
         |                                             |
         |                                             struct dentry *
   include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      93 |                                         struct kernfs_node *parent, void *data,
         |                                         ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace_stat.c:302:45: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
     302 |                                             &tracing_stat_fops);
         |                                             ^~~~~~~~~~~~~~~~~~
         |                                             |
         |                                             const struct file_operations *
   include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *'
      94 |                                         const struct kernfs_ops *ops);
         |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
   kernel/trace/trace_stat.c:300:23: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
     300 |         session->file = tracefs_create_file(session->ts->name, TRACE_MODE_WRITE,
         |                       ^
   cc1: some warnings being treated as errors
--
   kernel/trace/trace_events_synth.c: In function 'trace_events_synth_init':
>> kernel/trace/trace_events_synth.c:2322:49: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2322 |                                     NULL, NULL, &synth_events_fops);
         |                                                 ^~~~~~~~~~~~~~~~~~
         |                                                 |
         |                                                 const struct file_operations *
   In file included from kernel/trace/trace_events_synth.c:15:
   include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *'
      94 |                                         const struct kernfs_ops *ops);
         |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
   kernel/trace/trace_events_synth.c:2321:15: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    2321 |         entry = tracefs_create_file("synthetic_events", TRACE_MODE_WRITE,
         |               ^
   cc1: some warnings being treated as errors


vim +248 fs/kernfs/mount.c

   245	
   246	kuid_t kernfs_node_owner(struct kernfs_node *kn)
   247	{
 > 248		return kn->iattrs->ia_uid;
   249	}
   250	
 > 251	kuid_t kernfs_node_group(struct kernfs_node *kn)
   252	{
   253		return kn->iattrs->ia_gid;
   254	}
   255	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH DRAFT 1/4] : tracefs: port to kernfs
  2024-01-31 13:36 ` [PATCH DRAFT 1/4] : tracefs: port " Christian Brauner
@ 2024-02-01  0:37   ` kernel test robot
  2024-02-01  0:37   ` kernel test robot
  2024-02-01  7:01   ` kernel test robot
  2 siblings, 0 replies; 12+ messages in thread
From: kernel test robot @ 2024-02-01  0:37 UTC (permalink / raw)
  To: Christian Brauner, Steven Rostedt, Linus Torvalds, Amir Goldstein,
	Greg Kroah-Hartman
  Cc: oe-kbuild-all, LKML, lsf-pc, linux-fsdevel, Al Viro,
	Matthew Wilcox, Christian Brauner

Hi Christian,

kernel test robot noticed the following build errors:

[auto build test ERROR on 41bccc98fb7931d63d03f326a746ac4d429c1dd3]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Brauner/tracefs-port-to-kernfs/20240131-214120
base:   41bccc98fb7931d63d03f326a746ac4d429c1dd3
patch link:    https://lore.kernel.org/r/20240131-tracefs-kernfs-v1-1-f20e2e9a8d61%40kernel.org
patch subject: [PATCH DRAFT 1/4] : tracefs: port to kernfs
config: arc-randconfig-001-20240201 (https://download.01.org/0day-ci/archive/20240201/202402010834.J85Qu3eN-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240201/202402010834.J85Qu3eN-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402010834.J85Qu3eN-lkp@intel.com/

All errors (new ones prefixed by >>):

   kernel/trace/trace_hwlat.c: In function 'init_tracefs':
   kernel/trace/trace_hwlat.c:778:17: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
     778 |         top_dir = tracefs_create_dir("hwlat_detector", NULL);
         |                 ^
>> kernel/trace/trace_hwlat.c:783:51: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
     783 |                                                   top_dir,
         |                                                   ^~~~~~~
         |                                                   |
         |                                                   struct dentry *
   In file included from kernel/trace/trace_hwlat.c:41:
   include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      93 |                                         struct kernfs_node *parent, void *data,
         |                                         ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace_hwlat.c:785:51: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
     785 |                                                   &trace_min_max_fops);
         |                                                   ^~~~~~~~~~~~~~~~~~~
         |                                                   |
         |                                                   const struct file_operations *
   include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *'
      94 |                                         const struct kernfs_ops *ops);
         |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
   kernel/trace/trace_hwlat.c:782:29: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
     782 |         hwlat_sample_window = tracefs_create_file("window", TRACE_MODE_WRITE,
         |                             ^
   kernel/trace/trace_hwlat.c:790:50: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
     790 |                                                  top_dir,
         |                                                  ^~~~~~~
         |                                                  |
         |                                                  struct dentry *
   include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      93 |                                         struct kernfs_node *parent, void *data,
         |                                         ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace_hwlat.c:792:50: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
     792 |                                                  &trace_min_max_fops);
         |                                                  ^~~~~~~~~~~~~~~~~~~
         |                                                  |
         |                                                  const struct file_operations *
   include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *'
      94 |                                         const struct kernfs_ops *ops);
         |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
   kernel/trace/trace_hwlat.c:789:28: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
     789 |         hwlat_sample_width = tracefs_create_file("width", TRACE_MODE_WRITE,
         |                            ^
   kernel/trace/trace_hwlat.c:806:24: error: passing argument 1 of 'tracefs_remove' from incompatible pointer type [-Werror=incompatible-pointer-types]
     806 |         tracefs_remove(top_dir);
         |                        ^~~~~~~
         |                        |
         |                        struct dentry *
   include/linux/tracefs.h:99:41: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      99 | void tracefs_remove(struct kernfs_node *kn);
         |                     ~~~~~~~~~~~~~~~~~~~~^~
   cc1: some warnings being treated as errors
--
   kernel/trace/trace_osnoise.c: In function 'init_timerlat_stack_tracefs':
   kernel/trace/trace_osnoise.c:2695:68: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2695 |         tmp = tracefs_create_file("print_stack", TRACE_MODE_WRITE, top_dir,
         |                                                                    ^~~~~~~
         |                                                                    |
         |                                                                    struct dentry *
   In file included from kernel/trace/trace_osnoise.c:20:
   include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      93 |                                         struct kernfs_node *parent, void *data,
         |                                         ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace_osnoise.c:2696:57: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2696 |                                   &osnoise_print_stack, &trace_min_max_fops);
         |                                                         ^~~~~~~~~~~~~~~~~~~
         |                                                         |
         |                                                         const struct file_operations *
   include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *'
      94 |                                         const struct kernfs_ops *ops);
         |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
   kernel/trace/trace_osnoise.c:2695:13: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    2695 |         tmp = tracefs_create_file("print_stack", TRACE_MODE_WRITE, top_dir,
         |             ^
   kernel/trace/trace_osnoise.c: In function 'osnoise_create_cpu_timerlat_fd':
>> kernel/trace/trace_osnoise.c:2723:49: error: passing argument 2 of 'tracefs_create_dir' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2723 |         per_cpu = tracefs_create_dir("per_cpu", top_dir);
         |                                                 ^~~~~~~
         |                                                 |
         |                                                 struct dentry *
   include/linux/tracefs.h:97:60: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      97 |                                        struct kernfs_node *parent);
         |                                        ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace_osnoise.c:2723:17: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    2723 |         per_cpu = tracefs_create_dir("per_cpu", top_dir);
         |                 ^
   kernel/trace/trace_osnoise.c:2729:55: error: passing argument 2 of 'tracefs_create_dir' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2729 |                 cpu_dir = tracefs_create_dir(cpu_str, per_cpu);
         |                                                       ^~~~~~~
         |                                                       |
         |                                                       struct dentry *
   include/linux/tracefs.h:97:60: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      97 |                                        struct kernfs_node *parent);
         |                                        ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace_osnoise.c:2729:25: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    2729 |                 cpu_dir = tracefs_create_dir(cpu_str, per_cpu);
         |                         ^
   kernel/trace/trace_osnoise.c:2745:24: error: passing argument 1 of 'tracefs_remove' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2745 |         tracefs_remove(per_cpu);
         |                        ^~~~~~~
         |                        |
         |                        struct dentry *
   include/linux/tracefs.h:99:41: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      99 | void tracefs_remove(struct kernfs_node *kn);
         |                     ~~~~~~~~~~~~~~~~~~~~^~
   kernel/trace/trace_osnoise.c: In function 'init_timerlat_tracefs':
   kernel/trace/trace_osnoise.c:2757:75: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2757 |         tmp = tracefs_create_file("timerlat_period_us", TRACE_MODE_WRITE, top_dir,
         |                                                                           ^~~~~~~
         |                                                                           |
         |                                                                           struct dentry *
   include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      93 |                                         struct kernfs_node *parent, void *data,
         |                                         ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace_osnoise.c:2758:53: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2758 |                                   &timerlat_period, &trace_min_max_fops);
         |                                                     ^~~~~~~~~~~~~~~~~~~
         |                                                     |
         |                                                     const struct file_operations *
   include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *'
      94 |                                         const struct kernfs_ops *ops);
         |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
   kernel/trace/trace_osnoise.c:2757:13: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    2757 |         tmp = tracefs_create_file("timerlat_period_us", TRACE_MODE_WRITE, top_dir,
         |             ^
   kernel/trace/trace_osnoise.c: In function 'init_tracefs':
   kernel/trace/trace_osnoise.c:2792:17: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    2792 |         top_dir = tracefs_create_dir("osnoise", NULL);
         |                 ^
   kernel/trace/trace_osnoise.c:2796:66: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2796 |         tmp = tracefs_create_file("period_us", TRACE_MODE_WRITE, top_dir,
         |                                                                  ^~~~~~~
         |                                                                  |
         |                                                                  struct dentry *
   include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      93 |                                         struct kernfs_node *parent, void *data,
         |                                         ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace_osnoise.c:2797:52: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2797 |                                   &osnoise_period, &trace_min_max_fops);
         |                                                    ^~~~~~~~~~~~~~~~~~~
         |                                                    |
         |                                                    const struct file_operations *
   include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *'
      94 |                                         const struct kernfs_ops *ops);
         |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
   kernel/trace/trace_osnoise.c:2796:13: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    2796 |         tmp = tracefs_create_file("period_us", TRACE_MODE_WRITE, top_dir,
         |             ^
   kernel/trace/trace_osnoise.c:2801:67: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2801 |         tmp = tracefs_create_file("runtime_us", TRACE_MODE_WRITE, top_dir,
         |                                                                   ^~~~~~~
         |                                                                   |
         |                                                                   struct dentry *
   include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      93 |                                         struct kernfs_node *parent, void *data,
         |                                         ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace_osnoise.c:2802:53: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2802 |                                   &osnoise_runtime, &trace_min_max_fops);
         |                                                     ^~~~~~~~~~~~~~~~~~~
         |                                                     |
         |                                                     const struct file_operations *
   include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *'
      94 |                                         const struct kernfs_ops *ops);
         |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
   kernel/trace/trace_osnoise.c:2801:13: error: assignment to 'struct dentry *' from incompatible pointer type 'struct kernfs_node *' [-Werror=incompatible-pointer-types]
    2801 |         tmp = tracefs_create_file("runtime_us", TRACE_MODE_WRITE, top_dir,
         |             ^
   kernel/trace/trace_osnoise.c:2806:72: error: passing argument 3 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
    2806 |         tmp = tracefs_create_file("stop_tracing_us", TRACE_MODE_WRITE, top_dir,
         |                                                                        ^~~~~~~
         |                                                                        |
         |                                                                        struct dentry *
   include/linux/tracefs.h:93:61: note: expected 'struct kernfs_node *' but argument is of type 'struct dentry *'
      93 |                                         struct kernfs_node *parent, void *data,
         |                                         ~~~~~~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace_osnoise.c:2807:61: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]


vim +/tracefs_create_file +783 kernel/trace/trace_hwlat.c

e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  753) 
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  754  static const struct file_operations thread_mode_fops = {
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  755  	.open		= hwlat_mode_open,
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  756  	.read		= seq_read,
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  757  	.llseek		= seq_lseek,
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  758  	.release	= seq_release,
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  759  	.write		= hwlat_mode_write
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  760  };
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  761) /**
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  762)  * init_tracefs - A function to initialize the tracefs interface files
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  763)  *
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  764)  * This function creates entries in tracefs for "hwlat_detector".
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  765)  * It creates the hwlat_detector directory in the tracing directory,
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  766)  * and within that directory is the count, width and window files to
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  767)  * change and view those values.
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  768)  */
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  769) static int init_tracefs(void)
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  770) {
22c36b18263426 Wei Yang                   2020-07-12  771  	int ret;
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  772) 	struct dentry *top_dir;
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  773) 
22c36b18263426 Wei Yang                   2020-07-12  774  	ret = tracing_init_dentry();
22c36b18263426 Wei Yang                   2020-07-12  775  	if (ret)
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  776) 		return -ENOMEM;
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  777) 
22c36b18263426 Wei Yang                   2020-07-12  778  	top_dir = tracefs_create_dir("hwlat_detector", NULL);
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  779) 	if (!top_dir)
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  780) 		return -ENOMEM;
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  781) 
21ccc9cd721162 Steven Rostedt (VMware     2021-08-18  782) 	hwlat_sample_window = tracefs_create_file("window", TRACE_MODE_WRITE,
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23 @783) 						  top_dir,
f27a1c9e1ba1e4 Daniel Bristot de Oliveira 2021-06-22  784  						  &hwlat_window,
f27a1c9e1ba1e4 Daniel Bristot de Oliveira 2021-06-22  785  						  &trace_min_max_fops);
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  786) 	if (!hwlat_sample_window)
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  787) 		goto err;
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  788) 
21ccc9cd721162 Steven Rostedt (VMware     2021-08-18  789) 	hwlat_sample_width = tracefs_create_file("width", TRACE_MODE_WRITE,
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  790) 						 top_dir,
f27a1c9e1ba1e4 Daniel Bristot de Oliveira 2021-06-22  791  						 &hwlat_width,
f27a1c9e1ba1e4 Daniel Bristot de Oliveira 2021-06-22  792  						 &trace_min_max_fops);
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  793) 	if (!hwlat_sample_width)
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  794) 		goto err;
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  795) 
21ccc9cd721162 Steven Rostedt (VMware     2021-08-18  796) 	hwlat_thread_mode = trace_create_file("mode", TRACE_MODE_WRITE,
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  797  					      top_dir,
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  798  					      NULL,
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  799  					      &thread_mode_fops);
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  800  	if (!hwlat_thread_mode)
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  801  		goto err;
8fa826b7344d67 Daniel Bristot de Oliveira 2021-06-22  802  
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  803) 	return 0;
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  804) 
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  805)  err:
a3d1e7eb5abe3a Al Viro                    2019-11-18  806  	tracefs_remove(top_dir);
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  807) 	return -ENOMEM;
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  808) }
e7c15cd8a11333 Steven Rostedt (Red Hat    2016-06-23  809) 

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH DRAFT 3/4] : hwlat: port struct file_operations thread_mode_fops to struct kernfs_ops
  2024-01-31 13:36 ` [PATCH DRAFT 3/4] : hwlat: port struct file_operations thread_mode_fops to struct kernfs_ops Christian Brauner
@ 2024-02-01  3:30   ` kernel test robot
  0 siblings, 0 replies; 12+ messages in thread
From: kernel test robot @ 2024-02-01  3:30 UTC (permalink / raw)
  To: Christian Brauner, Steven Rostedt, Linus Torvalds, Amir Goldstein,
	Greg Kroah-Hartman
  Cc: oe-kbuild-all, LKML, lsf-pc, linux-fsdevel, Al Viro,
	Matthew Wilcox, Christian Brauner

Hi Christian,

kernel test robot noticed the following build errors:

[auto build test ERROR on 41bccc98fb7931d63d03f326a746ac4d429c1dd3]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Brauner/tracefs-port-to-kernfs/20240131-214120
base:   41bccc98fb7931d63d03f326a746ac4d429c1dd3
patch link:    https://lore.kernel.org/r/20240131-tracefs-kernfs-v1-3-f20e2e9a8d61%40kernel.org
patch subject: [PATCH DRAFT 3/4] : hwlat: port struct file_operations thread_mode_fops to struct kernfs_ops
config: x86_64-rhel-8.3 (https://download.01.org/0day-ci/archive/20240201/202402011108.V2Y9QaTk-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240201/202402011108.V2Y9QaTk-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402011108.V2Y9QaTk-lkp@intel.com/

All errors (new ones prefixed by >>):

   kernel/trace/trace_hwlat.c: In function 'hwlat_mode_write':
   kernel/trace/trace_hwlat.c:672:14: error: 'buf' redeclared as different kind of symbol
     672 |         char buf[64];
         |              ^~~
   kernel/trace/trace_hwlat.c:667:68: note: previous definition of 'buf' with type 'char *'
     667 | static ssize_t hwlat_mode_write(struct kernfs_open_file *of, char *buf,
         |                                                              ~~~~~~^~~
   kernel/trace/trace_hwlat.c:672:14: warning: unused variable 'buf' [-Wunused-variable]
     672 |         char buf[64];
         |              ^~~
   kernel/trace/trace_hwlat.c: At top level:
   kernel/trace/trace_hwlat.c:736:10: error: 'const struct kernfs_ops' has no member named 'start'
     736 |         .start                  = s_mode_start,
         |          ^~~~~
   kernel/trace/trace_hwlat.c:736:9: warning: the address of 's_mode_start' will always evaluate as 'true' [-Waddress]
     736 |         .start                  = s_mode_start,
         |         ^
   kernel/trace/trace_hwlat.c:737:10: error: 'const struct kernfs_ops' has no member named 'next'
     737 |         .next                   = s_mode_next,
         |          ^~~~
>> kernel/trace/trace_hwlat.c:737:35: error: initialization of 'ssize_t (*)(struct kernfs_open_file *, char *, size_t,  loff_t)' {aka 'long int (*)(struct kernfs_open_file *, char *, long unsigned int,  long long int)'} from incompatible pointer type 'void * (*)(struct seq_file *, void *, loff_t *)' {aka 'void * (*)(struct seq_file *, void *, long long int *)'} [-Werror=incompatible-pointer-types]
     737 |         .next                   = s_mode_next,
         |                                   ^~~~~~~~~~~
   kernel/trace/trace_hwlat.c:737:35: note: (near initialization for 'thread_mode_fops.write')
   kernel/trace/trace_hwlat.c:738:10: error: 'const struct kernfs_ops' has no member named 'show'
     738 |         .show                   = s_mode_show,
         |          ^~~~
   kernel/trace/trace_hwlat.c:738:35: error: initialization of '__poll_t (*)(struct kernfs_open_file *, struct poll_table_struct *)' {aka 'unsigned int (*)(struct kernfs_open_file *, struct poll_table_struct *)'} from incompatible pointer type 'int (*)(struct seq_file *, void *)' [-Werror=incompatible-pointer-types]
     738 |         .show                   = s_mode_show,
         |                                   ^~~~~~~~~~~
   kernel/trace/trace_hwlat.c:738:35: note: (near initialization for 'thread_mode_fops.poll')
   kernel/trace/trace_hwlat.c:739:10: error: 'const struct kernfs_ops' has no member named 'stop'
     739 |         .stop                   = s_mode_stop,
         |          ^~~~
   kernel/trace/trace_hwlat.c:739:35: error: initialization of 'int (*)(struct kernfs_open_file *, struct vm_area_struct *)' from incompatible pointer type 'void (*)(struct seq_file *, void *)' [-Werror=incompatible-pointer-types]
     739 |         .stop                   = s_mode_stop,
         |                                   ^~~~~~~~~~~
   kernel/trace/trace_hwlat.c:739:35: note: (near initialization for 'thread_mode_fops.mmap')
   kernel/trace/trace_hwlat.c:740:35: warning: initialized field overwritten [-Woverride-init]
     740 |         .write                  = hwlat_mode_write,
         |                                   ^~~~~~~~~~~~~~~~
   kernel/trace/trace_hwlat.c:740:35: note: (near initialization for 'thread_mode_fops.write')
   kernel/trace/trace_hwlat.c: In function 'init_tracefs':
   kernel/trace/trace_hwlat.c:766:51: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
     766 |                                                   &trace_min_max_fops);
         |                                                   ^~~~~~~~~~~~~~~~~~~
         |                                                   |
         |                                                   const struct file_operations *
   In file included from kernel/trace/trace_hwlat.c:41:
   include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *'
      94 |                                         const struct kernfs_ops *ops);
         |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
   kernel/trace/trace_hwlat.c:773:50: error: passing argument 5 of 'tracefs_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
     773 |                                                  &trace_min_max_fops);
         |                                                  ^~~~~~~~~~~~~~~~~~~
         |                                                  |
         |                                                  const struct file_operations *
   include/linux/tracefs.h:94:66: note: expected 'const struct kernfs_ops *' but argument is of type 'const struct file_operations *'
      94 |                                         const struct kernfs_ops *ops);
         |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
   kernel/trace/trace_hwlat.c:778:47: error: passing argument 3 of 'trace_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
     778 |                                               top_dir,
         |                                               ^~~~~~~
         |                                               |
         |                                               struct kernfs_node *
   In file included from kernel/trace/trace_hwlat.c:46:
   kernel/trace/trace.h:629:49: note: expected 'struct dentry *' but argument is of type 'struct kernfs_node *'
     629 |                                  struct dentry *parent,
         |                                  ~~~~~~~~~~~~~~~^~~~~~
   kernel/trace/trace_hwlat.c:780:47: error: passing argument 5 of 'trace_create_file' from incompatible pointer type [-Werror=incompatible-pointer-types]
     780 |                                               &thread_mode_fops);
         |                                               ^~~~~~~~~~~~~~~~~
         |                                               |
         |                                               const struct kernfs_ops *
   kernel/trace/trace.h:631:64: note: expected 'const struct file_operations *' but argument is of type 'const struct kernfs_ops *'
     631 |                                  const struct file_operations *fops);
         |                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
   kernel/trace/trace_hwlat.c:777:27: error: assignment to 'struct kernfs_node *' from incompatible pointer type 'struct dentry *' [-Werror=incompatible-pointer-types]
     777 |         hwlat_thread_mode = trace_create_file("mode", TRACE_MODE_WRITE,
         |                           ^
   cc1: some warnings being treated as errors


vim +737 kernel/trace/trace_hwlat.c

   733	
   734	static const struct kernfs_ops thread_mode_fops = {
   735		.atomic_write_len	= PAGE_SIZE,
   736		.start			= s_mode_start,
 > 737		.next			= s_mode_next,
   738		.show			= s_mode_show,
   739		.stop			= s_mode_stop,
   740		.write			= hwlat_mode_write,
   741	};
   742	/**
   743	 * init_tracefs - A function to initialize the tracefs interface files
   744	 *
   745	 * This function creates entries in tracefs for "hwlat_detector".
   746	 * It creates the hwlat_detector directory in the tracing directory,
   747	 * and within that directory is the count, width and window files to
   748	 * change and view those values.
   749	 */
   750	static int init_tracefs(void)
   751	{
   752		int ret;
   753		struct kernfs_node *top_dir;
   754	
   755		ret = tracing_init_dentry();
   756		if (ret)
   757			return -ENOMEM;
   758	
   759		top_dir = tracefs_create_dir("hwlat_detector", NULL);
   760		if (!top_dir)
   761			return -ENOMEM;
   762	
   763		hwlat_sample_window = tracefs_create_file("window", TRACE_MODE_WRITE,
   764							  top_dir,
   765							  &hwlat_window,
   766							  &trace_min_max_fops);
   767		if (!hwlat_sample_window)
   768			goto err;
   769	
   770		hwlat_sample_width = tracefs_create_file("width", TRACE_MODE_WRITE,
   771							 top_dir,
   772							 &hwlat_width,
   773							 &trace_min_max_fops);
   774		if (!hwlat_sample_width)
   775			goto err;
   776	
   777		hwlat_thread_mode = trace_create_file("mode", TRACE_MODE_WRITE,
   778						      top_dir,
   779						      NULL,
   780						      &thread_mode_fops);
   781		if (!hwlat_thread_mode)
   782			goto err;
   783	
   784		return 0;
   785	
   786	 err:
   787		tracefs_remove(top_dir);
   788		return -ENOMEM;
   789	}
   790	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH DRAFT 1/4] : tracefs: port to kernfs
  2024-01-31 13:36 ` [PATCH DRAFT 1/4] : tracefs: port " Christian Brauner
  2024-02-01  0:37   ` kernel test robot
  2024-02-01  0:37   ` kernel test robot
@ 2024-02-01  7:01   ` kernel test robot
  2 siblings, 0 replies; 12+ messages in thread
From: kernel test robot @ 2024-02-01  7:01 UTC (permalink / raw)
  To: Christian Brauner, Steven Rostedt, Linus Torvalds, Amir Goldstein,
	Greg Kroah-Hartman
  Cc: oe-kbuild-all, LKML, lsf-pc, linux-fsdevel, Al Viro,
	Matthew Wilcox, Christian Brauner

Hi Christian,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 41bccc98fb7931d63d03f326a746ac4d429c1dd3]

url:    https://github.com/intel-lab-lkp/linux/commits/Christian-Brauner/tracefs-port-to-kernfs/20240131-214120
base:   41bccc98fb7931d63d03f326a746ac4d429c1dd3
patch link:    https://lore.kernel.org/r/20240131-tracefs-kernfs-v1-1-f20e2e9a8d61%40kernel.org
patch subject: [PATCH DRAFT 1/4] : tracefs: port to kernfs
config: i386-randconfig-061-20240201 (https://download.01.org/0day-ci/archive/20240201/202402011431.c6K3rKZS-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240201/202402011431.c6K3rKZS-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202402011431.c6K3rKZS-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> fs/tracefs/inode.c:88:27: sparse: sparse: symbol 'global_opts' was not declared. Should it be static?

vim +/global_opts +88 fs/tracefs/inode.c

    87	
  > 88	struct tracefs_mount_opts global_opts = {
    89		.mode	= TRACEFS_DEFAULT_MODE,
    90		.uid	= GLOBAL_ROOT_UID,
    91		.gid	= GLOBAL_ROOT_GID,
    92		.opts	= 0,
    93	};
    94	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2024-02-01  7:01 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-31 13:36 [PATCH DRAFT 0/4] : Port tracefs to kernfs Christian Brauner
2024-01-31 13:36 ` [PATCH DRAFT 1/4] : tracefs: port " Christian Brauner
2024-02-01  0:37   ` kernel test robot
2024-02-01  0:37   ` kernel test robot
2024-02-01  7:01   ` kernel test robot
2024-01-31 13:36 ` [PATCH DRAFT 2/4] : trace: stash kernfs_node instead of dentries Christian Brauner
2024-01-31 13:36 ` [PATCH DRAFT 3/4] : hwlat: port struct file_operations thread_mode_fops to struct kernfs_ops Christian Brauner
2024-02-01  3:30   ` kernel test robot
2024-01-31 13:36 ` [PATCH DRAFT 4/4] : trace: illustrate how to convert basic open functions Christian Brauner
2024-01-31 14:41 ` [PATCH DRAFT 0/4] : Port tracefs to kernfs Steven Rostedt
2024-01-31 15:28   ` Steven Rostedt
2024-01-31 14:59 ` James Bottomley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).