From patchwork Wed Jan 31 13:36:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13539457 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4233080BE9 for ; Wed, 31 Jan 2024 13:37:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706708222; cv=none; b=oF9MdF0/+5PERAuab4/gnsIES+ts0rrcDqQLgQWhdZ2V2zfn6avEN2sCWsP/XfRCrZ4wzJyrT1PeF2vizY/zvBXgPHX0AAwzKEHT7XVLg6RIZl9hA8bB1slBTJ1gLjhpx1UW8tedssv74Yoo835BSOLSf+v/MN/0uw2sHrd9Xfs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706708222; c=relaxed/simple; bh=ZUrbo5js4L16Fo0vIaPMD1KJIGQEeF4g1bIUbS162nI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H43q/0WwcyIizJ35uB2G/w6MDU9KyEkrBSPntOHVXJKN25Gqh8331TP/MDHz8sZ+dlErbDv7o31cTr2DP4WgTlmqUB+lh6wB10hs2sKgBw5FaRqNF7Nq3/uH6Csy75SOwlxwRugC7vhV5tlieyufNhTWNXIDp9d/zTTcW/cXRM0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aV0HHOgz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="aV0HHOgz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 75CD2C43394; Wed, 31 Jan 2024 13:36:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1706708221; bh=ZUrbo5js4L16Fo0vIaPMD1KJIGQEeF4g1bIUbS162nI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=aV0HHOgzdYI5Rht/oqs9s4080UyE3PNTZgYbW8XjPZve3lAhTmn1dcCcsmuRf5wNT G/wjMoX85n9786I7p8L/iiFk31hLYt0nrydzcmbL/W5cvQRUTOJTG8edw/3n3mBDLQ X7itLZLdEkO3VcYuet/6d89csga9uJVlFakegSizlzyTA/YpaRTNYTSTDY7oDOHMZc mKMjZVDZdHGTmGFreTiVQitpuedrUodkjoFoCdNT4TmAo/Ao6PDbDtJIFXIxufkCua TKj+9rXhISA8p06Xf52Zs/4dzvyJ89ZChc35Hilo11GLyyEAObNiECKsUxUy52UNMY kAUTVD+YLeqiw== From: Christian Brauner Date: Wed, 31 Jan 2024 14:36:38 +0100 Subject: [PATCH DRAFT 1/4] : tracefs: port to kernfs Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240131-tracefs-kernfs-v1-1-f20e2e9a8d61@kernel.org> References: <20240131-tracefs-kernfs-v1-0-f20e2e9a8d61@kernel.org> In-Reply-To: <20240131-tracefs-kernfs-v1-0-f20e2e9a8d61@kernel.org> To: Steven Rostedt , Linus Torvalds , Amir Goldstein , Greg Kroah-Hartman Cc: lsf-pc@lists.linux-foundation.org, linux-fsdevel@vger.kernel.org, Al Viro , Matthew Wilcox , Christian Brauner X-Mailer: b4 0.13-dev-4e032 X-Developer-Signature: v=1; a=openpgp-sha256; l=27328; i=brauner@kernel.org; h=from:subject:message-id; bh=ZUrbo5js4L16Fo0vIaPMD1KJIGQEeF4g1bIUbS162nI=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTu8vkhwlp4MmPbElexcKkPHzcIScRserQ1OvrXJ5dnQ g/Kk97YdpSyMIhxMciKKbI4tJuEyy3nqdhslKkBM4eVCWQIAxenAEzkugHD/1z7xul8M/b/830w /UKpY3qwRldNpfK2aHWpbB3exDL2LkaGGUvcjJ6ZrLeMjBCb+e3dt68xaUXKfWoJD4+mPdZ4sia BHwA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Signed-off-by: Christian Brauner --- 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 #include +#include #include #include #include @@ -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 #include +#include #include @@ -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; From patchwork Wed Jan 31 13:36:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13539458 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9B3617F46B for ; Wed, 31 Jan 2024 13:37:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706708224; cv=none; b=URMUP7dB43ilIKOOwK7loraiZt/V2sykvpwgEY6ekNTvpE4yE5KOn1hB6bc5o86QYFr2nLn+nXFIfQMloVCSb/kcOmlRPecqMGHHsKNIhM2F5VGJaRDOBvMW0VMimKPxXpcYwX7udMFWa0PoRUStyyD3tnuixLNTdY/VqqBJoD0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706708224; c=relaxed/simple; bh=TYFkPIDUerVZAP7S+7bjohUuc8XQGRiTwBxf1RSlFNA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uRubiUSeChV6sQyAgItVvJs9Naw0QCcuJ8/tlnuKn02mCZDdcfM3rhtbx1NnUB9GzVaZVOHeSHtEZaxPsz9iqvDsyNcO9CVG4+6dXPlYoKbTynR5+MqAQX3sNurTDfVTSn1xxjAIwLNLr/uaQvxcN17nhbKgdK8gP9lewLnw9oQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Jm86+0DM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Jm86+0DM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 49C2DC433B1; Wed, 31 Jan 2024 13:37:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1706708224; bh=TYFkPIDUerVZAP7S+7bjohUuc8XQGRiTwBxf1RSlFNA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Jm86+0DMidX5DNROEbe5Yeht+/hnhhuhI4gZP/y6J5FgNyQKntZ38vmHSKol4HuEl 80pC1JmzJjeh9/AEbzWhwvzuHrfENRa3iKm8zaqXYvt76d/D/rV3oXgA0FzR5Cdb26 aPwRmdLJ79hTyDjkrdHuT9DClfjlWrpXp8dKV+uxbFaX4kqD+ICBNPq+Cl80LV3d87 8Lr6Hq4vgFcqmzMqAJP8fYexiKxmw96j4KoUwp2U2OBU4NNMe2CwiSMfw8duIudOHq bMAXBXUoj8wI0u8zgoXKXZcBVDXnKoi/wRWZ2JCK/eDhBWOX9mGdfrzmD6OB3eSEKG PY/TTvLCbM+hQ== From: Christian Brauner Date: Wed, 31 Jan 2024 14:36:39 +0100 Subject: [PATCH DRAFT 2/4] : trace: stash kernfs_node instead of dentries Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240131-tracefs-kernfs-v1-2-f20e2e9a8d61@kernel.org> References: <20240131-tracefs-kernfs-v1-0-f20e2e9a8d61@kernel.org> In-Reply-To: <20240131-tracefs-kernfs-v1-0-f20e2e9a8d61@kernel.org> To: Steven Rostedt , Linus Torvalds , Amir Goldstein , Greg Kroah-Hartman Cc: lsf-pc@lists.linux-foundation.org, linux-fsdevel@vger.kernel.org, Al Viro , Matthew Wilcox , Christian Brauner X-Mailer: b4 0.13-dev-4e032 X-Developer-Signature: v=1; a=openpgp-sha256; l=2526; i=brauner@kernel.org; h=from:subject:message-id; bh=TYFkPIDUerVZAP7S+7bjohUuc8XQGRiTwBxf1RSlFNA=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTu8vkRlXNeevvh+9u6triqfjTTnyHA/dPekOe3gcTyZ Rce3Jwa31HCwiDGxSArpsji0G4SLrecp2KzUaYGzBxWJpAhDFycAjAR0eMM3+MMvm5L+GXO7Vq0 c3bxzIW8V5zaJ56I8L6/Qa9CKGK9HSPDUilp9x1bFu1b5DPz/PKN9/YGVXavn8CcHdCw4sOW+1n 7uAE= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Signed-off-by: Christian Brauner --- 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) From patchwork Wed Jan 31 13:36:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13539459 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79EEB7F48C for ; Wed, 31 Jan 2024 13:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706708227; cv=none; b=LvGxJaqTKHZRQmCoE5JgzGRiwP0T8ctSGbeS3WmU1ZT+gr11Ypx8NRcnvZ9vLrvIOfOl1a0KTg2NNGY0AcRczDRy0fdT5AFMe2kC+AItXB3AUPA6TASmHqvhKrq+jWybqYK4iomNuCWe8UWpudYD+bJwOMjTAf1iGhTLCeJAU2U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706708227; c=relaxed/simple; bh=wbvajlmHu2Pzc559QV2/etJdPcH8TtSaDFnAcjEn1N8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FEmEsa0SVTwAOrZJiNgcAl6oH4EZ7VO9U9YYifOaAzKrny5eWj8vUGsUQUVDyVQsI84NTGHEnRzj/T3XMImMUA2aXCGgeD+jMPVkUHOFO1MxY03lzQwOfblqAKIsYiGSdkHtxH+dobbckgK2acqxhyNw9e3onhM5/OjXCLYu4RM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RNyRQ21h; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RNyRQ21h" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0300EC43394; Wed, 31 Jan 2024 13:37:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1706708227; bh=wbvajlmHu2Pzc559QV2/etJdPcH8TtSaDFnAcjEn1N8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RNyRQ21hUfMfLZv/E/ZYj8NXMPqBtqmniRJhZ3cHzsSvX7cjsJIY9OANRlQ3jnmAM NBWyAENdL769rObnD3R4hoHpGzrMbPDTRz/Q1hlE+izK4O6690uIzkLEzjuj5EjG48 PzAJN796d74u56W9CUTqpCdLhjbQFVSfbf3dFHgu3A3PaiBer/sED1h2RRfGf21GvX TrrmFYenlc2gW2MZlPpfTWZ3eeToEJYe+1Pr7ZTuzPqbHrH/4h6kgOVrrPfPMXxBQt +ALu/+vkjzZ/U9lzPIRuoiNbY3Gs6cjzOzrrzSZxE03DahaHKQG5PFdDpMjrMobAYh y2SBsq8hTDzZw== From: Christian Brauner Date: Wed, 31 Jan 2024 14:36:40 +0100 Subject: [PATCH DRAFT 3/4] : hwlat: port struct file_operations thread_mode_fops to struct kernfs_ops Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240131-tracefs-kernfs-v1-3-f20e2e9a8d61@kernel.org> References: <20240131-tracefs-kernfs-v1-0-f20e2e9a8d61@kernel.org> In-Reply-To: <20240131-tracefs-kernfs-v1-0-f20e2e9a8d61@kernel.org> To: Steven Rostedt , Linus Torvalds , Amir Goldstein , Greg Kroah-Hartman Cc: lsf-pc@lists.linux-foundation.org, linux-fsdevel@vger.kernel.org, Al Viro , Matthew Wilcox , Christian Brauner X-Mailer: b4 0.13-dev-4e032 X-Developer-Signature: v=1; a=openpgp-sha256; l=2758; i=brauner@kernel.org; h=from:subject:message-id; bh=wbvajlmHu2Pzc559QV2/etJdPcH8TtSaDFnAcjEn1N8=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTu8vnxI8Igwp9p3Y7znr/vcmTbVbClfOpze8r/sk+jo +/A42ObO0pZGMS4GGTFFFkc2k3C5ZbzVGw2ytSAmcPKBDKEgYtTACayx47hf5Hmjotn/S5Y7WnZ Z+lw8eO5lgWtk2O/lb7fWa6x85LCz12MDDeubeeqvfx0oZqmsdB1uYgwRqP/MnEVV6SP7YxLqHy zkBMA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Signed-off-by: Christian Brauner --- 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 From patchwork Wed Jan 31 13:36:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Brauner X-Patchwork-Id: 13539460 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 121F37F48C for ; Wed, 31 Jan 2024 13:37:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706708231; cv=none; b=eNzS09ruMBusYhhoIknykkTQedq7q/1meMsamPDmY8XljUXhgb8l0W2zrxJCdlQveYd/UZfAlxz/P5NRY3S8k1zI9IUIgfxAAkfTo1DZUwhz919xQdnO0tWuU+kZqz6lnOqoB2wVpACL/WlydJPUukYtkmShaTppFkR5CvPyAtE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706708231; c=relaxed/simple; bh=07pUU6zwtgqMLFLSmenEQPPYHlB+jgIuVh5/Q0ieR80=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A3CWMjpCxTLcRiFj+811gdjkQqD7T8opKLZrMRaP/258WfPItFV4JFNJMwRux5srW4c+BVe3rkBnqeyS3V/RH1Bw9TCxlA6PPArLTbReNeO6l0gycMr+Nz0F/tlXL9MJKGa09FhTezDWa1tx2/Po+EP8k0cRlTVk7AN+lzLYm2A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gI2Ll2mD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gI2Ll2mD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8BC65C433B1; Wed, 31 Jan 2024 13:37:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1706708229; bh=07pUU6zwtgqMLFLSmenEQPPYHlB+jgIuVh5/Q0ieR80=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=gI2Ll2mD8o6Ni3GvOW/X1ImCJAEV1p/eRuTOfy33ss2owa1fBIYJLlsfzZZSxq9xB CXgLJpIBcNBTmjag+207+PW9j6iHmnasGKqgf7khTKnrBOFlm5y9YItjW7p57sNC65 bnWKr4M8KgHt1aHVwHGiL1KifUj2+IMBswBHqgNto8Cz+/nP+9jhlwhaVZfTZmgs6f jRNxfLjl5gwXLCdfTvySmDLfMjkuuJx8mM2aIS7VRptxtq/LjesXtJCDk2q+l6v/2N ku6yTI5PoeCbEK3Mb8AdHUWHMVNoaX/uYbuUTIIhLamsTzw7rwK1Z0r7IqZZ7chg32 fvgAh3LuluIQA== From: Christian Brauner Date: Wed, 31 Jan 2024 14:36:41 +0100 Subject: [PATCH DRAFT 4/4] : trace: illustrate how to convert basic open functions Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240131-tracefs-kernfs-v1-4-f20e2e9a8d61@kernel.org> References: <20240131-tracefs-kernfs-v1-0-f20e2e9a8d61@kernel.org> In-Reply-To: <20240131-tracefs-kernfs-v1-0-f20e2e9a8d61@kernel.org> To: Steven Rostedt , Linus Torvalds , Amir Goldstein , Greg Kroah-Hartman Cc: lsf-pc@lists.linux-foundation.org, linux-fsdevel@vger.kernel.org, Al Viro , Matthew Wilcox , Christian Brauner X-Mailer: b4 0.13-dev-4e032 X-Developer-Signature: v=1; a=openpgp-sha256; l=2673; i=brauner@kernel.org; h=from:subject:message-id; bh=07pUU6zwtgqMLFLSmenEQPPYHlB+jgIuVh5/Q0ieR80=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMaTu8vkxP6Sj6lPEYjmx422TzeLbY2/mlxs1KRw+/fgxe 0ey7ttnHaUsDGJcDLJiiiwO7Sbhcst5KjYbZWrAzGFlAhnCwMUpABMR3sLw3zXoQeLUrg8nDZ5p rFHVOJd+Pm/Se8cdm0pfdT964f1GeDIjw5On2w5viVuzpSTf5MmMQmYecaPTm43OxYt2uld36xg tYQYA X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Signed-off-by: Christian Brauner --- 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);