LCOV - code coverage report
Current view: top level - fs/kernfs - mount.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 57 0.0 %
Date: 2014-04-16 Functions: 0 7 0.0 %
Branches: 0 24 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * fs/kernfs/mount.c - kernfs mount implementation
       3                 :            :  *
       4                 :            :  * Copyright (c) 2001-3 Patrick Mochel
       5                 :            :  * Copyright (c) 2007 SUSE Linux Products GmbH
       6                 :            :  * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
       7                 :            :  *
       8                 :            :  * This file is released under the GPLv2.
       9                 :            :  */
      10                 :            : 
      11                 :            : #include <linux/fs.h>
      12                 :            : #include <linux/mount.h>
      13                 :            : #include <linux/init.h>
      14                 :            : #include <linux/magic.h>
      15                 :            : #include <linux/slab.h>
      16                 :            : #include <linux/pagemap.h>
      17                 :            : 
      18                 :            : #include "kernfs-internal.h"
      19                 :            : 
      20                 :            : struct kmem_cache *kernfs_node_cache;
      21                 :            : 
      22                 :            : static const struct super_operations kernfs_sops = {
      23                 :            :         .statfs         = simple_statfs,
      24                 :            :         .drop_inode     = generic_delete_inode,
      25                 :            :         .evict_inode    = kernfs_evict_inode,
      26                 :            : };
      27                 :            : 
      28                 :          0 : static int kernfs_fill_super(struct super_block *sb)
      29                 :            : {
      30                 :          0 :         struct kernfs_super_info *info = kernfs_info(sb);
      31                 :            :         struct inode *inode;
      32                 :            :         struct dentry *root;
      33                 :            : 
      34                 :          0 :         sb->s_blocksize = PAGE_CACHE_SIZE;
      35                 :          0 :         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
      36                 :          0 :         sb->s_magic = SYSFS_MAGIC;
      37                 :          0 :         sb->s_op = &kernfs_sops;
      38                 :          0 :         sb->s_time_gran = 1;
      39                 :            : 
      40                 :            :         /* get root inode, initialize and unlock it */
      41                 :          0 :         mutex_lock(&kernfs_mutex);
      42                 :          0 :         inode = kernfs_get_inode(sb, info->root->kn);
      43                 :          0 :         mutex_unlock(&kernfs_mutex);
      44         [ #  # ]:          0 :         if (!inode) {
      45                 :            :                 pr_debug("kernfs: could not get root inode\n");
      46                 :            :                 return -ENOMEM;
      47                 :            :         }
      48                 :            : 
      49                 :            :         /* instantiate and link root dentry */
      50                 :          0 :         root = d_make_root(inode);
      51         [ #  # ]:          0 :         if (!root) {
      52                 :            :                 pr_debug("%s: could not get root dentry!\n", __func__);
      53                 :            :                 return -ENOMEM;
      54                 :            :         }
      55                 :          0 :         kernfs_get(info->root->kn);
      56                 :          0 :         root->d_fsdata = info->root->kn;
      57                 :          0 :         sb->s_root = root;
      58                 :          0 :         sb->s_d_op = &kernfs_dops;
      59                 :          0 :         return 0;
      60                 :            : }
      61                 :            : 
      62                 :          0 : static int kernfs_test_super(struct super_block *sb, void *data)
      63                 :            : {
      64                 :          0 :         struct kernfs_super_info *sb_info = kernfs_info(sb);
      65                 :            :         struct kernfs_super_info *info = data;
      66                 :            : 
      67 [ #  # ][ #  # ]:          0 :         return sb_info->root == info->root && sb_info->ns == info->ns;
      68                 :            : }
      69                 :            : 
      70                 :          0 : static int kernfs_set_super(struct super_block *sb, void *data)
      71                 :            : {
      72                 :            :         int error;
      73                 :          0 :         error = set_anon_super(sb, data);
      74         [ #  # ]:          0 :         if (!error)
      75                 :          0 :                 sb->s_fs_info = data;
      76                 :          0 :         return error;
      77                 :            : }
      78                 :            : 
      79                 :            : /**
      80                 :            :  * kernfs_super_ns - determine the namespace tag of a kernfs super_block
      81                 :            :  * @sb: super_block of interest
      82                 :            :  *
      83                 :            :  * Return the namespace tag associated with kernfs super_block @sb.
      84                 :            :  */
      85                 :          0 : const void *kernfs_super_ns(struct super_block *sb)
      86                 :            : {
      87                 :          0 :         struct kernfs_super_info *info = kernfs_info(sb);
      88                 :            : 
      89                 :          0 :         return info->ns;
      90                 :            : }
      91                 :            : 
      92                 :            : /**
      93                 :            :  * kernfs_mount_ns - kernfs mount helper
      94                 :            :  * @fs_type: file_system_type of the fs being mounted
      95                 :            :  * @flags: mount flags specified for the mount
      96                 :            :  * @root: kernfs_root of the hierarchy being mounted
      97                 :            :  * @new_sb_created: tell the caller if we allocated a new superblock
      98                 :            :  * @ns: optional namespace tag of the mount
      99                 :            :  *
     100                 :            :  * This is to be called from each kernfs user's file_system_type->mount()
     101                 :            :  * implementation, which should pass through the specified @fs_type and
     102                 :            :  * @flags, and specify the hierarchy and namespace tag to mount via @root
     103                 :            :  * and @ns, respectively.
     104                 :            :  *
     105                 :            :  * The return value can be passed to the vfs layer verbatim.
     106                 :            :  */
     107                 :          0 : struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags,
     108                 :            :                                struct kernfs_root *root, bool *new_sb_created,
     109                 :            :                                const void *ns)
     110                 :            : {
     111                 :            :         struct super_block *sb;
     112                 :            :         struct kernfs_super_info *info;
     113                 :            :         int error;
     114                 :            : 
     115                 :            :         info = kzalloc(sizeof(*info), GFP_KERNEL);
     116         [ #  # ]:          0 :         if (!info)
     117                 :            :                 return ERR_PTR(-ENOMEM);
     118                 :            : 
     119                 :          0 :         info->root = root;
     120                 :          0 :         info->ns = ns;
     121                 :            : 
     122                 :          0 :         sb = sget(fs_type, kernfs_test_super, kernfs_set_super, flags, info);
     123 [ #  # ][ #  # ]:          0 :         if (IS_ERR(sb) || sb->s_fs_info != info)
     124                 :          0 :                 kfree(info);
     125         [ #  # ]:          0 :         if (IS_ERR(sb))
     126                 :            :                 return ERR_CAST(sb);
     127                 :            : 
     128         [ #  # ]:          0 :         if (new_sb_created)
     129                 :          0 :                 *new_sb_created = !sb->s_root;
     130                 :            : 
     131         [ #  # ]:          0 :         if (!sb->s_root) {
     132                 :          0 :                 error = kernfs_fill_super(sb);
     133         [ #  # ]:          0 :                 if (error) {
     134                 :          0 :                         deactivate_locked_super(sb);
     135                 :          0 :                         return ERR_PTR(error);
     136                 :            :                 }
     137                 :          0 :                 sb->s_flags |= MS_ACTIVE;
     138                 :            :         }
     139                 :            : 
     140                 :          0 :         return dget(sb->s_root);
     141                 :            : }
     142                 :            : 
     143                 :            : /**
     144                 :            :  * kernfs_kill_sb - kill_sb for kernfs
     145                 :            :  * @sb: super_block being killed
     146                 :            :  *
     147                 :            :  * This can be used directly for file_system_type->kill_sb().  If a kernfs
     148                 :            :  * user needs extra cleanup, it can implement its own kill_sb() and call
     149                 :            :  * this function at the end.
     150                 :            :  */
     151                 :          0 : void kernfs_kill_sb(struct super_block *sb)
     152                 :            : {
     153                 :          0 :         struct kernfs_super_info *info = kernfs_info(sb);
     154                 :          0 :         struct kernfs_node *root_kn = sb->s_root->d_fsdata;
     155                 :            : 
     156                 :            :         /*
     157                 :            :          * Remove the superblock from fs_supers/s_instances
     158                 :            :          * so we can't find it, before freeing kernfs_super_info.
     159                 :            :          */
     160                 :          0 :         kill_anon_super(sb);
     161                 :          0 :         kfree(info);
     162                 :          0 :         kernfs_put(root_kn);
     163                 :          0 : }
     164                 :            : 
     165                 :          0 : void __init kernfs_init(void)
     166                 :            : {
     167                 :          0 :         kernfs_node_cache = kmem_cache_create("kernfs_node_cache",
     168                 :            :                                               sizeof(struct kernfs_node),
     169                 :            :                                               0, SLAB_PANIC, NULL);
     170                 :          0 :         kernfs_inode_init();
     171                 :          0 : }

Generated by: LCOV version 1.9