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