Example #1
0
static void configfs_d_iput(struct dentry * dentry,
			    struct inode * inode)
{
	struct configfs_dirent * sd = dentry->d_fsdata;

	if (sd) {
		BUG_ON(sd->s_dentry != dentry);
		sd->s_dentry = NULL;
		configfs_put(sd);
	}
	iput(inode);
}
Example #2
0
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;
}
Example #4
0
static void configfs_d_iput(struct dentry * dentry,
			    struct inode * inode)
{
	struct configfs_dirent *sd = dentry->d_fsdata;

	if (sd) {
		BUG_ON(sd->s_dentry != dentry);
		/* Coordinate with configfs_readdir */
		spin_lock(&configfs_dirent_lock);
		sd->s_dentry = NULL;
		spin_unlock(&configfs_dirent_lock);
		configfs_put(sd);
	}
	iput(inode);
}
Example #5
0
static void configfs_d_iput(struct dentry * dentry,
			    struct inode * inode)
{
	struct configfs_dirent *sd = dentry->d_fsdata;

	if (sd) {
		/* Coordinate with configfs_readdir */
		spin_lock(&configfs_dirent_lock);
		/* Coordinate with configfs_attach_attr where will increase
		 * sd->s_count and update sd->s_dentry to new allocated one.
		 * Only set sd->dentry to null when this dentry is the only
		 * sd owner.
		 * If not do so, configfs_d_iput may run just after
		 * configfs_attach_attr and set sd->s_dentry to null
		 * even it's still in use.
		 */
		if (atomic_read(&sd->s_count) <= 2)
			sd->s_dentry = NULL;

		spin_unlock(&configfs_dirent_lock);
		configfs_put(sd);
	}
	iput(inode);
}