LCOV - code coverage report
Current view: top level - fs - anon_inodes.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 23 41 56.1 %
Date: 2014-04-16 Functions: 3 5 60.0 %
Branches: 6 18 33.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *  fs/anon_inodes.c
       3                 :            :  *
       4                 :            :  *  Copyright (C) 2007  Davide Libenzi <davidel@xmailserver.org>
       5                 :            :  *
       6                 :            :  *  Thanks to Arnd Bergmann for code review and suggestions.
       7                 :            :  *  More changes for Thomas Gleixner suggestions.
       8                 :            :  *
       9                 :            :  */
      10                 :            : 
      11                 :            : #include <linux/cred.h>
      12                 :            : #include <linux/file.h>
      13                 :            : #include <linux/poll.h>
      14                 :            : #include <linux/sched.h>
      15                 :            : #include <linux/init.h>
      16                 :            : #include <linux/fs.h>
      17                 :            : #include <linux/mount.h>
      18                 :            : #include <linux/module.h>
      19                 :            : #include <linux/kernel.h>
      20                 :            : #include <linux/magic.h>
      21                 :            : #include <linux/anon_inodes.h>
      22                 :            : 
      23                 :            : #include <asm/uaccess.h>
      24                 :            : 
      25                 :            : static struct vfsmount *anon_inode_mnt __read_mostly;
      26                 :            : static struct inode *anon_inode_inode;
      27                 :            : 
      28                 :            : /*
      29                 :            :  * anon_inodefs_dname() is called from d_path().
      30                 :            :  */
      31                 :          0 : static char *anon_inodefs_dname(struct dentry *dentry, char *buffer, int buflen)
      32                 :            : {
      33                 :         52 :         return dynamic_dname(dentry, buffer, buflen, "anon_inode:%s",
      34                 :            :                                 dentry->d_name.name);
      35                 :            : }
      36                 :            : 
      37                 :            : static const struct dentry_operations anon_inodefs_dentry_operations = {
      38                 :            :         .d_dname        = anon_inodefs_dname,
      39                 :            : };
      40                 :            : 
      41                 :          0 : static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
      42                 :            :                                 int flags, const char *dev_name, void *data)
      43                 :            : {
      44                 :          0 :         return mount_pseudo(fs_type, "anon_inode:", NULL,
      45                 :            :                         &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC);
      46                 :            : }
      47                 :            : 
      48                 :            : static struct file_system_type anon_inode_fs_type = {
      49                 :            :         .name           = "anon_inodefs",
      50                 :            :         .mount          = anon_inodefs_mount,
      51                 :            :         .kill_sb        = kill_anon_super,
      52                 :            : };
      53                 :            : 
      54                 :            : /**
      55                 :            :  * anon_inode_getfile - creates a new file instance by hooking it up to an
      56                 :            :  *                      anonymous inode, and a dentry that describe the "class"
      57                 :            :  *                      of the file
      58                 :            :  *
      59                 :            :  * @name:    [in]    name of the "class" of the new file
      60                 :            :  * @fops:    [in]    file operations for the new file
      61                 :            :  * @priv:    [in]    private data for the new file (will be file's private_data)
      62                 :            :  * @flags:   [in]    flags
      63                 :            :  *
      64                 :            :  * Creates a new file by hooking it on a single inode. This is useful for files
      65                 :            :  * that do not need to have a full-fledged inode in order to operate correctly.
      66                 :            :  * All the files created with anon_inode_getfile() will share a single inode,
      67                 :            :  * hence saving memory and avoiding code duplication for the file/inode/dentry
      68                 :            :  * setup.  Returns the newly created file* or an error pointer.
      69                 :            :  */
      70                 :          0 : struct file *anon_inode_getfile(const char *name,
      71                 :            :                                 const struct file_operations *fops,
      72                 :            :                                 void *priv, int flags)
      73                 :            : {
      74                 :            :         struct qstr this;
      75                 :            :         struct path path;
      76                 :            :         struct file *file;
      77                 :            : 
      78         [ +  - ]:         90 :         if (IS_ERR(anon_inode_inode))
      79                 :            :                 return ERR_PTR(-ENODEV);
      80                 :            : 
      81 [ -  + ][ #  # ]:         90 :         if (fops->owner && !try_module_get(fops->owner))
      82                 :            :                 return ERR_PTR(-ENOENT);
      83                 :            : 
      84                 :            :         /*
      85                 :            :          * Link the inode to a directory entry by creating a unique name
      86                 :            :          * using the inode sequence number.
      87                 :            :          */
      88                 :            :         file = ERR_PTR(-ENOMEM);
      89                 :         90 :         this.name = name;
      90                 :         90 :         this.len = strlen(name);
      91                 :         90 :         this.hash = 0;
      92                 :         90 :         path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this);
      93         [ +  - ]:         90 :         if (!path.dentry)
      94                 :            :                 goto err_module;
      95                 :            : 
      96                 :         90 :         path.mnt = mntget(anon_inode_mnt);
      97                 :            :         /*
      98                 :            :          * We know the anon_inode inode count is always greater than zero,
      99                 :            :          * so ihold() is safe.
     100                 :            :          */
     101                 :         90 :         ihold(anon_inode_inode);
     102                 :            : 
     103                 :         90 :         d_instantiate(path.dentry, anon_inode_inode);
     104                 :            : 
     105                 :         90 :         file = alloc_file(&path, OPEN_FMODE(flags), fops);
     106         [ +  - ]:        180 :         if (IS_ERR(file))
     107                 :            :                 goto err_dput;
     108                 :         90 :         file->f_mapping = anon_inode_inode->i_mapping;
     109                 :            : 
     110                 :         90 :         file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
     111                 :         90 :         file->private_data = priv;
     112                 :            : 
     113                 :         90 :         return file;
     114                 :            : 
     115                 :            : err_dput:
     116                 :          0 :         path_put(&path);
     117                 :            : err_module:
     118                 :          0 :         module_put(fops->owner);
     119                 :          0 :         return file;
     120                 :            : }
     121                 :            : EXPORT_SYMBOL_GPL(anon_inode_getfile);
     122                 :            : 
     123                 :            : /**
     124                 :            :  * anon_inode_getfd - creates a new file instance by hooking it up to an
     125                 :            :  *                    anonymous inode, and a dentry that describe the "class"
     126                 :            :  *                    of the file
     127                 :            :  *
     128                 :            :  * @name:    [in]    name of the "class" of the new file
     129                 :            :  * @fops:    [in]    file operations for the new file
     130                 :            :  * @priv:    [in]    private data for the new file (will be file's private_data)
     131                 :            :  * @flags:   [in]    flags
     132                 :            :  *
     133                 :            :  * Creates a new file by hooking it on a single inode. This is useful for files
     134                 :            :  * that do not need to have a full-fledged inode in order to operate correctly.
     135                 :            :  * All the files created with anon_inode_getfd() will share a single inode,
     136                 :            :  * hence saving memory and avoiding code duplication for the file/inode/dentry
     137                 :            :  * setup.  Returns new descriptor or an error code.
     138                 :            :  */
     139                 :          0 : int anon_inode_getfd(const char *name, const struct file_operations *fops,
     140                 :            :                      void *priv, int flags)
     141                 :            : {
     142                 :            :         int error, fd;
     143                 :            :         struct file *file;
     144                 :            : 
     145                 :         19 :         error = get_unused_fd_flags(flags);
     146         [ +  - ]:         19 :         if (error < 0)
     147                 :            :                 return error;
     148                 :            :         fd = error;
     149                 :            : 
     150                 :         19 :         file = anon_inode_getfile(name, fops, priv, flags);
     151         [ -  + ]:         19 :         if (IS_ERR(file)) {
     152                 :            :                 error = PTR_ERR(file);
     153                 :            :                 goto err_put_unused_fd;
     154                 :            :         }
     155                 :         19 :         fd_install(fd, file);
     156                 :            : 
     157                 :         19 :         return fd;
     158                 :            : 
     159                 :            : err_put_unused_fd:
     160                 :          0 :         put_unused_fd(fd);
     161                 :          0 :         return error;
     162                 :            : }
     163                 :            : EXPORT_SYMBOL_GPL(anon_inode_getfd);
     164                 :            : 
     165                 :          0 : static int __init anon_inode_init(void)
     166                 :            : {
     167                 :          0 :         anon_inode_mnt = kern_mount(&anon_inode_fs_type);
     168         [ #  # ]:          0 :         if (IS_ERR(anon_inode_mnt))
     169                 :          0 :                 panic("anon_inode_init() kernel mount failed (%ld)\n", PTR_ERR(anon_inode_mnt));
     170                 :            : 
     171                 :          0 :         anon_inode_inode = alloc_anon_inode(anon_inode_mnt->mnt_sb);
     172         [ #  # ]:          0 :         if (IS_ERR(anon_inode_inode))
     173                 :          0 :                 panic("anon_inode_init() inode allocation failed (%ld)\n", PTR_ERR(anon_inode_inode));
     174                 :            : 
     175                 :          0 :         return 0;
     176                 :            : }
     177                 :            : 
     178                 :            : fs_initcall(anon_inode_init);
     179                 :            : 

Generated by: LCOV version 1.9