configfs: factor dirent removal into helpers

Lots of duplicated code that benefits from a little consolidation.

Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Christoph Hellwig 2019-09-11 08:50:46 +02:00
parent 351e5d869e
commit 1cf7a003b0

View File

@ -253,6 +253,18 @@ int configfs_make_dirent(struct configfs_dirent * parent_sd,
return 0; 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) static void init_dir(struct inode * inode)
{ {
inode->i_op = &configfs_dir_inode_operations; 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); configfs_set_dir_dirent_depth(p->d_fsdata, dentry->d_fsdata);
error = configfs_create(dentry, mode, init_dir); error = configfs_create(dentry, mode, init_dir);
if (!error) { if (error)
inc_nlink(d_inode(p)); goto out_remove;
item->ci_dentry = dentry;
} else { inc_nlink(d_inode(p));
struct configfs_dirent *sd = dentry->d_fsdata; item->ci_dentry = dentry;
if (sd) { return 0;
spin_lock(&configfs_dirent_lock);
list_del_init(&sd->s_sibling); out_remove:
spin_unlock(&configfs_dirent_lock); configfs_remove_dirent(dentry);
configfs_put(sd);
}
}
return error; return error;
} }
@ -372,31 +381,25 @@ int configfs_create_link(struct configfs_symlink *sl,
err = configfs_make_dirent(p, dentry, sl, mode, err = configfs_make_dirent(p, dentry, sl, mode,
CONFIGFS_ITEM_LINK, p->s_frag); CONFIGFS_ITEM_LINK, p->s_frag);
if (!err) { if (err)
err = configfs_create(dentry, mode, init_symlink); return err;
if (err) {
struct configfs_dirent *sd = dentry->d_fsdata; err = configfs_create(dentry, mode, init_symlink);
if (sd) { if (err)
spin_lock(&configfs_dirent_lock); goto out_remove;
list_del_init(&sd->s_sibling); return 0;
spin_unlock(&configfs_dirent_lock);
configfs_put(sd); out_remove:
} configfs_remove_dirent(dentry);
}
}
return err; return err;
} }
static void remove_dir(struct dentry * d) static void remove_dir(struct dentry * d)
{ {
struct dentry * parent = dget(d->d_parent); struct dentry * parent = dget(d->d_parent);
struct configfs_dirent * sd;
sd = d->d_fsdata; configfs_remove_dirent(d);
spin_lock(&configfs_dirent_lock);
list_del_init(&sd->s_sibling);
spin_unlock(&configfs_dirent_lock);
configfs_put(sd);
if (d_really_is_positive(d)) if (d_really_is_positive(d))
simple_rmdir(d_inode(parent),d); simple_rmdir(d_inode(parent),d);