int configfs_unlink(struct inode *dir, struct dentry *dentry) { struct configfs_dirent *sd = dentry->d_fsdata; struct configfs_symlink *sl; struct config_item *parent_item; struct config_item_type *type; int ret; ret = -EPERM; /* What lack-of-symlink returns */ if (!(sd->s_type & CONFIGFS_ITEM_LINK)) goto out; BUG_ON(dentry->d_parent == configfs_sb->s_root); sl = sd->s_element; parent_item = configfs_get_config_item(dentry->d_parent); type = parent_item->ci_type; spin_lock(&configfs_dirent_lock); list_del_init(&sd->s_sibling); spin_unlock(&configfs_dirent_lock); configfs_drop_dentry(sd, dentry->d_parent); dput(dentry); configfs_put(sd); /* * drop_link() must be called before * list_del_init(&sl->sl_list), so that the order of * drop_link(this, target) and drop_item(target) is preserved. */ if (type && type->ct_item_ops && type->ct_item_ops->drop_link) type->ct_item_ops->drop_link(parent_item, sl->sl_target); spin_lock(&configfs_dirent_lock); list_del_init(&sl->sl_list); spin_unlock(&configfs_dirent_lock); /* Put reference from create_link() */ config_item_put(sl->sl_target); kfree(sl); config_item_put(parent_item); ret = 0; out: return ret; }
int configfs_unlink(struct inode *dir, struct dentry *dentry) { struct configfs_dirent *sd = dentry->d_fsdata; struct configfs_symlink *sl; struct config_item *parent_item; struct config_item_type *type; int ret; ret = -EPERM; /* */ if (!(sd->s_type & CONFIGFS_ITEM_LINK)) goto out; sl = sd->s_element; parent_item = configfs_get_config_item(dentry->d_parent); type = parent_item->ci_type; spin_lock(&configfs_dirent_lock); list_del_init(&sd->s_sibling); spin_unlock(&configfs_dirent_lock); configfs_drop_dentry(sd, dentry->d_parent); dput(dentry); configfs_put(sd); /* */ if (type && type->ct_item_ops && type->ct_item_ops->drop_link) type->ct_item_ops->drop_link(parent_item, sl->sl_target); spin_lock(&configfs_dirent_lock); list_del_init(&sl->sl_list); spin_unlock(&configfs_dirent_lock); /* */ config_item_put(sl->sl_target); kfree(sl); config_item_put(parent_item); ret = 0; out: return ret; }