mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
debugfs: add support for more elaborate ->d_fsdata
Currently, the user provided fops, "real_fops", are stored directly into ->d_fsdata. In order to be able to store more per-file state and thus prepare for more granular file removal protection, wrap the real_fops into a dynamically allocated container struct, debugfs_fsdata. A struct debugfs_fsdata gets allocated at file creation and freed from the newly intoduced ->d_release(). Finally, move the implementation of debugfs_real_fops() out of the public debugfs header such that struct debugfs_fsdata's declaration can be kept private. Signed-off-by: Nicolai Stange <nicstange@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2ec1615017
commit
7c8d469877
4 changed files with 38 additions and 20 deletions
|
@ -185,6 +185,11 @@ static const struct super_operations debugfs_super_operations = {
|
|||
.evict_inode = debugfs_evict_inode,
|
||||
};
|
||||
|
||||
static void debugfs_release_dentry(struct dentry *dentry)
|
||||
{
|
||||
kfree(dentry->d_fsdata);
|
||||
}
|
||||
|
||||
static struct vfsmount *debugfs_automount(struct path *path)
|
||||
{
|
||||
debugfs_automount_t f;
|
||||
|
@ -194,6 +199,7 @@ static struct vfsmount *debugfs_automount(struct path *path)
|
|||
|
||||
static const struct dentry_operations debugfs_dops = {
|
||||
.d_delete = always_delete_dentry,
|
||||
.d_release = debugfs_release_dentry,
|
||||
.d_automount = debugfs_automount,
|
||||
};
|
||||
|
||||
|
@ -341,24 +347,34 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
|
|||
{
|
||||
struct dentry *dentry;
|
||||
struct inode *inode;
|
||||
struct debugfs_fsdata *fsd;
|
||||
|
||||
fsd = kmalloc(sizeof(*fsd), GFP_KERNEL);
|
||||
if (!fsd)
|
||||
return NULL;
|
||||
|
||||
if (!(mode & S_IFMT))
|
||||
mode |= S_IFREG;
|
||||
BUG_ON(!S_ISREG(mode));
|
||||
dentry = start_creating(name, parent);
|
||||
|
||||
if (IS_ERR(dentry))
|
||||
if (IS_ERR(dentry)) {
|
||||
kfree(fsd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inode = debugfs_get_inode(dentry->d_sb);
|
||||
if (unlikely(!inode))
|
||||
if (unlikely(!inode)) {
|
||||
kfree(fsd);
|
||||
return failed_creating(dentry);
|
||||
}
|
||||
|
||||
inode->i_mode = mode;
|
||||
inode->i_private = data;
|
||||
|
||||
inode->i_fop = proxy_fops;
|
||||
dentry->d_fsdata = (void *)real_fops;
|
||||
fsd->real_fops = real_fops;
|
||||
dentry->d_fsdata = fsd;
|
||||
|
||||
d_instantiate(dentry, inode);
|
||||
fsnotify_create(d_inode(dentry->d_parent), dentry);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue