... and deal with grabbing/dropping it in the sole caller. After that configfs_remove_dir() becomes an unconditional call of remove_dir(), so we can fold them together. Reviewed-by: Jan Kara Signed-off-by: Al Viro --- fs/configfs/dir.c | 60 ++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 6580c919ee5a..11e2597fb1e2 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -395,7 +395,18 @@ int configfs_create_link(struct configfs_dirent *target, struct dentry *parent, return PTR_ERR(inode); } -static void remove_dir(struct dentry * d) +/** + * configfs_remove_dir - remove an config_item's directory. + * @d: dentry we're removing. + * + * The only thing special about this is that we remove any files in + * the directory before we remove the directory, and we've inlined + * what used to be configfs_rmdir() below, instead of calling separately. + * + * Caller holds the mutex of the item's inode + */ + +static void configfs_remove_dir(struct dentry *d) { struct dentry * parent = dget(d->d_parent); @@ -415,31 +426,6 @@ static void remove_dir(struct dentry * d) dput(parent); } -/** - * configfs_remove_dir - remove an config_item's directory. - * @item: config_item we're removing. - * - * The only thing special about this is that we remove any files in - * the directory before we remove the directory, and we've inlined - * what used to be configfs_rmdir() below, instead of calling separately. - * - * Caller holds the mutex of the item's inode - */ - -static void configfs_remove_dir(struct config_item * item) -{ - struct dentry * dentry = dget(item->ci_dentry); - - if (!dentry) - return; - - remove_dir(dentry); - /** - * Drop reference from dget() on entrance. - */ - dput(dentry); -} - static struct dentry * configfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) @@ -591,17 +577,12 @@ static struct configfs_dirent *next_dirent(struct configfs_dirent *parent, return NULL; } -static void detach_attrs(struct config_item * item) +static void detach_attrs(struct dentry *dentry) { - struct dentry * dentry = dget(item->ci_dentry); struct configfs_dirent *parent_sd; struct configfs_dirent *sd, *next; - if (!dentry) - return; - - pr_debug("configfs %s: dropping attrs for dir\n", - dentry->d_name.name); + pr_debug("configfs %pd: dropping attrs for dir\n", dentry); parent_sd = dentry->d_fsdata; @@ -617,11 +598,6 @@ static void detach_attrs(struct config_item * item) spin_lock(&configfs_dirent_lock); } spin_unlock(&configfs_dirent_lock); - - /** - * Drop reference from dget() on entrance. - */ - dput(dentry); } static int populate_attrs(struct config_item *item) @@ -851,8 +827,12 @@ static void link_group(struct config_group *parent_group, struct config_group *g /* Caller holds the mutex of the item's inode */ static void configfs_detach_item(struct config_item *item) { - detach_attrs(item); - configfs_remove_dir(item); + struct dentry *dentry = dget(item->ci_dentry); + if (dentry) { + detach_attrs(dentry); + configfs_remove_dir(dentry); + dput(dentry); + } } /* -- 2.47.3