0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/fs.h>
0012 #include <linux/module.h>
0013 #include <linux/mount.h>
0014 #include <linux/fs_context.h>
0015 #include <linux/pagemap.h>
0016 #include <linux/init.h>
0017 #include <linux/slab.h>
0018
0019 #include <linux/configfs.h>
0020 #include "configfs_internal.h"
0021
0022
0023 #define CONFIGFS_MAGIC 0x62656570
0024
0025 static struct vfsmount *configfs_mount = NULL;
0026 struct kmem_cache *configfs_dir_cachep;
0027 static int configfs_mnt_count = 0;
0028
0029
0030 static void configfs_free_inode(struct inode *inode)
0031 {
0032 if (S_ISLNK(inode->i_mode))
0033 kfree(inode->i_link);
0034 free_inode_nonrcu(inode);
0035 }
0036
0037 static const struct super_operations configfs_ops = {
0038 .statfs = simple_statfs,
0039 .drop_inode = generic_delete_inode,
0040 .free_inode = configfs_free_inode,
0041 };
0042
0043 static struct config_group configfs_root_group = {
0044 .cg_item = {
0045 .ci_namebuf = "root",
0046 .ci_name = configfs_root_group.cg_item.ci_namebuf,
0047 },
0048 };
0049
0050 int configfs_is_root(struct config_item *item)
0051 {
0052 return item == &configfs_root_group.cg_item;
0053 }
0054
0055 static struct configfs_dirent configfs_root = {
0056 .s_sibling = LIST_HEAD_INIT(configfs_root.s_sibling),
0057 .s_children = LIST_HEAD_INIT(configfs_root.s_children),
0058 .s_element = &configfs_root_group.cg_item,
0059 .s_type = CONFIGFS_ROOT,
0060 .s_iattr = NULL,
0061 };
0062
0063 static int configfs_fill_super(struct super_block *sb, struct fs_context *fc)
0064 {
0065 struct inode *inode;
0066 struct dentry *root;
0067
0068 sb->s_blocksize = PAGE_SIZE;
0069 sb->s_blocksize_bits = PAGE_SHIFT;
0070 sb->s_magic = CONFIGFS_MAGIC;
0071 sb->s_op = &configfs_ops;
0072 sb->s_time_gran = 1;
0073
0074 inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
0075 &configfs_root, sb);
0076 if (inode) {
0077 inode->i_op = &configfs_root_inode_operations;
0078 inode->i_fop = &configfs_dir_operations;
0079
0080 inc_nlink(inode);
0081 } else {
0082 pr_debug("could not get root inode\n");
0083 return -ENOMEM;
0084 }
0085
0086 root = d_make_root(inode);
0087 if (!root) {
0088 pr_debug("%s: could not get root dentry!\n",__func__);
0089 return -ENOMEM;
0090 }
0091 config_group_init(&configfs_root_group);
0092 configfs_root_group.cg_item.ci_dentry = root;
0093 root->d_fsdata = &configfs_root;
0094 sb->s_root = root;
0095 sb->s_d_op = &configfs_dentry_ops;
0096 return 0;
0097 }
0098
0099 static int configfs_get_tree(struct fs_context *fc)
0100 {
0101 return get_tree_single(fc, configfs_fill_super);
0102 }
0103
0104 static const struct fs_context_operations configfs_context_ops = {
0105 .get_tree = configfs_get_tree,
0106 };
0107
0108 static int configfs_init_fs_context(struct fs_context *fc)
0109 {
0110 fc->ops = &configfs_context_ops;
0111 return 0;
0112 }
0113
0114 static struct file_system_type configfs_fs_type = {
0115 .owner = THIS_MODULE,
0116 .name = "configfs",
0117 .init_fs_context = configfs_init_fs_context,
0118 .kill_sb = kill_litter_super,
0119 };
0120 MODULE_ALIAS_FS("configfs");
0121
0122 struct dentry *configfs_pin_fs(void)
0123 {
0124 int err = simple_pin_fs(&configfs_fs_type, &configfs_mount,
0125 &configfs_mnt_count);
0126 return err ? ERR_PTR(err) : configfs_mount->mnt_root;
0127 }
0128
0129 void configfs_release_fs(void)
0130 {
0131 simple_release_fs(&configfs_mount, &configfs_mnt_count);
0132 }
0133
0134
0135 static int __init configfs_init(void)
0136 {
0137 int err = -ENOMEM;
0138
0139 configfs_dir_cachep = kmem_cache_create("configfs_dir_cache",
0140 sizeof(struct configfs_dirent),
0141 0, 0, NULL);
0142 if (!configfs_dir_cachep)
0143 goto out;
0144
0145 err = sysfs_create_mount_point(kernel_kobj, "config");
0146 if (err)
0147 goto out2;
0148
0149 err = register_filesystem(&configfs_fs_type);
0150 if (err)
0151 goto out3;
0152
0153 return 0;
0154 out3:
0155 pr_err("Unable to register filesystem!\n");
0156 sysfs_remove_mount_point(kernel_kobj, "config");
0157 out2:
0158 kmem_cache_destroy(configfs_dir_cachep);
0159 configfs_dir_cachep = NULL;
0160 out:
0161 return err;
0162 }
0163
0164 static void __exit configfs_exit(void)
0165 {
0166 unregister_filesystem(&configfs_fs_type);
0167 sysfs_remove_mount_point(kernel_kobj, "config");
0168 kmem_cache_destroy(configfs_dir_cachep);
0169 configfs_dir_cachep = NULL;
0170 }
0171
0172 MODULE_AUTHOR("Oracle");
0173 MODULE_LICENSE("GPL");
0174 MODULE_VERSION("0.0.2");
0175 MODULE_DESCRIPTION("Simple RAM filesystem for user driven kernel subsystem configuration.");
0176
0177 core_initcall(configfs_init);
0178 module_exit(configfs_exit);