From: Cornelia Huck <cornelia.huck@de.ibm.com>
To: Greg KH <greg@kroah.com>
Cc: Jeff Garzik <jeff@garzik.org>,
LKML <linux-kernel@vger.kernel.org>,
Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH 1/3] drivers/base/core: improve device_add() error handling, fix bugs
Date: Wed, 18 Jul 2007 10:57:14 +0200 [thread overview]
Message-ID: <20070718105714.2ff2facb@gondolin.boeblingen.de.ibm.com> (raw)
In-Reply-To: <20070718083600.GA21650@kroah.com>
On Wed, 18 Jul 2007 01:36:00 -0700,
Greg KH <greg@kroah.com> wrote:
> Or it should be, hm, Cornelia, can you resend it, I seem to have dropped
> it :(
Andrew just did :)
(For reference, here's the patch:)
> From: akpm@linux-foundation.org
> To: greg@kroah.com
> Cc: akpm@linux-foundation.org, cornelia.huck@de.ibm.com
> Subject: [patch 1/1] Driver core: check return code of sysfs_create_link()
> Date: Wed, 18 Jul 2007 01:43:47 -0700
>
> From: Cornelia Huck <cornelia.huck@de.ibm.com>
>
> Check for return value of sysfs_create_link() in device_add() and
> device_rename(). Add helper functions device_add_class_symlinks() and
> device_remove_class_symlinks() to make the code easier to read.
>
> [akpm@linux-foundation.org: fix unused var warnings]
> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
> Cc: Greg KH <greg@kroah.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> ---
>
> drivers/base/core.c | 145 ++++++++++++++++++++++++++++++------------
> 1 file changed, 105 insertions(+), 40 deletions(-)
>
> diff -puN drivers/base/core.c~driver-core-check-return-code-of-sysfs_create_link drivers/base/core.c
> --- a/drivers/base/core.c~driver-core-check-return-code-of-sysfs_create_link
> +++ a/drivers/base/core.c
> @@ -643,6 +643,82 @@ static int setup_parent(struct device *d
> return 0;
> }
>
> +static int device_add_class_symlinks(struct device *dev)
> +{
> + int error;
> +
> + if (!dev->class)
> + return 0;
> + error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj,
> + "subsystem");
> + if (error)
> + goto out;
> + /*
> + * 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) {
> + error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
> + dev->bus_id);
> + if (error)
> + goto out_subsys;
> + }
> + /* only bus-device parents get a "device"-link */
> + if (dev->parent && dev->parent->bus) {
> + error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
> + "device");
> + if (error)
> + goto out_busid;
> +#ifdef CONFIG_SYSFS_DEPRECATED
> + {
> + char * class_name = make_class_name(dev->class->name,
> + &dev->kobj);
> + if (class_name)
> + error = sysfs_create_link(&dev->parent->kobj,
> + &dev->kobj, class_name);
> + kfree(class_name);
> + if (error)
> + goto out_device;
> + }
> +#endif
> + }
> + return 0;
> +
> +#ifdef CONFIG_SYSFS_DEPRECATED
> +out_device:
> + if (dev->parent)
> + sysfs_remove_link(&dev->kobj, "device");
> +#endif
> +out_busid:
> + if (dev->kobj.parent != &dev->class->subsys.kobj)
> + sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
> +out_subsys:
> + sysfs_remove_link(&dev->kobj, "subsystem");
> +out:
> + return error;
> +}
> +
> +static void device_remove_class_symlinks(struct device *dev)
> +{
> + if (!dev->class)
> + return;
> + if (dev->parent) {
> +#ifdef CONFIG_SYSFS_DEPRECATED
> + char *class_name;
> +
> + class_name = make_class_name(dev->class->name, &dev->kobj);
> + if (class_name) {
> + sysfs_remove_link(&dev->parent->kobj, class_name);
> + kfree(class_name);
> + }
> +#endif
> + sysfs_remove_link(&dev->kobj, "device");
> + }
> + if (dev->kobj.parent != &dev->class->subsys.kobj)
> + sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
> + sysfs_remove_link(&dev->kobj, "subsystem");
> +}
> +
> /**
> * device_add - add device to device hierarchy.
> * @dev: device.
> @@ -657,7 +733,6 @@ static int setup_parent(struct device *d
> int device_add(struct device *dev)
> {
> struct device *parent = NULL;
> - char *class_name = NULL;
> struct class_interface *class_intf;
> int error = -EINVAL;
>
> @@ -697,27 +772,9 @@ int device_add(struct device *dev)
> goto ueventattrError;
> }
>
> - if (dev->class) {
> - sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj,
> - "subsystem");
> - /* 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 (parent) {
> - sysfs_create_link(&dev->kobj, &dev->parent->kobj,
> - "device");
> -#ifdef CONFIG_SYSFS_DEPRECATED
> - class_name = make_class_name(dev->class->name,
> - &dev->kobj);
> - if (class_name)
> - sysfs_create_link(&dev->parent->kobj,
> - &dev->kobj, class_name);
> -#endif
> - }
> - }
> -
> + error = device_add_class_symlinks(dev);
> + if (error)
> + goto SymlinkError;
> error = device_add_attrs(dev);
> if (error)
> goto AttrsError;
> @@ -744,7 +801,6 @@ int device_add(struct device *dev)
> up(&dev->class->sem);
> }
> Done:
> - kfree(class_name);
> put_device(dev);
> return error;
> BusError:
> @@ -755,6 +811,8 @@ int device_add(struct device *dev)
> BUS_NOTIFY_DEL_DEVICE, dev);
> device_remove_attrs(dev);
> AttrsError:
> + device_remove_class_symlinks(dev);
> + SymlinkError:
> if (MAJOR(dev->devt))
> device_remove_file(dev, &devt_attr);
>
> @@ -1140,7 +1198,7 @@ int device_rename(struct device *dev, ch
> {
> char *old_class_name = NULL;
> char *new_class_name = NULL;
> - char *old_symlink_name = NULL;
> + char *old_device_name = NULL;
> int error;
>
> dev = get_device(dev);
> @@ -1154,42 +1212,49 @@ int device_rename(struct device *dev, ch
> old_class_name = make_class_name(dev->class->name, &dev->kobj);
> #endif
>
> - if (dev->class) {
> - old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
> - if (!old_symlink_name) {
> - error = -ENOMEM;
> - goto out_free_old_class;
> - }
> - strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE);
> + old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
> + if (!old_device_name) {
> + error = -ENOMEM;
> + goto out;
> }
> -
> + strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
> strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
>
> error = kobject_rename(&dev->kobj, new_name);
> + if (error) {
> + strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
> + goto out;
> + }
>
> #ifdef CONFIG_SYSFS_DEPRECATED
> if (old_class_name) {
> new_class_name = make_class_name(dev->class->name, &dev->kobj);
> if (new_class_name) {
> - sysfs_create_link(&dev->parent->kobj, &dev->kobj,
> - new_class_name);
> + error = sysfs_create_link(&dev->parent->kobj,
> + &dev->kobj, new_class_name);
> + if (error)
> + goto out;
> sysfs_remove_link(&dev->parent->kobj, old_class_name);
> }
> }
> #endif
>
> if (dev->class) {
> - sysfs_remove_link(&dev->class->subsys.kobj,
> - old_symlink_name);
> - sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
> - dev->bus_id);
> + sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
> + error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
> + dev->bus_id);
> + if (error) {
> + /* Uh... how to unravel this if restoring can fail? */
> + dev_err(dev, "%s: sysfs_create_symlink failed (%d)\n",
> + __FUNCTION__, error);
> + }
> }
> +out:
> put_device(dev);
>
> kfree(new_class_name);
> - kfree(old_symlink_name);
> - out_free_old_class:
> kfree(old_class_name);
> + kfree(old_device_name);
>
> return error;
> }
> _
next prev parent reply other threads:[~2007-07-18 8:57 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-18 5:53 Jeff Garzik
2007-07-18 5:55 ` [PATCH 2/3] drivers/video/aty/radeon_base: fix radeonfb_pci_register() err handling Jeff Garzik
2007-07-18 5:56 ` [PATCH 3/3] x86-64: make flush_tlb_kernel_range() a static inline function Jeff Garzik
2007-07-18 8:15 ` [PATCH 1/3] drivers/base/core: improve device_add() error handling, fix bugs Cornelia Huck
2007-07-18 8:16 ` Jeff Garzik
2007-07-18 8:36 ` Greg KH
2007-07-18 8:57 ` Cornelia Huck [this message]
2007-07-18 9:00 ` Jeff Garzik
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=20070718105714.2ff2facb@gondolin.boeblingen.de.ibm.com \
--to=cornelia.huck@de.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=greg@kroah.com \
--cc=jeff@garzik.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®