File Index
Files and directories
Sign in
FILE

mount.c

File preview with syntax highlighting.

linux-6.19.14/fs/configfs/mount.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * mount.c - operations for initializing and mounting configfs.
  4 *
  5 * Based on sysfs:
  6 * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
  7 *
  8 * configfs Copyright (C) 2005 Oracle.  All rights reserved.
  9 */
 10
 11#include <linux/fs.h>
 12#include <linux/module.h>
 13#include <linux/mount.h>
 14#include <linux/fs_context.h>
 15#include <linux/pagemap.h>
 16#include <linux/init.h>
 17#include <linux/slab.h>
 18
 19#include <linux/configfs.h>
 20#include "configfs_internal.h"
 21
 22/* Random magic number */
 23#define CONFIGFS_MAGIC 0x62656570
 24
 25static struct vfsmount *configfs_mount = NULL;
 26struct kmem_cache *configfs_dir_cachep;
 27static int configfs_mnt_count = 0;
 28
 29
 30static void configfs_free_inode(struct inode *inode)
 31{
 32	if (S_ISLNK(inode->i_mode))
 33		kfree(inode->i_link);
 34	free_inode_nonrcu(inode);
 35}
 36
 37static const struct super_operations configfs_ops = {
 38	.statfs		= simple_statfs,
 39	.drop_inode	= inode_just_drop,
 40	.free_inode	= configfs_free_inode,
 41};
 42
 43static struct config_group configfs_root_group = {
 44	.cg_item = {
 45		.ci_namebuf	= "root",
 46		.ci_name	= configfs_root_group.cg_item.ci_namebuf,
 47	},
 48};
 49
 50int configfs_is_root(struct config_item *item)
 51{
 52	return item == &configfs_root_group.cg_item;
 53}
 54
 55static struct configfs_dirent configfs_root = {
 56	.s_sibling	= LIST_HEAD_INIT(configfs_root.s_sibling),
 57	.s_children	= LIST_HEAD_INIT(configfs_root.s_children),
 58	.s_element	= &configfs_root_group.cg_item,
 59	.s_type		= CONFIGFS_ROOT,
 60	.s_iattr	= NULL,
 61};
 62
 63static int configfs_fill_super(struct super_block *sb, struct fs_context *fc)
 64{
 65	struct inode *inode;
 66	struct dentry *root;
 67
 68	sb->s_blocksize = PAGE_SIZE;
 69	sb->s_blocksize_bits = PAGE_SHIFT;
 70	sb->s_magic = CONFIGFS_MAGIC;
 71	sb->s_op = &configfs_ops;
 72	sb->s_time_gran = 1;
 73
 74	inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
 75				   &configfs_root, sb);
 76	if (inode) {
 77		inode->i_op = &configfs_root_inode_operations;
 78		inode->i_fop = &configfs_dir_operations;
 79		/* directory inodes start off with i_nlink == 2 (for "." entry) */
 80		inc_nlink(inode);
 81	} else {
 82		pr_debug("could not get root inode\n");
 83		return -ENOMEM;
 84	}
 85
 86	root = d_make_root(inode);
 87	if (!root) {
 88		pr_debug("%s: could not get root dentry!\n",__func__);
 89		return -ENOMEM;
 90	}
 91	config_group_init(&configfs_root_group);
 92	configfs_root_group.cg_item.ci_dentry = root;
 93	root->d_fsdata = &configfs_root;
 94	sb->s_root = root;
 95	set_default_d_op(sb, &configfs_dentry_ops); /* the rest get that */
 96	sb->s_d_flags |= DCACHE_DONTCACHE;
 97	return 0;
 98}
 99
100static int configfs_get_tree(struct fs_context *fc)
101{
102	return get_tree_single(fc, configfs_fill_super);
103}
104
105static const struct fs_context_operations configfs_context_ops = {
106	.get_tree	= configfs_get_tree,
107};
108
109static int configfs_init_fs_context(struct fs_context *fc)
110{
111	fc->ops = &configfs_context_ops;
112	return 0;
113}
114
115static struct file_system_type configfs_fs_type = {
116	.owner		= THIS_MODULE,
117	.name		= "configfs",
118	.init_fs_context = configfs_init_fs_context,
119	.kill_sb	= kill_anon_super,
120};
121MODULE_ALIAS_FS("configfs");
122
123struct dentry *configfs_pin_fs(void)
124{
125	int err = simple_pin_fs(&configfs_fs_type, &configfs_mount,
126			     &configfs_mnt_count);
127	return err ? ERR_PTR(err) : configfs_mount->mnt_root;
128}
129
130void configfs_release_fs(void)
131{
132	simple_release_fs(&configfs_mount, &configfs_mnt_count);
133}
134
135
136static int __init configfs_init(void)
137{
138	int err = -ENOMEM;
139
140	configfs_dir_cachep = kmem_cache_create("configfs_dir_cache",
141						sizeof(struct configfs_dirent),
142						0, 0, NULL);
143	if (!configfs_dir_cachep)
144		goto out;
145
146	err = sysfs_create_mount_point(kernel_kobj, "config");
147	if (err)
148		goto out2;
149
150	err = register_filesystem(&configfs_fs_type);
151	if (err)
152		goto out3;
153
154	return 0;
155out3:
156	pr_err("Unable to register filesystem!\n");
157	sysfs_remove_mount_point(kernel_kobj, "config");
158out2:
159	kmem_cache_destroy(configfs_dir_cachep);
160	configfs_dir_cachep = NULL;
161out:
162	return err;
163}
164
165static void __exit configfs_exit(void)
166{
167	unregister_filesystem(&configfs_fs_type);
168	sysfs_remove_mount_point(kernel_kobj, "config");
169	kmem_cache_destroy(configfs_dir_cachep);
170	configfs_dir_cachep = NULL;
171}
172
173MODULE_AUTHOR("Oracle");
174MODULE_LICENSE("GPL");
175MODULE_VERSION("0.0.2");
176MODULE_DESCRIPTION("Simple RAM filesystem for user driven kernel subsystem configuration.");
177
178core_initcall(configfs_init);
179module_exit(configfs_exit);
~/ Read-only file preview.