cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mount.c (4281B)


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