aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2007-07-18 04:43:47 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-18 18:49:50 -0400
commit2ee97caf0a6602f749ddbfdb1449e383e1212707 (patch)
tree6f0fb8f1c856aeb20149a73b1cb85ba943d11ce8 /drivers
parentbe3884943674f8ee7656b1d8b71c087ec900c836 (diff)
Driver core: check return code of sysfs_create_link()
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> Acked-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/core.c145
1 files changed, 105 insertions, 40 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 91a0367d583e..3599ab2506d2 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -660,6 +660,82 @@ static int setup_parent(struct device *dev, struct device *parent)
660 return 0; 660 return 0;
661} 661}
662 662
663static int device_add_class_symlinks(struct device *dev)
664{
665 int error;
666
667 if (!dev->class)
668 return 0;
669 error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj,
670 "subsystem");
671 if (error)
672 goto out;
673 /*
674 * If this is not a "fake" compatible device, then create the
675 * symlink from the class to the device.
676 */
677 if (dev->kobj.parent != &dev->class->subsys.kobj) {
678 error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
679 dev->bus_id);
680 if (error)
681 goto out_subsys;
682 }
683 /* only bus-device parents get a "device"-link */
684 if (dev->parent && dev->parent->bus) {
685 error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
686 "device");
687 if (error)
688 goto out_busid;
689#ifdef CONFIG_SYSFS_DEPRECATED
690 {
691 char * class_name = make_class_name(dev->class->name,
692 &dev->kobj);
693 if (class_name)
694 error = sysfs_create_link(&dev->parent->kobj,
695 &dev->kobj, class_name);
696 kfree(class_name);
697 if (error)
698 goto out_device;
699 }
700#endif
701 }
702 return 0;
703
704#ifdef CONFIG_SYSFS_DEPRECATED
705out_device:
706 if (dev->parent)
707 sysfs_remove_link(&dev->kobj, "device");
708#endif
709out_busid:
710 if (dev->kobj.parent != &dev->class->subsys.kobj)
711 sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
712out_subsys:
713 sysfs_remove_link(&dev->kobj, "subsystem");
714out:
715 return error;
716}
717
718static void device_remove_class_symlinks(struct device *dev)
719{
720 if (!dev->class)
721 return;
722 if (dev->parent) {
723#ifdef CONFIG_SYSFS_DEPRECATED
724 char *class_name;
725
726 class_name = make_class_name(dev->class->name, &dev->kobj);
727 if (class_name) {
728 sysfs_remove_link(&dev->parent->kobj, class_name);
729 kfree(class_name);
730 }
731#endif
732 sysfs_remove_link(&dev->kobj, "device");
733 }
734 if (dev->kobj.parent != &dev->class->subsys.kobj)
735 sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
736 sysfs_remove_link(&dev->kobj, "subsystem");
737}
738
663/** 739/**
664 * device_add - add device to device hierarchy. 740 * device_add - add device to device hierarchy.
665 * @dev: device. 741 * @dev: device.
@@ -674,7 +750,6 @@ static int setup_parent(struct device *dev, struct device *parent)
674int device_add(struct device *dev) 750int device_add(struct device *dev)
675{ 751{
676 struct device *parent = NULL; 752 struct device *parent = NULL;
677 char *class_name = NULL;
678 struct class_interface *class_intf; 753 struct class_interface *class_intf;
679 int error = -EINVAL; 754 int error = -EINVAL;
680 755
@@ -714,27 +789,9 @@ int device_add(struct device *dev)
714 goto ueventattrError; 789 goto ueventattrError;
715 } 790 }
716 791
717 if (dev->class) { 792 error = device_add_class_symlinks(dev);
718 sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, 793 if (error)
719 "subsystem"); 794 goto SymlinkError;
720 /* If this is not a "fake" compatible device, then create the
721 * symlink from the class to the device. */
722 if (dev->kobj.parent != &dev->class->subsys.kobj)
723 sysfs_create_link(&dev->class->subsys.kobj,
724 &dev->kobj, dev->bus_id);
725 if (parent) {
726 sysfs_create_link(&dev->kobj, &dev->parent->kobj,
727 "device");
728#ifdef CONFIG_SYSFS_DEPRECATED
729 class_name = make_class_name(dev->class->name,
730 &dev->kobj);
731 if (class_name)
732 sysfs_create_link(&dev->parent->kobj,
733 &dev->kobj, class_name);
734#endif
735 }
736 }
737
738 error = device_add_attrs(dev); 795 error = device_add_attrs(dev);
739 if (error) 796 if (error)
740 goto AttrsError; 797 goto AttrsError;
@@ -761,7 +818,6 @@ int device_add(struct device *dev)
761 up(&dev->class->sem); 818 up(&dev->class->sem);
762 } 819 }
763 Done: 820 Done:
764 kfree(class_name);
765 put_device(dev); 821 put_device(dev);
766 return error; 822 return error;
767 BusError: 823 BusError:
@@ -772,6 +828,8 @@ int device_add(struct device *dev)
772 BUS_NOTIFY_DEL_DEVICE, dev); 828 BUS_NOTIFY_DEL_DEVICE, dev);
773 device_remove_attrs(dev); 829 device_remove_attrs(dev);
774 AttrsError: 830 AttrsError:
831 device_remove_class_symlinks(dev);
832 SymlinkError:
775 if (MAJOR(dev->devt)) 833 if (MAJOR(dev->devt))
776 device_remove_file(dev, &devt_attr); 834 device_remove_file(dev, &devt_attr);
777 835
@@ -1156,7 +1214,7 @@ int device_rename(struct device *dev, char *new_name)
1156{ 1214{
1157 char *old_class_name = NULL; 1215 char *old_class_name = NULL;
1158 char *new_class_name = NULL; 1216 char *new_class_name = NULL;
1159 char *old_symlink_name = NULL; 1217 char *old_device_name = NULL;
1160 int error; 1218 int error;
1161 1219
1162 dev = get_device(dev); 1220 dev = get_device(dev);
@@ -1170,42 +1228,49 @@ int device_rename(struct device *dev, char *new_name)
1170 old_class_name = make_class_name(dev->class->name, &dev->kobj); 1228 old_class_name = make_class_name(dev->class->name, &dev->kobj);
1171#endif 1229#endif
1172 1230
1173 if (dev->class) { 1231 old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
1174 old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); 1232 if (!old_device_name) {
1175 if (!old_symlink_name) { 1233 error = -ENOMEM;
1176 error = -ENOMEM; 1234 goto out;
1177 goto out_free_old_class;
1178 }
1179 strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE);
1180 } 1235 }
1181 1236 strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
1182 strlcpy(dev->bus_id, new_name, BUS_ID_SIZE); 1237 strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
1183 1238
1184 error = kobject_rename(&dev->kobj, new_name); 1239 error = kobject_rename(&dev->kobj, new_name);
1240 if (error) {
1241 strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
1242 goto out;
1243 }
1185 1244
1186#ifdef CONFIG_SYSFS_DEPRECATED 1245#ifdef CONFIG_SYSFS_DEPRECATED
1187 if (old_class_name) { 1246 if (old_class_name) {
1188 new_class_name = make_class_name(dev->class->name, &dev->kobj); 1247 new_class_name = make_class_name(dev->class->name, &dev->kobj);
1189 if (new_class_name) { 1248 if (new_class_name) {
1190 sysfs_create_link(&dev->parent->kobj, &dev->kobj, 1249 error = sysfs_create_link(&dev->parent->kobj,
1191 new_class_name); 1250 &dev->kobj, new_class_name);
1251 if (error)
1252 goto out;
1192 sysfs_remove_link(&dev->parent->kobj, old_class_name); 1253 sysfs_remove_link(&dev->parent->kobj, old_class_name);
1193 } 1254 }
1194 } 1255 }
1195#endif 1256#endif
1196 1257
1197 if (dev->class) { 1258 if (dev->class) {
1198 sysfs_remove_link(&dev->class->subsys.kobj, 1259 sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
1199 old_symlink_name); 1260 error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
1200 sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, 1261 dev->bus_id);
1201 dev->bus_id); 1262 if (error) {
1263 /* Uh... how to unravel this if restoring can fail? */
1264 dev_err(dev, "%s: sysfs_create_symlink failed (%d)\n",
1265 __FUNCTION__, error);
1266 }
1202 } 1267 }
1268out:
1203 put_device(dev); 1269 put_device(dev);
1204 1270
1205 kfree(new_class_name); 1271 kfree(new_class_name);
1206 kfree(old_symlink_name);
1207 out_free_old_class:
1208 kfree(old_class_name); 1272 kfree(old_class_name);
1273 kfree(old_device_name);
1209 1274
1210 return error; 1275 return error;
1211} 1276}