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