Skip to content

Commit 5570869

Browse files
Gu Zhengbcrl
authored andcommitted
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>
1 parent 47188d3 commit 5570869

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

fs/anon_inodes.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,72 @@ static struct file_system_type anon_inode_fs_type = {
108108
.kill_sb = kill_anon_super,
109109
};
110110

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+
111177
/**
112178
* anon_inode_getfile - creates a new file instance by hooking it up to an
113179
* anonymous inode, and a dentry that describe the "class"

include/linux/anon_inodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ struct file_operations;
1313
struct file *anon_inode_getfile(const char *name,
1414
const struct file_operations *fops,
1515
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);
1619
int anon_inode_getfd(const char *name, const struct file_operations *fops,
1720
void *priv, int flags);
1821

0 commit comments

Comments
 (0)