Skip to content

Commit

Permalink
fs/anon_inode: Introduce a new lib function anon_inode_getfile_private()
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Benjamin LaHaise <[email protected]>
  • Loading branch information
Gu Zheng authored and bcrl committed Jul 16, 2013
1 parent 47188d3 commit 5570869
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
66 changes: 66 additions & 0 deletions fs/anon_inodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
3 changes: 3 additions & 0 deletions include/linux/anon_inodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 5570869

Please sign in to comment.