Linux Audio

Check our new training course

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