Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55708698 authored by Gu Zheng's avatar Gu Zheng Committed by Benjamin LaHaise
Browse files

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: default avatarGu Zheng <guz.fnst@cn.fujitsu.com>
Signed-off-by: default avatarBenjamin LaHaise <bcrl@kvack.org>
parent 47188d39
Loading
Loading
Loading
Loading
+66 −0
Original line number Diff line number Diff line
@@ -108,6 +108,72 @@ static struct file_system_type anon_inode_fs_type = {
	.kill_sb	= kill_anon_super,
};

/**
 * anon_inode_getfile_private - creates a new file instance by hooking it up to an
 *                      anonymous inode, and a dentry that describe the "class"
 *                      of the file
 *
 * @name:    [in]    name of the "class" of the new file
 * @fops:    [in]    file operations for the new file
 * @priv:    [in]    private data for the new file (will be file's private_data)
 * @flags:   [in]    flags
 *
 *
 * Similar to anon_inode_getfile, but each file holds a single inode.
 *
 */
struct file *anon_inode_getfile_private(const char *name,
					const struct file_operations *fops,
					void *priv, int flags)
{
	struct qstr this;
	struct path path;
	struct file *file;
	struct inode *inode;

	if (fops->owner && !try_module_get(fops->owner))
		return ERR_PTR(-ENOENT);

	inode = anon_inode_mkinode(anon_inode_mnt->mnt_sb);
	if (IS_ERR(inode)) {
		file = ERR_PTR(-ENOMEM);
		goto err_module;
	}

	/*
	 * Link the inode to a directory entry by creating a unique name
	 * using the inode sequence number.
	 */
	file = ERR_PTR(-ENOMEM);
	this.name = name;
	this.len = strlen(name);
	this.hash = 0;
	path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this);
	if (!path.dentry)
		goto err_module;

	path.mnt = mntget(anon_inode_mnt);

	d_instantiate(path.dentry, inode);

	file = alloc_file(&path, OPEN_FMODE(flags), fops);
	if (IS_ERR(file))
		goto err_dput;

	file->f_mapping = inode->i_mapping;
	file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
	file->private_data = priv;

	return file;

err_dput:
	path_put(&path);
err_module:
	module_put(fops->owner);
	return file;
}
EXPORT_SYMBOL_GPL(anon_inode_getfile_private);

/**
 * anon_inode_getfile - creates a new file instance by hooking it up to an
 *                      anonymous inode, and a dentry that describe the "class"
+3 −0
Original line number Diff line number Diff line
@@ -13,6 +13,9 @@ struct file_operations;
struct file *anon_inode_getfile(const char *name,
				const struct file_operations *fops,
				void *priv, int flags);
struct file *anon_inode_getfile_private(const char *name,
				const struct file_operations *fops,
				void *priv, int flags);
int anon_inode_getfd(const char *name, const struct file_operations *fops,
		     void *priv, int flags);