Messages in this thread Patch in this message | | | Date | Wed, 18 Jul 2007 01:53:48 -0400 | From | Jeff Garzik <> | Subject | [PATCH 1/3] drivers/base/core: improve device_add() error handling, fix bugs |
| |
The following change was checked into 'warnings' branch of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git
commit 5330916f5a11d8b7def46a6b3e14a831684032f5 Author: Jeff Garzik <jeff@garzik.org> Date: Wed Jul 18 01:41:29 2007 -0400
drivers/base/core: improve device_add() error handling, fix bugs
* silence several warnings by handling sysfs_create_link() failure
* re-order some operations in error handling, to precisely reverse the order of operations, i.e. unwind properly.
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/base/core.c | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-)
5330916f5a11d8b7def46a6b3e14a831684032f5 diff --git a/drivers/base/core.c b/drivers/base/core.c index 0455aa7..f26c005 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -698,16 +698,26 @@ int device_add(struct device *dev) } if (dev->class) { - sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, - "subsystem"); + error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, + "subsystem"); + if (error) + goto ClassSubsysError; + /* If this is not a "fake" compatible device, then create the * symlink from the class to the device. */ - if (dev->kobj.parent != &dev->class->subsys.kobj) - sysfs_create_link(&dev->class->subsys.kobj, - &dev->kobj, dev->bus_id); + if (dev->kobj.parent != &dev->class->subsys.kobj) { + error = sysfs_create_link(&dev->class->subsys.kobj, + &dev->kobj, dev->bus_id); + if (error) + goto ClassDevLinkError; + } + if (parent) { - sysfs_create_link(&dev->kobj, &dev->parent->kobj, - "device"); + error = sysfs_create_link(&dev->kobj,&dev->parent->kobj, + "device"); + if (error) + goto ParentDevLinkError; + #ifdef CONFIG_SYSFS_DEPRECATED class_name = make_class_name(dev->class->name, &dev->kobj); @@ -755,16 +765,7 @@ int device_add(struct device *dev) BUS_NOTIFY_DEL_DEVICE, dev); device_remove_attrs(dev); AttrsError: - if (MAJOR(dev->devt)) - device_remove_file(dev, &devt_attr); - if (dev->class) { - sysfs_remove_link(&dev->kobj, "subsystem"); - /* If this is not a "fake" compatible device, remove the - * symlink from the class to the device. */ - if (dev->kobj.parent != &dev->class->subsys.kobj) - sysfs_remove_link(&dev->class->subsys.kobj, - dev->bus_id); if (parent) { #ifdef CONFIG_SYSFS_DEPRECATED char *class_name = make_class_name(dev->class->name, @@ -776,7 +777,20 @@ int device_add(struct device *dev) #endif sysfs_remove_link(&dev->kobj, "device"); } + + ParentDevLinkError: + /* If this is not a "fake" compatible device, remove the + * symlink from the class to the device. */ + if (dev->kobj.parent != &dev->class->subsys.kobj) + sysfs_remove_link(&dev->class->subsys.kobj, + dev->bus_id); + + ClassDevLinkError: + sysfs_remove_link(&dev->kobj, "subsystem"); } + ClassSubsysError: + if (MAJOR(dev->devt)) + device_remove_file(dev, &devt_attr); ueventattrError: device_remove_file(dev, &uevent_attr); attrError: - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |