162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * fs/kernfs/mount.c - kernfs mount implementation
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2001-3 Patrick Mochel
662306a36Sopenharmony_ci * Copyright (c) 2007 SUSE Linux Products GmbH
762306a36Sopenharmony_ci * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/fs.h>
1162306a36Sopenharmony_ci#include <linux/mount.h>
1262306a36Sopenharmony_ci#include <linux/init.h>
1362306a36Sopenharmony_ci#include <linux/magic.h>
1462306a36Sopenharmony_ci#include <linux/slab.h>
1562306a36Sopenharmony_ci#include <linux/pagemap.h>
1662306a36Sopenharmony_ci#include <linux/namei.h>
1762306a36Sopenharmony_ci#include <linux/seq_file.h>
1862306a36Sopenharmony_ci#include <linux/exportfs.h>
1962306a36Sopenharmony_ci#include <linux/uuid.h>
2062306a36Sopenharmony_ci#include <linux/statfs.h>
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#include "kernfs-internal.h"
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistruct kmem_cache *kernfs_node_cache, *kernfs_iattrs_cache;
2562306a36Sopenharmony_cistruct kernfs_global_locks *kernfs_locks;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic int kernfs_sop_show_options(struct seq_file *sf, struct dentry *dentry)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	struct kernfs_root *root = kernfs_root(kernfs_dentry_node(dentry));
3062306a36Sopenharmony_ci	struct kernfs_syscall_ops *scops = root->syscall_ops;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	if (scops && scops->show_options)
3362306a36Sopenharmony_ci		return scops->show_options(sf, root);
3462306a36Sopenharmony_ci	return 0;
3562306a36Sopenharmony_ci}
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_cistatic int kernfs_sop_show_path(struct seq_file *sf, struct dentry *dentry)
3862306a36Sopenharmony_ci{
3962306a36Sopenharmony_ci	struct kernfs_node *node = kernfs_dentry_node(dentry);
4062306a36Sopenharmony_ci	struct kernfs_root *root = kernfs_root(node);
4162306a36Sopenharmony_ci	struct kernfs_syscall_ops *scops = root->syscall_ops;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	if (scops && scops->show_path)
4462306a36Sopenharmony_ci		return scops->show_path(sf, node, root);
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	seq_dentry(sf, dentry, " \t\n\\");
4762306a36Sopenharmony_ci	return 0;
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic int kernfs_statfs(struct dentry *dentry, struct kstatfs *buf)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	simple_statfs(dentry, buf);
5362306a36Sopenharmony_ci	buf->f_fsid = uuid_to_fsid(dentry->d_sb->s_uuid.b);
5462306a36Sopenharmony_ci	return 0;
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ciconst struct super_operations kernfs_sops = {
5862306a36Sopenharmony_ci	.statfs		= kernfs_statfs,
5962306a36Sopenharmony_ci	.drop_inode	= generic_delete_inode,
6062306a36Sopenharmony_ci	.evict_inode	= kernfs_evict_inode,
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	.show_options	= kernfs_sop_show_options,
6362306a36Sopenharmony_ci	.show_path	= kernfs_sop_show_path,
6462306a36Sopenharmony_ci};
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic int kernfs_encode_fh(struct inode *inode, __u32 *fh, int *max_len,
6762306a36Sopenharmony_ci			    struct inode *parent)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	struct kernfs_node *kn = inode->i_private;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	if (*max_len < 2) {
7262306a36Sopenharmony_ci		*max_len = 2;
7362306a36Sopenharmony_ci		return FILEID_INVALID;
7462306a36Sopenharmony_ci	}
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	*max_len = 2;
7762306a36Sopenharmony_ci	*(u64 *)fh = kn->id;
7862306a36Sopenharmony_ci	return FILEID_KERNFS;
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cistatic struct dentry *__kernfs_fh_to_dentry(struct super_block *sb,
8262306a36Sopenharmony_ci					    struct fid *fid, int fh_len,
8362306a36Sopenharmony_ci					    int fh_type, bool get_parent)
8462306a36Sopenharmony_ci{
8562306a36Sopenharmony_ci	struct kernfs_super_info *info = kernfs_info(sb);
8662306a36Sopenharmony_ci	struct kernfs_node *kn;
8762306a36Sopenharmony_ci	struct inode *inode;
8862306a36Sopenharmony_ci	u64 id;
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	if (fh_len < 2)
9162306a36Sopenharmony_ci		return NULL;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	switch (fh_type) {
9462306a36Sopenharmony_ci	case FILEID_KERNFS:
9562306a36Sopenharmony_ci		id = *(u64 *)fid;
9662306a36Sopenharmony_ci		break;
9762306a36Sopenharmony_ci	case FILEID_INO32_GEN:
9862306a36Sopenharmony_ci	case FILEID_INO32_GEN_PARENT:
9962306a36Sopenharmony_ci		/*
10062306a36Sopenharmony_ci		 * blk_log_action() exposes "LOW32,HIGH32" pair without
10162306a36Sopenharmony_ci		 * type and userland can call us with generic fid
10262306a36Sopenharmony_ci		 * constructed from them.  Combine it back to ID.  See
10362306a36Sopenharmony_ci		 * blk_log_action().
10462306a36Sopenharmony_ci		 */
10562306a36Sopenharmony_ci		id = ((u64)fid->i32.gen << 32) | fid->i32.ino;
10662306a36Sopenharmony_ci		break;
10762306a36Sopenharmony_ci	default:
10862306a36Sopenharmony_ci		return NULL;
10962306a36Sopenharmony_ci	}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	kn = kernfs_find_and_get_node_by_id(info->root, id);
11262306a36Sopenharmony_ci	if (!kn)
11362306a36Sopenharmony_ci		return ERR_PTR(-ESTALE);
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	if (get_parent) {
11662306a36Sopenharmony_ci		struct kernfs_node *parent;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci		parent = kernfs_get_parent(kn);
11962306a36Sopenharmony_ci		kernfs_put(kn);
12062306a36Sopenharmony_ci		kn = parent;
12162306a36Sopenharmony_ci		if (!kn)
12262306a36Sopenharmony_ci			return ERR_PTR(-ESTALE);
12362306a36Sopenharmony_ci	}
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	inode = kernfs_get_inode(sb, kn);
12662306a36Sopenharmony_ci	kernfs_put(kn);
12762306a36Sopenharmony_ci	if (!inode)
12862306a36Sopenharmony_ci		return ERR_PTR(-ESTALE);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	return d_obtain_alias(inode);
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistatic struct dentry *kernfs_fh_to_dentry(struct super_block *sb,
13462306a36Sopenharmony_ci					  struct fid *fid, int fh_len,
13562306a36Sopenharmony_ci					  int fh_type)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	return __kernfs_fh_to_dentry(sb, fid, fh_len, fh_type, false);
13862306a36Sopenharmony_ci}
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistatic struct dentry *kernfs_fh_to_parent(struct super_block *sb,
14162306a36Sopenharmony_ci					  struct fid *fid, int fh_len,
14262306a36Sopenharmony_ci					  int fh_type)
14362306a36Sopenharmony_ci{
14462306a36Sopenharmony_ci	return __kernfs_fh_to_dentry(sb, fid, fh_len, fh_type, true);
14562306a36Sopenharmony_ci}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistatic struct dentry *kernfs_get_parent_dentry(struct dentry *child)
14862306a36Sopenharmony_ci{
14962306a36Sopenharmony_ci	struct kernfs_node *kn = kernfs_dentry_node(child);
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	return d_obtain_alias(kernfs_get_inode(child->d_sb, kn->parent));
15262306a36Sopenharmony_ci}
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_cistatic const struct export_operations kernfs_export_ops = {
15562306a36Sopenharmony_ci	.encode_fh	= kernfs_encode_fh,
15662306a36Sopenharmony_ci	.fh_to_dentry	= kernfs_fh_to_dentry,
15762306a36Sopenharmony_ci	.fh_to_parent	= kernfs_fh_to_parent,
15862306a36Sopenharmony_ci	.get_parent	= kernfs_get_parent_dentry,
15962306a36Sopenharmony_ci};
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci/**
16262306a36Sopenharmony_ci * kernfs_root_from_sb - determine kernfs_root associated with a super_block
16362306a36Sopenharmony_ci * @sb: the super_block in question
16462306a36Sopenharmony_ci *
16562306a36Sopenharmony_ci * Return: the kernfs_root associated with @sb.  If @sb is not a kernfs one,
16662306a36Sopenharmony_ci * %NULL is returned.
16762306a36Sopenharmony_ci */
16862306a36Sopenharmony_cistruct kernfs_root *kernfs_root_from_sb(struct super_block *sb)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	if (sb->s_op == &kernfs_sops)
17162306a36Sopenharmony_ci		return kernfs_info(sb)->root;
17262306a36Sopenharmony_ci	return NULL;
17362306a36Sopenharmony_ci}
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci/*
17662306a36Sopenharmony_ci * find the next ancestor in the path down to @child, where @parent was the
17762306a36Sopenharmony_ci * ancestor whose descendant we want to find.
17862306a36Sopenharmony_ci *
17962306a36Sopenharmony_ci * Say the path is /a/b/c/d.  @child is d, @parent is %NULL.  We return the root
18062306a36Sopenharmony_ci * node.  If @parent is b, then we return the node for c.
18162306a36Sopenharmony_ci * Passing in d as @parent is not ok.
18262306a36Sopenharmony_ci */
18362306a36Sopenharmony_cistatic struct kernfs_node *find_next_ancestor(struct kernfs_node *child,
18462306a36Sopenharmony_ci					      struct kernfs_node *parent)
18562306a36Sopenharmony_ci{
18662306a36Sopenharmony_ci	if (child == parent) {
18762306a36Sopenharmony_ci		pr_crit_once("BUG in find_next_ancestor: called with parent == child");
18862306a36Sopenharmony_ci		return NULL;
18962306a36Sopenharmony_ci	}
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	while (child->parent != parent) {
19262306a36Sopenharmony_ci		if (!child->parent)
19362306a36Sopenharmony_ci			return NULL;
19462306a36Sopenharmony_ci		child = child->parent;
19562306a36Sopenharmony_ci	}
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	return child;
19862306a36Sopenharmony_ci}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci/**
20162306a36Sopenharmony_ci * kernfs_node_dentry - get a dentry for the given kernfs_node
20262306a36Sopenharmony_ci * @kn: kernfs_node for which a dentry is needed
20362306a36Sopenharmony_ci * @sb: the kernfs super_block
20462306a36Sopenharmony_ci *
20562306a36Sopenharmony_ci * Return: the dentry pointer
20662306a36Sopenharmony_ci */
20762306a36Sopenharmony_cistruct dentry *kernfs_node_dentry(struct kernfs_node *kn,
20862306a36Sopenharmony_ci				  struct super_block *sb)
20962306a36Sopenharmony_ci{
21062306a36Sopenharmony_ci	struct dentry *dentry;
21162306a36Sopenharmony_ci	struct kernfs_node *knparent = NULL;
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	BUG_ON(sb->s_op != &kernfs_sops);
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	dentry = dget(sb->s_root);
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	/* Check if this is the root kernfs_node */
21862306a36Sopenharmony_ci	if (!kn->parent)
21962306a36Sopenharmony_ci		return dentry;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	knparent = find_next_ancestor(kn, NULL);
22262306a36Sopenharmony_ci	if (WARN_ON(!knparent)) {
22362306a36Sopenharmony_ci		dput(dentry);
22462306a36Sopenharmony_ci		return ERR_PTR(-EINVAL);
22562306a36Sopenharmony_ci	}
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci	do {
22862306a36Sopenharmony_ci		struct dentry *dtmp;
22962306a36Sopenharmony_ci		struct kernfs_node *kntmp;
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci		if (kn == knparent)
23262306a36Sopenharmony_ci			return dentry;
23362306a36Sopenharmony_ci		kntmp = find_next_ancestor(kn, knparent);
23462306a36Sopenharmony_ci		if (WARN_ON(!kntmp)) {
23562306a36Sopenharmony_ci			dput(dentry);
23662306a36Sopenharmony_ci			return ERR_PTR(-EINVAL);
23762306a36Sopenharmony_ci		}
23862306a36Sopenharmony_ci		dtmp = lookup_positive_unlocked(kntmp->name, dentry,
23962306a36Sopenharmony_ci					       strlen(kntmp->name));
24062306a36Sopenharmony_ci		dput(dentry);
24162306a36Sopenharmony_ci		if (IS_ERR(dtmp))
24262306a36Sopenharmony_ci			return dtmp;
24362306a36Sopenharmony_ci		knparent = kntmp;
24462306a36Sopenharmony_ci		dentry = dtmp;
24562306a36Sopenharmony_ci	} while (true);
24662306a36Sopenharmony_ci}
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_cistatic int kernfs_fill_super(struct super_block *sb, struct kernfs_fs_context *kfc)
24962306a36Sopenharmony_ci{
25062306a36Sopenharmony_ci	struct kernfs_super_info *info = kernfs_info(sb);
25162306a36Sopenharmony_ci	struct kernfs_root *kf_root = kfc->root;
25262306a36Sopenharmony_ci	struct inode *inode;
25362306a36Sopenharmony_ci	struct dentry *root;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	info->sb = sb;
25662306a36Sopenharmony_ci	/* Userspace would break if executables or devices appear on sysfs */
25762306a36Sopenharmony_ci	sb->s_iflags |= SB_I_NOEXEC | SB_I_NODEV;
25862306a36Sopenharmony_ci	sb->s_blocksize = PAGE_SIZE;
25962306a36Sopenharmony_ci	sb->s_blocksize_bits = PAGE_SHIFT;
26062306a36Sopenharmony_ci	sb->s_magic = kfc->magic;
26162306a36Sopenharmony_ci	sb->s_op = &kernfs_sops;
26262306a36Sopenharmony_ci	sb->s_xattr = kernfs_xattr_handlers;
26362306a36Sopenharmony_ci	if (info->root->flags & KERNFS_ROOT_SUPPORT_EXPORTOP)
26462306a36Sopenharmony_ci		sb->s_export_op = &kernfs_export_ops;
26562306a36Sopenharmony_ci	sb->s_time_gran = 1;
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	/* sysfs dentries and inodes don't require IO to create */
26862306a36Sopenharmony_ci	sb->s_shrink.seeks = 0;
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	/* get root inode, initialize and unlock it */
27162306a36Sopenharmony_ci	down_read(&kf_root->kernfs_rwsem);
27262306a36Sopenharmony_ci	inode = kernfs_get_inode(sb, info->root->kn);
27362306a36Sopenharmony_ci	up_read(&kf_root->kernfs_rwsem);
27462306a36Sopenharmony_ci	if (!inode) {
27562306a36Sopenharmony_ci		pr_debug("kernfs: could not get root inode\n");
27662306a36Sopenharmony_ci		return -ENOMEM;
27762306a36Sopenharmony_ci	}
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	/* instantiate and link root dentry */
28062306a36Sopenharmony_ci	root = d_make_root(inode);
28162306a36Sopenharmony_ci	if (!root) {
28262306a36Sopenharmony_ci		pr_debug("%s: could not get root dentry!\n", __func__);
28362306a36Sopenharmony_ci		return -ENOMEM;
28462306a36Sopenharmony_ci	}
28562306a36Sopenharmony_ci	sb->s_root = root;
28662306a36Sopenharmony_ci	sb->s_d_op = &kernfs_dops;
28762306a36Sopenharmony_ci	return 0;
28862306a36Sopenharmony_ci}
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_cistatic int kernfs_test_super(struct super_block *sb, struct fs_context *fc)
29162306a36Sopenharmony_ci{
29262306a36Sopenharmony_ci	struct kernfs_super_info *sb_info = kernfs_info(sb);
29362306a36Sopenharmony_ci	struct kernfs_super_info *info = fc->s_fs_info;
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	return sb_info->root == info->root && sb_info->ns == info->ns;
29662306a36Sopenharmony_ci}
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_cistatic int kernfs_set_super(struct super_block *sb, struct fs_context *fc)
29962306a36Sopenharmony_ci{
30062306a36Sopenharmony_ci	struct kernfs_fs_context *kfc = fc->fs_private;
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci	kfc->ns_tag = NULL;
30362306a36Sopenharmony_ci	return set_anon_super_fc(sb, fc);
30462306a36Sopenharmony_ci}
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci/**
30762306a36Sopenharmony_ci * kernfs_super_ns - determine the namespace tag of a kernfs super_block
30862306a36Sopenharmony_ci * @sb: super_block of interest
30962306a36Sopenharmony_ci *
31062306a36Sopenharmony_ci * Return: the namespace tag associated with kernfs super_block @sb.
31162306a36Sopenharmony_ci */
31262306a36Sopenharmony_ciconst void *kernfs_super_ns(struct super_block *sb)
31362306a36Sopenharmony_ci{
31462306a36Sopenharmony_ci	struct kernfs_super_info *info = kernfs_info(sb);
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	return info->ns;
31762306a36Sopenharmony_ci}
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci/**
32062306a36Sopenharmony_ci * kernfs_get_tree - kernfs filesystem access/retrieval helper
32162306a36Sopenharmony_ci * @fc: The filesystem context.
32262306a36Sopenharmony_ci *
32362306a36Sopenharmony_ci * This is to be called from each kernfs user's fs_context->ops->get_tree()
32462306a36Sopenharmony_ci * implementation, which should set the specified ->@fs_type and ->@flags, and
32562306a36Sopenharmony_ci * specify the hierarchy and namespace tag to mount via ->@root and ->@ns,
32662306a36Sopenharmony_ci * respectively.
32762306a36Sopenharmony_ci *
32862306a36Sopenharmony_ci * Return: %0 on success, -errno on failure.
32962306a36Sopenharmony_ci */
33062306a36Sopenharmony_ciint kernfs_get_tree(struct fs_context *fc)
33162306a36Sopenharmony_ci{
33262306a36Sopenharmony_ci	struct kernfs_fs_context *kfc = fc->fs_private;
33362306a36Sopenharmony_ci	struct super_block *sb;
33462306a36Sopenharmony_ci	struct kernfs_super_info *info;
33562306a36Sopenharmony_ci	int error;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	info = kzalloc(sizeof(*info), GFP_KERNEL);
33862306a36Sopenharmony_ci	if (!info)
33962306a36Sopenharmony_ci		return -ENOMEM;
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci	info->root = kfc->root;
34262306a36Sopenharmony_ci	info->ns = kfc->ns_tag;
34362306a36Sopenharmony_ci	INIT_LIST_HEAD(&info->node);
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	fc->s_fs_info = info;
34662306a36Sopenharmony_ci	sb = sget_fc(fc, kernfs_test_super, kernfs_set_super);
34762306a36Sopenharmony_ci	if (IS_ERR(sb))
34862306a36Sopenharmony_ci		return PTR_ERR(sb);
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci	if (!sb->s_root) {
35162306a36Sopenharmony_ci		struct kernfs_super_info *info = kernfs_info(sb);
35262306a36Sopenharmony_ci		struct kernfs_root *root = kfc->root;
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci		kfc->new_sb_created = true;
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci		error = kernfs_fill_super(sb, kfc);
35762306a36Sopenharmony_ci		if (error) {
35862306a36Sopenharmony_ci			deactivate_locked_super(sb);
35962306a36Sopenharmony_ci			return error;
36062306a36Sopenharmony_ci		}
36162306a36Sopenharmony_ci		sb->s_flags |= SB_ACTIVE;
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci		uuid_gen(&sb->s_uuid);
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci		down_write(&root->kernfs_supers_rwsem);
36662306a36Sopenharmony_ci		list_add(&info->node, &info->root->supers);
36762306a36Sopenharmony_ci		up_write(&root->kernfs_supers_rwsem);
36862306a36Sopenharmony_ci	}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	fc->root = dget(sb->s_root);
37162306a36Sopenharmony_ci	return 0;
37262306a36Sopenharmony_ci}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_civoid kernfs_free_fs_context(struct fs_context *fc)
37562306a36Sopenharmony_ci{
37662306a36Sopenharmony_ci	/* Note that we don't deal with kfc->ns_tag here. */
37762306a36Sopenharmony_ci	kfree(fc->s_fs_info);
37862306a36Sopenharmony_ci	fc->s_fs_info = NULL;
37962306a36Sopenharmony_ci}
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci/**
38262306a36Sopenharmony_ci * kernfs_kill_sb - kill_sb for kernfs
38362306a36Sopenharmony_ci * @sb: super_block being killed
38462306a36Sopenharmony_ci *
38562306a36Sopenharmony_ci * This can be used directly for file_system_type->kill_sb().  If a kernfs
38662306a36Sopenharmony_ci * user needs extra cleanup, it can implement its own kill_sb() and call
38762306a36Sopenharmony_ci * this function at the end.
38862306a36Sopenharmony_ci */
38962306a36Sopenharmony_civoid kernfs_kill_sb(struct super_block *sb)
39062306a36Sopenharmony_ci{
39162306a36Sopenharmony_ci	struct kernfs_super_info *info = kernfs_info(sb);
39262306a36Sopenharmony_ci	struct kernfs_root *root = info->root;
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci	down_write(&root->kernfs_supers_rwsem);
39562306a36Sopenharmony_ci	list_del(&info->node);
39662306a36Sopenharmony_ci	up_write(&root->kernfs_supers_rwsem);
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	/*
39962306a36Sopenharmony_ci	 * Remove the superblock from fs_supers/s_instances
40062306a36Sopenharmony_ci	 * so we can't find it, before freeing kernfs_super_info.
40162306a36Sopenharmony_ci	 */
40262306a36Sopenharmony_ci	kill_anon_super(sb);
40362306a36Sopenharmony_ci	kfree(info);
40462306a36Sopenharmony_ci}
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_cistatic void __init kernfs_mutex_init(void)
40762306a36Sopenharmony_ci{
40862306a36Sopenharmony_ci	int count;
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci	for (count = 0; count < NR_KERNFS_LOCKS; count++)
41162306a36Sopenharmony_ci		mutex_init(&kernfs_locks->open_file_mutex[count]);
41262306a36Sopenharmony_ci}
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_cistatic void __init kernfs_lock_init(void)
41562306a36Sopenharmony_ci{
41662306a36Sopenharmony_ci	kernfs_locks = kmalloc(sizeof(struct kernfs_global_locks), GFP_KERNEL);
41762306a36Sopenharmony_ci	WARN_ON(!kernfs_locks);
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci	kernfs_mutex_init();
42062306a36Sopenharmony_ci}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_civoid __init kernfs_init(void)
42362306a36Sopenharmony_ci{
42462306a36Sopenharmony_ci	kernfs_node_cache = kmem_cache_create("kernfs_node_cache",
42562306a36Sopenharmony_ci					      sizeof(struct kernfs_node),
42662306a36Sopenharmony_ci					      0, SLAB_PANIC, NULL);
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci	/* Creates slab cache for kernfs inode attributes */
42962306a36Sopenharmony_ci	kernfs_iattrs_cache  = kmem_cache_create("kernfs_iattrs_cache",
43062306a36Sopenharmony_ci					      sizeof(struct kernfs_iattrs),
43162306a36Sopenharmony_ci					      0, SLAB_PANIC, NULL);
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	kernfs_lock_init();
43462306a36Sopenharmony_ci}
435