Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * mount.c - operations for initializing and mounting configfs.
0004  *
0005  * Based on sysfs:
0006  *  sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
0007  *
0008  * configfs Copyright (C) 2005 Oracle.  All rights reserved.
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 /* Random magic number */
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         /* directory inodes start off with i_nlink == 2 (for "." entry) */
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; /* the rest get that */
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);