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 /fs | |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/anon_inodes.c | 66 |
1 files changed, 66 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 |