debugfs: move ->automount into debugfs_inode_info

... and don't bother with debugfs_fsdata for those.  Life's
simpler that way...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Reviewed-by: Christian Brauner <brauner@kernel.org>
Link: https://lore.kernel.org/r/20250112080705.141166-2-viro@zeniv.linux.org.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
pull/1136/head
Al Viro 2025-01-12 08:06:46 +00:00 committed by Greg Kroah-Hartman
parent 268b36116f
commit bacaaf833e
2 changed files with 14 additions and 26 deletions

View File

@ -246,8 +246,8 @@ static void debugfs_release_dentry(struct dentry *dentry)
if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)
return; return;
/* check it wasn't a dir (no fsdata) or automount (no real_fops) */ /* check it wasn't a dir or automount (no fsdata) */
if (fsd && (fsd->real_fops || fsd->short_fops)) { if (fsd) {
WARN_ON(!list_empty(&fsd->cancellations)); WARN_ON(!list_empty(&fsd->cancellations));
mutex_destroy(&fsd->cancellations_mtx); mutex_destroy(&fsd->cancellations_mtx);
} }
@ -257,9 +257,9 @@ static void debugfs_release_dentry(struct dentry *dentry)
static struct vfsmount *debugfs_automount(struct path *path) static struct vfsmount *debugfs_automount(struct path *path)
{ {
struct debugfs_fsdata *fsd = path->dentry->d_fsdata; struct inode *inode = path->dentry->d_inode;
return fsd->automount(path->dentry, d_inode(path->dentry)->i_private); return DEBUGFS_I(inode)->automount(path->dentry, inode->i_private);
} }
static const struct dentry_operations debugfs_dops = { static const struct dentry_operations debugfs_dops = {
@ -642,23 +642,13 @@ struct dentry *debugfs_create_automount(const char *name,
void *data) void *data)
{ {
struct dentry *dentry = start_creating(name, parent); struct dentry *dentry = start_creating(name, parent);
struct debugfs_fsdata *fsd;
struct inode *inode; struct inode *inode;
if (IS_ERR(dentry)) if (IS_ERR(dentry))
return dentry; return dentry;
fsd = kzalloc(sizeof(*fsd), GFP_KERNEL);
if (!fsd) {
failed_creating(dentry);
return ERR_PTR(-ENOMEM);
}
fsd->automount = f;
if (!(debugfs_allow & DEBUGFS_ALLOW_API)) { if (!(debugfs_allow & DEBUGFS_ALLOW_API)) {
failed_creating(dentry); failed_creating(dentry);
kfree(fsd);
return ERR_PTR(-EPERM); return ERR_PTR(-EPERM);
} }
@ -666,14 +656,13 @@ struct dentry *debugfs_create_automount(const char *name,
if (unlikely(!inode)) { if (unlikely(!inode)) {
pr_err("out of free dentries, can not create automount '%s'\n", pr_err("out of free dentries, can not create automount '%s'\n",
name); name);
kfree(fsd);
return failed_creating(dentry); return failed_creating(dentry);
} }
make_empty_dir_inode(inode); make_empty_dir_inode(inode);
inode->i_flags |= S_AUTOMOUNT; inode->i_flags |= S_AUTOMOUNT;
inode->i_private = data; inode->i_private = data;
dentry->d_fsdata = fsd; DEBUGFS_I(inode)->automount = f;
/* directory inodes start off with i_nlink == 2 (for "." entry) */ /* directory inodes start off with i_nlink == 2 (for "." entry) */
inc_nlink(inode); inc_nlink(inode);
d_instantiate(dentry, inode); d_instantiate(dentry, inode);

View File

@ -13,6 +13,9 @@ struct file_operations;
struct debugfs_inode_info { struct debugfs_inode_info {
struct inode vfs_inode; struct inode vfs_inode;
union {
debugfs_automount_t automount;
};
}; };
static inline struct debugfs_inode_info *DEBUGFS_I(struct inode *inode) static inline struct debugfs_inode_info *DEBUGFS_I(struct inode *inode)
@ -29,17 +32,13 @@ extern const struct file_operations debugfs_full_short_proxy_file_operations;
struct debugfs_fsdata { struct debugfs_fsdata {
const struct file_operations *real_fops; const struct file_operations *real_fops;
const struct debugfs_short_fops *short_fops; const struct debugfs_short_fops *short_fops;
union { struct {
/* automount_fn is used when real_fops is NULL */ refcount_t active_users;
debugfs_automount_t automount; struct completion active_users_drained;
struct {
refcount_t active_users;
struct completion active_users_drained;
/* protect cancellations */ /* protect cancellations */
struct mutex cancellations_mtx; struct mutex cancellations_mtx;
struct list_head cancellations; struct list_head cancellations;
};
}; };
}; };