From: Greg KH <greg@kroah.com>
To: linux-kernel@vger.kernel.org
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>,
Greg Kroah-Hartman <gregkh@suse.de>
Subject: [PATCH 6/28] driver core: Allow device_move(dev, NULL).
Date: Wed, 7 Feb 2007 16:29:54 -0800 [thread overview]
Message-ID: <11708946391465-git-send-email-greg@kroah.com> (raw)
In-Reply-To: <11708946362677-git-send-email-greg@kroah.com>
From: Cornelia Huck <cornelia.huck@de.ibm.com>
If we allow NULL as the new parent in device_move(), we need to make sure
that the device is placed into the same place as it would if it was
newly registered:
- Consider the device virtual tree. In order to be able to reuse code,
setup_parent() has been tweaked a bit.
- kobject_move() can fall back to the kset's kobject.
- sysfs_move_dir() uses the sysfs root dir as fallback.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/base/core.c | 76 +++++++++++++++++++++++++++++++-------------------
fs/sysfs/dir.c | 6 +---
lib/kobject.c | 6 ++--
3 files changed, 52 insertions(+), 36 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 36eedfd..c60114d 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -390,22 +390,23 @@ void device_initialize(struct device *dev)
}
#ifdef CONFIG_SYSFS_DEPRECATED
-static int setup_parent(struct device *dev, struct device *parent)
+static struct kobject * get_device_parent(struct device *dev,
+ struct device *parent)
{
/* Set the parent to the class, not the parent device */
/* this keeps sysfs from having a symlink to make old udevs happy */
if (dev->class)
- dev->kobj.parent = &dev->class->subsys.kset.kobj;
+ return &dev->class->subsys.kset.kobj;
else if (parent)
- dev->kobj.parent = &parent->kobj;
+ return &parent->kobj;
- return 0;
+ return NULL;
}
#else
-static int virtual_device_parent(struct device *dev)
+static struct kobject * virtual_device_parent(struct device *dev)
{
if (!dev->class)
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
if (!dev->class->virtual_dir) {
static struct kobject *virtual_dir = NULL;
@@ -415,25 +416,31 @@ static int virtual_device_parent(struct device *dev)
dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name);
}
- dev->kobj.parent = dev->class->virtual_dir;
- return 0;
+ return dev->class->virtual_dir;
}
-static int setup_parent(struct device *dev, struct device *parent)
+static struct kobject * get_device_parent(struct device *dev,
+ struct device *parent)
{
- int error;
-
/* if this is a class device, and has no parent, create one */
if ((dev->class) && (parent == NULL)) {
- error = virtual_device_parent(dev);
- if (error)
- return error;
+ return virtual_device_parent(dev);
} else if (parent)
- dev->kobj.parent = &parent->kobj;
+ return &parent->kobj;
+ return NULL;
+}
+#endif
+static int setup_parent(struct device *dev, struct device *parent)
+{
+ struct kobject *kobj;
+ kobj = get_device_parent(dev, parent);
+ if (IS_ERR(kobj))
+ return PTR_ERR(kobj);
+ if (kobj)
+ dev->kobj.parent = kobj;
return 0;
}
-#endif
/**
* device_add - add device to device hierarchy.
@@ -976,12 +983,18 @@ static int device_move_class_links(struct device *dev,
sysfs_remove_link(&dev->kobj, "device");
sysfs_remove_link(&old_parent->kobj, class_name);
}
- error = sysfs_create_link(&dev->kobj, &new_parent->kobj, "device");
- if (error)
- goto out;
- error = sysfs_create_link(&new_parent->kobj, &dev->kobj, class_name);
- if (error)
- sysfs_remove_link(&dev->kobj, "device");
+ if (new_parent) {
+ error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
+ "device");
+ if (error)
+ goto out;
+ error = sysfs_create_link(&new_parent->kobj, &dev->kobj,
+ class_name);
+ if (error)
+ sysfs_remove_link(&dev->kobj, "device");
+ }
+ else
+ error = 0;
out:
kfree(class_name);
return error;
@@ -993,25 +1006,28 @@ out:
/**
* device_move - moves a device to a new parent
* @dev: the pointer to the struct device to be moved
- * @new_parent: the new parent of the device
+ * @new_parent: the new parent of the device (can by NULL)
*/
int device_move(struct device *dev, struct device *new_parent)
{
int error;
struct device *old_parent;
+ struct kobject *new_parent_kobj;
dev = get_device(dev);
if (!dev)
return -EINVAL;
new_parent = get_device(new_parent);
- if (!new_parent) {
- error = -EINVAL;
+ new_parent_kobj = get_device_parent (dev, new_parent);
+ if (IS_ERR(new_parent_kobj)) {
+ error = PTR_ERR(new_parent_kobj);
+ put_device(new_parent);
goto out;
}
pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id,
- new_parent->bus_id);
- error = kobject_move(&dev->kobj, &new_parent->kobj);
+ new_parent ? new_parent->bus_id : "<NULL>");
+ error = kobject_move(&dev->kobj, new_parent_kobj);
if (error) {
put_device(new_parent);
goto out;
@@ -1020,7 +1036,8 @@ int device_move(struct device *dev, struct device *new_parent)
dev->parent = new_parent;
if (old_parent)
klist_remove(&dev->knode_parent);
- klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
+ if (new_parent)
+ klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
if (!dev->class)
goto out_put;
error = device_move_class_links(dev, old_parent, new_parent);
@@ -1028,7 +1045,8 @@ int device_move(struct device *dev, struct device *new_parent)
/* We ignore errors on cleanup since we're hosed anyway... */
device_move_class_links(dev, new_parent, old_parent);
if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
- klist_remove(&dev->knode_parent);
+ if (new_parent)
+ klist_remove(&dev->knode_parent);
if (old_parent)
klist_add_tail(&dev->knode_parent,
&old_parent->klist_children);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 511edef..2bab1b4 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -378,12 +378,10 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent)
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;
+ new_parent_dentry = new_parent ?
+ new_parent->dentry : sysfs_mount->mnt_sb->s_root;
again:
mutex_lock(&old_parent_dentry->d_inode->i_mutex);
diff --git a/lib/kobject.c b/lib/kobject.c
index 9aed594..c033dc8 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -314,7 +314,7 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
/**
* kobject_move - move object to another parent
* @kobj: object in question.
- * @new_parent: object's new parent
+ * @new_parent: object's new parent (can be NULL)
*/
int kobject_move(struct kobject *kobj, struct kobject *new_parent)
@@ -330,8 +330,8 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
return -EINVAL;
new_parent = kobject_get(new_parent);
if (!new_parent) {
- error = -EINVAL;
- goto out;
+ if (kobj->kset)
+ new_parent = kobject_get(&kobj->kset->kobj);
}
/* old object path */
devpath = kobject_get_path(kobj, GFP_KERNEL);
--
1.4.4.4
next prev parent reply other threads:[~2007-02-08 0:39 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-08 0:29 [GIT PATCH] Driver core patches for 2.6.20 Greg KH
2007-02-08 0:29 ` [PATCH 1/28] Kobject: make kobject apis more robust in handling NULL pointers Greg KH
2007-02-08 0:29 ` [PATCH 2/28] Driver core: convert pcmcia code to use struct device Greg KH
2007-02-08 0:29 ` [PATCH 3/28] Driver core: convert SPI " Greg KH
2007-02-08 0:29 ` [PATCH 4/28] Network: convert network devices to use struct device instead of class_device Greg KH
2007-02-08 0:29 ` [PATCH 5/28] driver core: Remove device_is_registered() in device_move() Greg KH
2007-02-08 0:29 ` Greg KH [this message]
2007-02-08 0:29 ` [PATCH 7/28] MODULES: add the module name for built in kernel drivers Greg KH
2007-02-08 0:29 ` [PATCH 8/28] Modules: only add drivers/ direcory if needed Greg KH
2007-02-08 0:29 ` [PATCH 9/28] PCI: add the sysfs driver name to all modules Greg KH
2007-02-08 0:29 ` [PATCH 10/28] SERIO: " Greg KH
2007-02-08 0:29 ` [PATCH 11/28] USB: " Greg KH
2007-02-08 0:30 ` [PATCH 12/28] /sys/modules/*/holders Greg KH
2007-02-08 0:30 ` [PATCH 13/28] driver core fixes: make_class_name() retval checks Greg KH
2007-02-08 0:30 ` [PATCH 14/28] driver core fixes: device_register() retval check in platform.c Greg KH
2007-02-08 0:30 ` [PATCH 15/28] driver core: Don't stop probing on ->probe errors Greg KH
2007-02-08 0:30 ` [PATCH 16/28] driver core: Change function call order in device_bind_driver() Greg KH
2007-02-08 0:30 ` [PATCH 17/28] Driver core: fix race in sysfs between sysfs_remove_file() and read()/write() Greg KH
2007-02-08 0:30 ` [PATCH 18/28] sysfs: suppress lockdep warnings Greg KH
2007-02-08 0:30 ` [PATCH 19/28] sysfs: kobject_put cleanup Greg KH
2007-02-08 0:30 ` [PATCH 20/28] kobject: " Greg KH
2007-02-08 0:30 ` [PATCH 21/28] sysfs: error handling in sysfs, fill_read_buffer() Greg KH
2007-02-08 0:30 ` [PATCH 22/28] HOWTO: Add a reference to Harbison and Steele Greg KH
2007-02-08 0:30 ` [PATCH 23/28] SYSFS: Fix missing include of list.h in sysfs.h Greg KH
2007-02-08 0:30 ` [PATCH 24/28] Driver core: add uevent vars for devices of a class Greg KH
2007-02-08 0:30 ` [PATCH 25/28] Driver core: add device_type to struct device Greg KH
2007-02-08 0:30 ` [PATCH 26/28] Driver core: allow to delay the uevent at device creation time Greg KH
2007-02-08 0:30 ` [PATCH 27/28] Driver Core: Increase the default timeout value of the firmware subsystem Greg KH
2007-02-08 0:30 ` [PATCH 28/28] sysfs: Shadow directory support Greg KH
2007-02-08 17:20 ` [PATCH 10/28] SERIO: add the sysfs driver name to all modules Dmitry Torokhov
2007-02-08 18:51 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=11708946391465-git-send-email-greg@kroah.com \
--to=greg@kroah.com \
--cc=cornelia.huck@de.ibm.com \
--cc=gregkh@suse.de \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.