From 0293902a4d66fab27d0ddcc0766e05dae68f004e Mon Sep 17 00:00:00 2001 From: Wang Chen Date: Wed, 23 Jul 2008 21:30:01 -0700 Subject: I2O: handle sysfs_create_link() failures Compile warning: ignoring return value of `sysfs_create_link', declared with attribute warn_unused_result. If sysfs_create_link failed, take care of the return value and do some error handle after the failure. Since sysfs_remove_link() will check whether a link exists, when removing the link in error path, we don't need to care whether a link was created. Signed-off-by: Wang Chen Cc: Markus Lidel Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/message/i2o/device.c | 54 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'drivers/message/i2o/device.c') diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c index 489d7c5c4965..8774c670e668 100644 --- a/drivers/message/i2o/device.c +++ b/drivers/message/i2o/device.c @@ -243,29 +243,41 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry) /* create user entries for this device */ tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid); - if (tmp && (tmp != i2o_dev)) - sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj, - "user"); + if (tmp && (tmp != i2o_dev)) { + rc = sysfs_create_link(&i2o_dev->device.kobj, + &tmp->device.kobj, "user"); + if (rc) + goto unreg_dev; + } /* create user entries refering to this device */ list_for_each_entry(tmp, &c->devices, list) if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid) - && (tmp != i2o_dev)) - sysfs_create_link(&tmp->device.kobj, - &i2o_dev->device.kobj, "user"); + && (tmp != i2o_dev)) { + rc = sysfs_create_link(&tmp->device.kobj, + &i2o_dev->device.kobj, "user"); + if (rc) + goto rmlink1; + } /* create parent entries for this device */ tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid); - if (tmp && (tmp != i2o_dev)) - sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj, - "parent"); + if (tmp && (tmp != i2o_dev)) { + rc = sysfs_create_link(&i2o_dev->device.kobj, + &tmp->device.kobj, "parent"); + if (rc) + goto rmlink1; + } /* create parent entries refering to this device */ list_for_each_entry(tmp, &c->devices, list) if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) - && (tmp != i2o_dev)) - sysfs_create_link(&tmp->device.kobj, - &i2o_dev->device.kobj, "parent"); + && (tmp != i2o_dev)) { + rc = sysfs_create_link(&tmp->device.kobj, + &i2o_dev->device.kobj, "parent"); + if (rc) + goto rmlink2; + } i2o_driver_notify_device_add_all(i2o_dev); @@ -273,6 +285,24 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry) return 0; +rmlink2: + /* If link creating failed halfway, we loop whole list to cleanup. + * And we don't care wrong removing of link, because sysfs_remove_link + * will take care of it. + */ + list_for_each_entry(tmp, &c->devices, list) { + if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) + sysfs_remove_link(&tmp->device.kobj, "parent"); + } + sysfs_remove_link(&i2o_dev->device.kobj, "parent"); +rmlink1: + list_for_each_entry(tmp, &c->devices, list) + if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid) + sysfs_remove_link(&tmp->device.kobj, "user"); + sysfs_remove_link(&i2o_dev->device.kobj, "user"); +unreg_dev: + list_del(&i2o_dev->list); + device_unregister(&i2o_dev->device); err: kfree(i2o_dev); return rc; -- cgit v1.2.3