diff options
author | Christoph Hellwig <hch@lst.de> | 2019-09-11 09:50:46 +0300 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2019-09-11 13:45:57 +0300 |
commit | 1cf7a003b044744c06dfa452cd136e71223b5569 (patch) | |
tree | a4f5a278e653ac9e942ccd96d54a3463ac8c02f3 | |
parent | 351e5d869e5ac10cb40c78b5f2d7dfc816ad4587 (diff) | |
download | linux-1cf7a003b044744c06dfa452cd136e71223b5569.tar.xz |
configfs: factor dirent removal into helpers
Lots of duplicated code that benefits from a little consolidation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r-- | fs/configfs/dir.c | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 79fc25aaa8cd..fbd6f9dbe7a6 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -253,6 +253,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; @@ -309,18 +321,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; } @@ -372,31 +381,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); |