Back to home page

LXR

 
 

    


0001 /*
0002  *  fs/anon_inodes.c
0003  *
0004  *  Copyright (C) 2007  Davide Libenzi <davidel@xmailserver.org>
0005  *
0006  *  Thanks to Arnd Bergmann for code review and suggestions.
0007  *  More changes for Thomas Gleixner suggestions.
0008  *
0009  */
0010 
0011 #include <linux/cred.h>
0012 #include <linux/file.h>
0013 #include <linux/poll.h>
0014 #include <linux/sched.h>
0015 #include <linux/init.h>
0016 #include <linux/fs.h>
0017 #include <linux/mount.h>
0018 #include <linux/module.h>
0019 #include <linux/kernel.h>
0020 #include <linux/magic.h>
0021 #include <linux/anon_inodes.h>
0022 
0023 #include <linux/uaccess.h>
0024 
0025 static struct vfsmount *anon_inode_mnt __read_mostly;
0026 static struct inode *anon_inode_inode;
0027 
0028 /*
0029  * anon_inodefs_dname() is called from d_path().
0030  */
0031 static char *anon_inodefs_dname(struct dentry *dentry, char *buffer, int buflen)
0032 {
0033     return dynamic_dname(dentry, buffer, buflen, "anon_inode:%s",
0034                 dentry->d_name.name);
0035 }
0036 
0037 static const struct dentry_operations anon_inodefs_dentry_operations = {
0038     .d_dname    = anon_inodefs_dname,
0039 };
0040 
0041 static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
0042                 int flags, const char *dev_name, void *data)
0043 {
0044     return mount_pseudo(fs_type, "anon_inode:", NULL,
0045             &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC);
0046 }
0047 
0048 static struct file_system_type anon_inode_fs_type = {
0049     .name       = "anon_inodefs",
0050     .mount      = anon_inodefs_mount,
0051     .kill_sb    = kill_anon_super,
0052 };
0053 
0054 /**
0055  * anon_inode_getfile - creates a new file instance by hooking it up to an
0056  *                      anonymous inode, and a dentry that describe the "class"
0057  *                      of the file
0058  *
0059  * @name:    [in]    name of the "class" of the new file
0060  * @fops:    [in]    file operations for the new file
0061  * @priv:    [in]    private data for the new file (will be file's private_data)
0062  * @flags:   [in]    flags
0063  *
0064  * Creates a new file by hooking it on a single inode. This is useful for files
0065  * that do not need to have a full-fledged inode in order to operate correctly.
0066  * All the files created with anon_inode_getfile() will share a single inode,
0067  * hence saving memory and avoiding code duplication for the file/inode/dentry
0068  * setup.  Returns the newly created file* or an error pointer.
0069  */
0070 struct file *anon_inode_getfile(const char *name,
0071                 const struct file_operations *fops,
0072                 void *priv, int flags)
0073 {
0074     struct qstr this;
0075     struct path path;
0076     struct file *file;
0077 
0078     if (IS_ERR(anon_inode_inode))
0079         return ERR_PTR(-ENODEV);
0080 
0081     if (fops->owner && !try_module_get(fops->owner))
0082         return ERR_PTR(-ENOENT);
0083 
0084     /*
0085      * Link the inode to a directory entry by creating a unique name
0086      * using the inode sequence number.
0087      */
0088     file = ERR_PTR(-ENOMEM);
0089     this.name = name;
0090     this.len = strlen(name);
0091     this.hash = 0;
0092     path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this);
0093     if (!path.dentry)
0094         goto err_module;
0095 
0096     path.mnt = mntget(anon_inode_mnt);
0097     /*
0098      * We know the anon_inode inode count is always greater than zero,
0099      * so ihold() is safe.
0100      */
0101     ihold(anon_inode_inode);
0102 
0103     d_instantiate(path.dentry, anon_inode_inode);
0104 
0105     file = alloc_file(&path, OPEN_FMODE(flags), fops);
0106     if (IS_ERR(file))
0107         goto err_dput;
0108     file->f_mapping = anon_inode_inode->i_mapping;
0109 
0110     file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
0111     file->private_data = priv;
0112 
0113     return file;
0114 
0115 err_dput:
0116     path_put(&path);
0117 err_module:
0118     module_put(fops->owner);
0119     return file;
0120 }
0121 EXPORT_SYMBOL_GPL(anon_inode_getfile);
0122 
0123 /**
0124  * anon_inode_getfd - creates a new file instance by hooking it up to an
0125  *                    anonymous inode, and a dentry that describe the "class"
0126  *                    of the file
0127  *
0128  * @name:    [in]    name of the "class" of the new file
0129  * @fops:    [in]    file operations for the new file
0130  * @priv:    [in]    private data for the new file (will be file's private_data)
0131  * @flags:   [in]    flags
0132  *
0133  * Creates a new file by hooking it on a single inode. This is useful for files
0134  * that do not need to have a full-fledged inode in order to operate correctly.
0135  * All the files created with anon_inode_getfd() will share a single inode,
0136  * hence saving memory and avoiding code duplication for the file/inode/dentry
0137  * setup.  Returns new descriptor or an error code.
0138  */
0139 int anon_inode_getfd(const char *name, const struct file_operations *fops,
0140              void *priv, int flags)
0141 {
0142     int error, fd;
0143     struct file *file;
0144 
0145     error = get_unused_fd_flags(flags);
0146     if (error < 0)
0147         return error;
0148     fd = error;
0149 
0150     file = anon_inode_getfile(name, fops, priv, flags);
0151     if (IS_ERR(file)) {
0152         error = PTR_ERR(file);
0153         goto err_put_unused_fd;
0154     }
0155     fd_install(fd, file);
0156 
0157     return fd;
0158 
0159 err_put_unused_fd:
0160     put_unused_fd(fd);
0161     return error;
0162 }
0163 EXPORT_SYMBOL_GPL(anon_inode_getfd);
0164 
0165 static int __init anon_inode_init(void)
0166 {
0167     anon_inode_mnt = kern_mount(&anon_inode_fs_type);
0168     if (IS_ERR(anon_inode_mnt))
0169         panic("anon_inode_init() kernel mount failed (%ld)\n", PTR_ERR(anon_inode_mnt));
0170 
0171     anon_inode_inode = alloc_anon_inode(anon_inode_mnt->mnt_sb);
0172     if (IS_ERR(anon_inode_inode))
0173         panic("anon_inode_init() inode allocation failed (%ld)\n", PTR_ERR(anon_inode_inode));
0174 
0175     return 0;
0176 }
0177 
0178 fs_initcall(anon_inode_init);
0179