LCOV - code coverage report
Current view: top level - fs/configfs - mount.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 34 61 55.7 %
Date: 2022-04-01 14:17:54 Functions: 4 9 44.4 %
Branches: 5 14 35.7 %

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

Generated by: LCOV version 1.14