xref: /kernel/linux/linux-6.6/fs/proc/root.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  linux/fs/proc/root.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Copyright (C) 1991, 1992 Linus Torvalds
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci *  proc root directory handling functions
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci#include <linux/errno.h>
1062306a36Sopenharmony_ci#include <linux/time.h>
1162306a36Sopenharmony_ci#include <linux/proc_fs.h>
1262306a36Sopenharmony_ci#include <linux/stat.h>
1362306a36Sopenharmony_ci#include <linux/init.h>
1462306a36Sopenharmony_ci#include <linux/sched.h>
1562306a36Sopenharmony_ci#include <linux/sched/stat.h>
1662306a36Sopenharmony_ci#include <linux/module.h>
1762306a36Sopenharmony_ci#include <linux/bitops.h>
1862306a36Sopenharmony_ci#include <linux/user_namespace.h>
1962306a36Sopenharmony_ci#include <linux/fs_context.h>
2062306a36Sopenharmony_ci#include <linux/mount.h>
2162306a36Sopenharmony_ci#include <linux/pid_namespace.h>
2262306a36Sopenharmony_ci#include <linux/fs_parser.h>
2362306a36Sopenharmony_ci#include <linux/cred.h>
2462306a36Sopenharmony_ci#include <linux/magic.h>
2562306a36Sopenharmony_ci#include <linux/slab.h>
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#include "internal.h"
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistruct proc_fs_context {
3062306a36Sopenharmony_ci	struct pid_namespace	*pid_ns;
3162306a36Sopenharmony_ci	unsigned int		mask;
3262306a36Sopenharmony_ci	enum proc_hidepid	hidepid;
3362306a36Sopenharmony_ci	int			gid;
3462306a36Sopenharmony_ci	enum proc_pidonly	pidonly;
3562306a36Sopenharmony_ci};
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_cienum proc_param {
3862306a36Sopenharmony_ci	Opt_gid,
3962306a36Sopenharmony_ci	Opt_hidepid,
4062306a36Sopenharmony_ci	Opt_subset,
4162306a36Sopenharmony_ci};
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistatic const struct fs_parameter_spec proc_fs_parameters[] = {
4462306a36Sopenharmony_ci	fsparam_u32("gid",	Opt_gid),
4562306a36Sopenharmony_ci	fsparam_string("hidepid",	Opt_hidepid),
4662306a36Sopenharmony_ci	fsparam_string("subset",	Opt_subset),
4762306a36Sopenharmony_ci	{}
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic inline int valid_hidepid(unsigned int value)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	return (value == HIDEPID_OFF ||
5362306a36Sopenharmony_ci		value == HIDEPID_NO_ACCESS ||
5462306a36Sopenharmony_ci		value == HIDEPID_INVISIBLE ||
5562306a36Sopenharmony_ci		value == HIDEPID_NOT_PTRACEABLE);
5662306a36Sopenharmony_ci}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_cistatic int proc_parse_hidepid_param(struct fs_context *fc, struct fs_parameter *param)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	struct proc_fs_context *ctx = fc->fs_private;
6162306a36Sopenharmony_ci	struct fs_parameter_spec hidepid_u32_spec = fsparam_u32("hidepid", Opt_hidepid);
6262306a36Sopenharmony_ci	struct fs_parse_result result;
6362306a36Sopenharmony_ci	int base = (unsigned long)hidepid_u32_spec.data;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	if (param->type != fs_value_is_string)
6662306a36Sopenharmony_ci		return invalf(fc, "proc: unexpected type of hidepid value\n");
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	if (!kstrtouint(param->string, base, &result.uint_32)) {
6962306a36Sopenharmony_ci		if (!valid_hidepid(result.uint_32))
7062306a36Sopenharmony_ci			return invalf(fc, "proc: unknown value of hidepid - %s\n", param->string);
7162306a36Sopenharmony_ci		ctx->hidepid = result.uint_32;
7262306a36Sopenharmony_ci		return 0;
7362306a36Sopenharmony_ci	}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	if (!strcmp(param->string, "off"))
7662306a36Sopenharmony_ci		ctx->hidepid = HIDEPID_OFF;
7762306a36Sopenharmony_ci	else if (!strcmp(param->string, "noaccess"))
7862306a36Sopenharmony_ci		ctx->hidepid = HIDEPID_NO_ACCESS;
7962306a36Sopenharmony_ci	else if (!strcmp(param->string, "invisible"))
8062306a36Sopenharmony_ci		ctx->hidepid = HIDEPID_INVISIBLE;
8162306a36Sopenharmony_ci	else if (!strcmp(param->string, "ptraceable"))
8262306a36Sopenharmony_ci		ctx->hidepid = HIDEPID_NOT_PTRACEABLE;
8362306a36Sopenharmony_ci	else
8462306a36Sopenharmony_ci		return invalf(fc, "proc: unknown value of hidepid - %s\n", param->string);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	return 0;
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistatic int proc_parse_subset_param(struct fs_context *fc, char *value)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	struct proc_fs_context *ctx = fc->fs_private;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	while (value) {
9462306a36Sopenharmony_ci		char *ptr = strchr(value, ',');
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci		if (ptr != NULL)
9762306a36Sopenharmony_ci			*ptr++ = '\0';
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci		if (*value != '\0') {
10062306a36Sopenharmony_ci			if (!strcmp(value, "pid")) {
10162306a36Sopenharmony_ci				ctx->pidonly = PROC_PIDONLY_ON;
10262306a36Sopenharmony_ci			} else {
10362306a36Sopenharmony_ci				return invalf(fc, "proc: unsupported subset option - %s\n", value);
10462306a36Sopenharmony_ci			}
10562306a36Sopenharmony_ci		}
10662306a36Sopenharmony_ci		value = ptr;
10762306a36Sopenharmony_ci	}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	return 0;
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cistatic int proc_parse_param(struct fs_context *fc, struct fs_parameter *param)
11362306a36Sopenharmony_ci{
11462306a36Sopenharmony_ci	struct proc_fs_context *ctx = fc->fs_private;
11562306a36Sopenharmony_ci	struct fs_parse_result result;
11662306a36Sopenharmony_ci	int opt;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	opt = fs_parse(fc, proc_fs_parameters, param, &result);
11962306a36Sopenharmony_ci	if (opt < 0)
12062306a36Sopenharmony_ci		return opt;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	switch (opt) {
12362306a36Sopenharmony_ci	case Opt_gid:
12462306a36Sopenharmony_ci		ctx->gid = result.uint_32;
12562306a36Sopenharmony_ci		break;
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	case Opt_hidepid:
12862306a36Sopenharmony_ci		if (proc_parse_hidepid_param(fc, param))
12962306a36Sopenharmony_ci			return -EINVAL;
13062306a36Sopenharmony_ci		break;
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	case Opt_subset:
13362306a36Sopenharmony_ci		if (proc_parse_subset_param(fc, param->string) < 0)
13462306a36Sopenharmony_ci			return -EINVAL;
13562306a36Sopenharmony_ci		break;
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	default:
13862306a36Sopenharmony_ci		return -EINVAL;
13962306a36Sopenharmony_ci	}
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	ctx->mask |= 1 << opt;
14262306a36Sopenharmony_ci	return 0;
14362306a36Sopenharmony_ci}
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_cistatic void proc_apply_options(struct proc_fs_info *fs_info,
14662306a36Sopenharmony_ci			       struct fs_context *fc,
14762306a36Sopenharmony_ci			       struct user_namespace *user_ns)
14862306a36Sopenharmony_ci{
14962306a36Sopenharmony_ci	struct proc_fs_context *ctx = fc->fs_private;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	if (ctx->mask & (1 << Opt_gid))
15262306a36Sopenharmony_ci		fs_info->pid_gid = make_kgid(user_ns, ctx->gid);
15362306a36Sopenharmony_ci	if (ctx->mask & (1 << Opt_hidepid))
15462306a36Sopenharmony_ci		fs_info->hide_pid = ctx->hidepid;
15562306a36Sopenharmony_ci	if (ctx->mask & (1 << Opt_subset))
15662306a36Sopenharmony_ci		fs_info->pidonly = ctx->pidonly;
15762306a36Sopenharmony_ci}
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_cistatic int proc_fill_super(struct super_block *s, struct fs_context *fc)
16062306a36Sopenharmony_ci{
16162306a36Sopenharmony_ci	struct proc_fs_context *ctx = fc->fs_private;
16262306a36Sopenharmony_ci	struct inode *root_inode;
16362306a36Sopenharmony_ci	struct proc_fs_info *fs_info;
16462306a36Sopenharmony_ci	int ret;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	fs_info = kzalloc(sizeof(*fs_info), GFP_KERNEL);
16762306a36Sopenharmony_ci	if (!fs_info)
16862306a36Sopenharmony_ci		return -ENOMEM;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	fs_info->pid_ns = get_pid_ns(ctx->pid_ns);
17162306a36Sopenharmony_ci	proc_apply_options(fs_info, fc, current_user_ns());
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	/* User space would break if executables or devices appear on proc */
17462306a36Sopenharmony_ci	s->s_iflags |= SB_I_USERNS_VISIBLE | SB_I_NOEXEC | SB_I_NODEV;
17562306a36Sopenharmony_ci	s->s_flags |= SB_NODIRATIME | SB_NOSUID | SB_NOEXEC;
17662306a36Sopenharmony_ci	s->s_blocksize = 1024;
17762306a36Sopenharmony_ci	s->s_blocksize_bits = 10;
17862306a36Sopenharmony_ci	s->s_magic = PROC_SUPER_MAGIC;
17962306a36Sopenharmony_ci	s->s_op = &proc_sops;
18062306a36Sopenharmony_ci	s->s_time_gran = 1;
18162306a36Sopenharmony_ci	s->s_fs_info = fs_info;
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	/*
18462306a36Sopenharmony_ci	 * procfs isn't actually a stacking filesystem; however, there is
18562306a36Sopenharmony_ci	 * too much magic going on inside it to permit stacking things on
18662306a36Sopenharmony_ci	 * top of it
18762306a36Sopenharmony_ci	 */
18862306a36Sopenharmony_ci	s->s_stack_depth = FILESYSTEM_MAX_STACK_DEPTH;
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	/* procfs dentries and inodes don't require IO to create */
19162306a36Sopenharmony_ci	s->s_shrink.seeks = 0;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	pde_get(&proc_root);
19462306a36Sopenharmony_ci	root_inode = proc_get_inode(s, &proc_root);
19562306a36Sopenharmony_ci	if (!root_inode) {
19662306a36Sopenharmony_ci		pr_err("proc_fill_super: get root inode failed\n");
19762306a36Sopenharmony_ci		return -ENOMEM;
19862306a36Sopenharmony_ci	}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	s->s_root = d_make_root(root_inode);
20162306a36Sopenharmony_ci	if (!s->s_root) {
20262306a36Sopenharmony_ci		pr_err("proc_fill_super: allocate dentry failed\n");
20362306a36Sopenharmony_ci		return -ENOMEM;
20462306a36Sopenharmony_ci	}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	ret = proc_setup_self(s);
20762306a36Sopenharmony_ci	if (ret) {
20862306a36Sopenharmony_ci		return ret;
20962306a36Sopenharmony_ci	}
21062306a36Sopenharmony_ci	return proc_setup_thread_self(s);
21162306a36Sopenharmony_ci}
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_cistatic int proc_reconfigure(struct fs_context *fc)
21462306a36Sopenharmony_ci{
21562306a36Sopenharmony_ci	struct super_block *sb = fc->root->d_sb;
21662306a36Sopenharmony_ci	struct proc_fs_info *fs_info = proc_sb_info(sb);
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	sync_filesystem(sb);
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	proc_apply_options(fs_info, fc, current_user_ns());
22162306a36Sopenharmony_ci	return 0;
22262306a36Sopenharmony_ci}
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_cistatic int proc_get_tree(struct fs_context *fc)
22562306a36Sopenharmony_ci{
22662306a36Sopenharmony_ci	return get_tree_nodev(fc, proc_fill_super);
22762306a36Sopenharmony_ci}
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_cistatic void proc_fs_context_free(struct fs_context *fc)
23062306a36Sopenharmony_ci{
23162306a36Sopenharmony_ci	struct proc_fs_context *ctx = fc->fs_private;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	put_pid_ns(ctx->pid_ns);
23462306a36Sopenharmony_ci	kfree(ctx);
23562306a36Sopenharmony_ci}
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_cistatic const struct fs_context_operations proc_fs_context_ops = {
23862306a36Sopenharmony_ci	.free		= proc_fs_context_free,
23962306a36Sopenharmony_ci	.parse_param	= proc_parse_param,
24062306a36Sopenharmony_ci	.get_tree	= proc_get_tree,
24162306a36Sopenharmony_ci	.reconfigure	= proc_reconfigure,
24262306a36Sopenharmony_ci};
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_cistatic int proc_init_fs_context(struct fs_context *fc)
24562306a36Sopenharmony_ci{
24662306a36Sopenharmony_ci	struct proc_fs_context *ctx;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	ctx = kzalloc(sizeof(struct proc_fs_context), GFP_KERNEL);
24962306a36Sopenharmony_ci	if (!ctx)
25062306a36Sopenharmony_ci		return -ENOMEM;
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	ctx->pid_ns = get_pid_ns(task_active_pid_ns(current));
25362306a36Sopenharmony_ci	put_user_ns(fc->user_ns);
25462306a36Sopenharmony_ci	fc->user_ns = get_user_ns(ctx->pid_ns->user_ns);
25562306a36Sopenharmony_ci	fc->fs_private = ctx;
25662306a36Sopenharmony_ci	fc->ops = &proc_fs_context_ops;
25762306a36Sopenharmony_ci	return 0;
25862306a36Sopenharmony_ci}
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_cistatic void proc_kill_sb(struct super_block *sb)
26162306a36Sopenharmony_ci{
26262306a36Sopenharmony_ci	struct proc_fs_info *fs_info = proc_sb_info(sb);
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	if (!fs_info) {
26562306a36Sopenharmony_ci		kill_anon_super(sb);
26662306a36Sopenharmony_ci		return;
26762306a36Sopenharmony_ci	}
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	dput(fs_info->proc_self);
27062306a36Sopenharmony_ci	dput(fs_info->proc_thread_self);
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	kill_anon_super(sb);
27362306a36Sopenharmony_ci	put_pid_ns(fs_info->pid_ns);
27462306a36Sopenharmony_ci	kfree(fs_info);
27562306a36Sopenharmony_ci}
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_cistatic struct file_system_type proc_fs_type = {
27862306a36Sopenharmony_ci	.name			= "proc",
27962306a36Sopenharmony_ci	.init_fs_context	= proc_init_fs_context,
28062306a36Sopenharmony_ci	.parameters		= proc_fs_parameters,
28162306a36Sopenharmony_ci	.kill_sb		= proc_kill_sb,
28262306a36Sopenharmony_ci	.fs_flags		= FS_USERNS_MOUNT | FS_DISALLOW_NOTIFY_PERM,
28362306a36Sopenharmony_ci};
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_civoid __init proc_root_init(void)
28662306a36Sopenharmony_ci{
28762306a36Sopenharmony_ci	proc_init_kmemcache();
28862306a36Sopenharmony_ci	set_proc_pid_nlink();
28962306a36Sopenharmony_ci	proc_self_init();
29062306a36Sopenharmony_ci	proc_thread_self_init();
29162306a36Sopenharmony_ci	proc_symlink("mounts", NULL, "self/mounts");
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci	proc_net_init();
29462306a36Sopenharmony_ci	proc_mkdir("fs", NULL);
29562306a36Sopenharmony_ci	proc_mkdir("driver", NULL);
29662306a36Sopenharmony_ci	proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */
29762306a36Sopenharmony_ci#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
29862306a36Sopenharmony_ci	/* just give it a mountpoint */
29962306a36Sopenharmony_ci	proc_create_mount_point("openprom");
30062306a36Sopenharmony_ci#endif
30162306a36Sopenharmony_ci	proc_tty_init();
30262306a36Sopenharmony_ci	proc_mkdir("bus", NULL);
30362306a36Sopenharmony_ci	proc_sys_init();
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	/*
30662306a36Sopenharmony_ci	 * Last things last. It is not like userspace processes eager
30762306a36Sopenharmony_ci	 * to open /proc files exist at this point but register last
30862306a36Sopenharmony_ci	 * anyway.
30962306a36Sopenharmony_ci	 */
31062306a36Sopenharmony_ci	register_filesystem(&proc_fs_type);
31162306a36Sopenharmony_ci}
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_cistatic int proc_root_getattr(struct mnt_idmap *idmap,
31462306a36Sopenharmony_ci			     const struct path *path, struct kstat *stat,
31562306a36Sopenharmony_ci			     u32 request_mask, unsigned int query_flags)
31662306a36Sopenharmony_ci{
31762306a36Sopenharmony_ci	generic_fillattr(&nop_mnt_idmap, request_mask, d_inode(path->dentry),
31862306a36Sopenharmony_ci			 stat);
31962306a36Sopenharmony_ci	stat->nlink = proc_root.nlink + nr_processes();
32062306a36Sopenharmony_ci	return 0;
32162306a36Sopenharmony_ci}
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_cistatic struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, unsigned int flags)
32462306a36Sopenharmony_ci{
32562306a36Sopenharmony_ci	if (!proc_pid_lookup(dentry, flags))
32662306a36Sopenharmony_ci		return NULL;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	return proc_lookup(dir, dentry, flags);
32962306a36Sopenharmony_ci}
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_cistatic int proc_root_readdir(struct file *file, struct dir_context *ctx)
33262306a36Sopenharmony_ci{
33362306a36Sopenharmony_ci	if (ctx->pos < FIRST_PROCESS_ENTRY) {
33462306a36Sopenharmony_ci		int error = proc_readdir(file, ctx);
33562306a36Sopenharmony_ci		if (unlikely(error <= 0))
33662306a36Sopenharmony_ci			return error;
33762306a36Sopenharmony_ci		ctx->pos = FIRST_PROCESS_ENTRY;
33862306a36Sopenharmony_ci	}
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	return proc_pid_readdir(file, ctx);
34162306a36Sopenharmony_ci}
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci/*
34462306a36Sopenharmony_ci * The root /proc directory is special, as it has the
34562306a36Sopenharmony_ci * <pid> directories. Thus we don't use the generic
34662306a36Sopenharmony_ci * directory handling functions for that..
34762306a36Sopenharmony_ci */
34862306a36Sopenharmony_cistatic const struct file_operations proc_root_operations = {
34962306a36Sopenharmony_ci	.read		 = generic_read_dir,
35062306a36Sopenharmony_ci	.iterate_shared	 = proc_root_readdir,
35162306a36Sopenharmony_ci	.llseek		= generic_file_llseek,
35262306a36Sopenharmony_ci};
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci/*
35562306a36Sopenharmony_ci * proc root can do almost nothing..
35662306a36Sopenharmony_ci */
35762306a36Sopenharmony_cistatic const struct inode_operations proc_root_inode_operations = {
35862306a36Sopenharmony_ci	.lookup		= proc_root_lookup,
35962306a36Sopenharmony_ci	.getattr	= proc_root_getattr,
36062306a36Sopenharmony_ci};
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci/*
36362306a36Sopenharmony_ci * This is the root "inode" in the /proc tree..
36462306a36Sopenharmony_ci */
36562306a36Sopenharmony_cistruct proc_dir_entry proc_root = {
36662306a36Sopenharmony_ci	.low_ino	= PROC_ROOT_INO,
36762306a36Sopenharmony_ci	.namelen	= 5,
36862306a36Sopenharmony_ci	.mode		= S_IFDIR | S_IRUGO | S_IXUGO,
36962306a36Sopenharmony_ci	.nlink		= 2,
37062306a36Sopenharmony_ci	.refcnt		= REFCOUNT_INIT(1),
37162306a36Sopenharmony_ci	.proc_iops	= &proc_root_inode_operations,
37262306a36Sopenharmony_ci	.proc_dir_ops	= &proc_root_operations,
37362306a36Sopenharmony_ci	.parent		= &proc_root,
37462306a36Sopenharmony_ci	.subdir		= RB_ROOT,
37562306a36Sopenharmony_ci	.name		= "/proc",
37662306a36Sopenharmony_ci};
377