driver core: Introduce device_move(): move a device to a new parent.
Provide a function device_move() to move a device to a new parent device. Add auxilliary functions kobject_move() and sysfs_move_dir(). kobject_move() generates a new uevent of type KOBJ_MOVE, containing the previous path (DEVPATH_OLD) in addition to the usual values. For this, a new interface kobject_uevent_env() is created that allows to add further environmental data to the uevent at the kobject layer. Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Acked-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
af9e076536
commit
8a82472f86
@@ -372,6 +372,51 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
|
||||
return error;
|
||||
}
|
||||
|
||||
int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent)
|
||||
{
|
||||
struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry;
|
||||
struct sysfs_dirent *new_parent_sd, *sd;
|
||||
int error;
|
||||
|
||||
if (!new_parent)
|
||||
return -EINVAL;
|
||||
|
||||
old_parent_dentry = kobj->parent ?
|
||||
kobj->parent->dentry : sysfs_mount->mnt_sb->s_root;
|
||||
new_parent_dentry = new_parent->dentry;
|
||||
|
||||
again:
|
||||
mutex_lock(&old_parent_dentry->d_inode->i_mutex);
|
||||
if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) {
|
||||
mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
|
||||
goto again;
|
||||
}
|
||||
|
||||
new_parent_sd = new_parent_dentry->d_fsdata;
|
||||
sd = kobj->dentry->d_fsdata;
|
||||
|
||||
new_dentry = lookup_one_len(kobj->name, new_parent_dentry,
|
||||
strlen(kobj->name));
|
||||
if (IS_ERR(new_dentry)) {
|
||||
error = PTR_ERR(new_dentry);
|
||||
goto out;
|
||||
} else
|
||||
error = 0;
|
||||
d_add(new_dentry, NULL);
|
||||
d_move(kobj->dentry, new_dentry);
|
||||
dput(new_dentry);
|
||||
|
||||
/* Remove from old parent's list and insert into new parent's list. */
|
||||
list_del_init(&sd->s_sibling);
|
||||
list_add(&sd->s_sibling, &new_parent_sd->s_children);
|
||||
|
||||
out:
|
||||
mutex_unlock(&new_parent_dentry->d_inode->i_mutex);
|
||||
mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int sysfs_dir_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct dentry * dentry = file->f_dentry;
|
||||
|
Reference in New Issue
Block a user