summaryrefslogtreecommitdiff
path: root/fs/configfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2019-09-11 09:50:46 +0300
committerChristoph Hellwig <hch@lst.de>2019-09-11 13:45:57 +0300
commit1cf7a003b044744c06dfa452cd136e71223b5569 (patch)
treea4f5a278e653ac9e942ccd96d54a3463ac8c02f3 /fs/configfs
parent351e5d869e5ac10cb40c78b5f2d7dfc816ad4587 (diff)
downloadlinux-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>
Diffstat (limited to 'fs/configfs')
-rw-r--r--fs/configfs/dir.c63
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);