From: Christoph Hellwig hch@lst.de
mainline inclusion from mainline-v5.4-rc1 commit 1cf7a003b044744c06dfa452cd136e71223b5569 category: bugfix bugzilla: 187567, https://gitee.com/openeuler/kernel/issues/I5PK1G CVE: NA
--------------------------------
Lots of duplicated code that benefits from a little consolidation.
Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com Reviewed-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- fs/configfs/dir.c | 63 +++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 30 deletions(-)
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 26bd2004fe35..cbec81662a2a 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -274,6 +274,18 @@ int configfs_make_dirent(struct configfs_dirent * parent_sd, return 0; }
+static void configfs_remove_dirent(struct dentry *dentry) +{ + struct configfs_dirent *sd = dentry->d_fsdata; + + if (!sd) + return; + spin_lock(&configfs_dirent_lock); + list_del_init(&sd->s_sibling); + spin_unlock(&configfs_dirent_lock); + configfs_put(sd); +} + static void init_dir(struct inode * inode) { inode->i_op = &configfs_dir_inode_operations; @@ -330,18 +342,15 @@ static int configfs_create_dir(struct config_item *item, struct dentry *dentry,
configfs_set_dir_dirent_depth(p->d_fsdata, dentry->d_fsdata); error = configfs_create(dentry, mode, init_dir); - if (!error) { - inc_nlink(d_inode(p)); - item->ci_dentry = dentry; - } else { - struct configfs_dirent *sd = dentry->d_fsdata; - if (sd) { - spin_lock(&configfs_dirent_lock); - list_del_init(&sd->s_sibling); - spin_unlock(&configfs_dirent_lock); - configfs_put(sd); - } - } + if (error) + goto out_remove; + + inc_nlink(d_inode(p)); + item->ci_dentry = dentry; + return 0; + +out_remove: + configfs_remove_dirent(dentry); return error; }
@@ -393,31 +402,25 @@ int configfs_create_link(struct configfs_symlink *sl,
err = configfs_make_dirent(p, dentry, sl, mode, CONFIGFS_ITEM_LINK, p->s_frag); - if (!err) { - err = configfs_create(dentry, mode, init_symlink); - if (err) { - struct configfs_dirent *sd = dentry->d_fsdata; - if (sd) { - spin_lock(&configfs_dirent_lock); - list_del_init(&sd->s_sibling); - spin_unlock(&configfs_dirent_lock); - configfs_put(sd); - } - } - } + if (err) + return err; + + err = configfs_create(dentry, mode, init_symlink); + if (err) + goto out_remove; + return 0; + +out_remove: + configfs_remove_dirent(dentry); return err; }
static void remove_dir(struct dentry * d) { struct dentry * parent = dget(d->d_parent); - struct configfs_dirent * sd;
- sd = d->d_fsdata; - spin_lock(&configfs_dirent_lock); - list_del_init(&sd->s_sibling); - spin_unlock(&configfs_dirent_lock); - configfs_put(sd); + configfs_remove_dirent(d); + if (d_really_is_positive(d)) simple_rmdir(d_inode(parent),d);