diff options
| author | Gu Zheng <guz.fnst@cn.fujitsu.com> | 2013-07-16 05:56:12 -0400 |
|---|---|---|
| committer | Benjamin LaHaise <bcrl@kvack.org> | 2013-07-16 09:32:17 -0400 |
| commit | 55708698c5f153f4e390175cdfc395333b2eafbd (patch) | |
| tree | b1d915cae064e83af09b9e2001c25429e289ad6b | |
| parent | 47188d39b5deeebf41f87a02af1b3935866364cf (diff) | |
fs/anon_inode: Introduce a new lib function anon_inode_getfile_private()
Introduce a new lib function anon_inode_getfile_private(), it creates a new file
instance by hooking it up to an anonymous inode, and a dentry that describe the
"class" of the file, similar to anon_inode_getfile(), but each file holds a
single inode. Furthermore, anyone who wants to create a private anon file will
benefit from this change.
Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
| -rw-r--r-- | fs/anon_inodes.c | 66 | ||||
| -rw-r--r-- | include/linux/anon_inodes.h | 3 |
2 files changed, 69 insertions, 0 deletions
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 47a65df8c871..85c961849953 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
| @@ -109,6 +109,72 @@ static struct file_system_type anon_inode_fs_type = { | |||
| 109 | }; | 109 | }; |
| 110 | 110 | ||
| 111 | /** | 111 | /** |
| 112 | * anon_inode_getfile_private - creates a new file instance by hooking it up to an | ||
| 113 | * anonymous inode, and a dentry that describe the "class" | ||
| 114 | * of the file | ||
| 115 | * | ||
| 116 | * @name: [in] name of the "class" of the new file | ||
| 117 | * @fops: [in] file operations for the new file | ||
| 118 | * @priv: [in] private data for the new file (will be file's private_data) | ||
| 119 | * @flags: [in] flags | ||
| 120 | * | ||
| 121 | * | ||
| 122 | * Similar to anon_inode_getfile, but each file holds a single inode. | ||
| 123 | * | ||
| 124 | */ | ||
| 125 | struct file *anon_inode_getfile_private(const char *name, | ||
| 126 | const struct file_operations *fops, | ||
| 127 | void *priv, int flags) | ||
| 128 | { | ||
| 129 | struct qstr this; | ||
| 130 | struct path path; | ||
| 131 | struct file *file; | ||
| 132 | struct inode *inode; | ||
| 133 | |||
| 134 | if (fops->owner && !try_module_get(fops->owner)) | ||
| 135 | return ERR_PTR(-ENOENT); | ||
| 136 | |||
| 137 | inode = anon_inode_mkinode(anon_inode_mnt->mnt_sb); | ||
| 138 | if (IS_ERR(inode)) { | ||
| 139 | file = ERR_PTR(-ENOMEM); | ||
| 140 | goto err_module; | ||
| 141 | } | ||
| 142 | |||
| 143 | /* | ||
| 144 | * Link the inode to a directory entry by creating a unique name | ||
| 145 | * using the inode sequence number. | ||
| 146 | */ | ||
| 147 | file = ERR_PTR(-ENOMEM); | ||
| 148 | this.name = name; | ||
| 149 | this.len = strlen(name); | ||
| 150 | this.hash = 0; | ||
| 151 | path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this); | ||
| 152 | if (!path.dentry) | ||
| 153 | goto err_module; | ||
| 154 | |||
| 155 | path.mnt = mntget(anon_inode_mnt); | ||
| 156 | |||
| 157 | d_instantiate(path.dentry, inode); | ||
| 158 | |||
| 159 | file = alloc_file(&path, OPEN_FMODE(flags), fops); | ||
| 160 | if (IS_ERR(file)) | ||
| 161 | goto err_dput; | ||
| 162 | |||
| 163 | file->f_mapping = inode->i_mapping; | ||
| 164 | file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); | ||
| 165 | file->private_data = priv; | ||
| 166 | |||
| 167 | return file; | ||
| 168 | |||
| 169 | err_dput: | ||
| 170 | path_put(&path); | ||
| 171 | err_module: | ||
| 172 | module_put(fops->owner); | ||
| 173 | return file; | ||
| 174 | } | ||
| 175 | EXPORT_SYMBOL_GPL(anon_inode_getfile_private); | ||
| 176 | |||
| 177 | /** | ||
| 112 | * anon_inode_getfile - creates a new file instance by hooking it up to an | 178 | * anon_inode_getfile - creates a new file instance by hooking it up to an |
| 113 | * anonymous inode, and a dentry that describe the "class" | 179 | * anonymous inode, and a dentry that describe the "class" |
| 114 | * of the file | 180 | * of the file |
diff --git a/include/linux/anon_inodes.h b/include/linux/anon_inodes.h index 8013a45242fe..cf573c22b81e 100644 --- a/include/linux/anon_inodes.h +++ b/include/linux/anon_inodes.h | |||
| @@ -13,6 +13,9 @@ struct file_operations; | |||
| 13 | struct file *anon_inode_getfile(const char *name, | 13 | struct file *anon_inode_getfile(const char *name, |
| 14 | const struct file_operations *fops, | 14 | const struct file_operations *fops, |
| 15 | void *priv, int flags); | 15 | void *priv, int flags); |
| 16 | struct file *anon_inode_getfile_private(const char *name, | ||
| 17 | const struct file_operations *fops, | ||
| 18 | void *priv, int flags); | ||
| 16 | int anon_inode_getfd(const char *name, const struct file_operations *fops, | 19 | int anon_inode_getfd(const char *name, const struct file_operations *fops, |
| 17 | void *priv, int flags); | 20 | void *priv, int flags); |
| 18 | 21 | ||
