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:
Cornelia Huck
2006-11-20 17:07:51 +01:00
committed by Greg Kroah-Hartman
parent af9e076536
commit 8a82472f86
7 changed files with 228 additions and 4 deletions

View File

@@ -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;