summaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2009-08-18 15:43:30 +0200
committerJames Bottomley <James.Bottomley@suse.de>2009-09-05 08:49:46 -0500
commit0fac3f477b6b520ae7d972ceb6e958e6807c8e1a (patch)
treebef6ee15c92486613dd918de6a8ff00311fc379d /drivers/s390
parentf4395b652636398eb4712e6f3caf79c9a6c02e21 (diff)
downloadlinux-0fac3f477b6b520ae7d972ceb6e958e6807c8e1a.tar.gz
linux-0fac3f477b6b520ae7d972ceb6e958e6807c8e1a.tar.bz2
linux-0fac3f477b6b520ae7d972ceb6e958e6807c8e1a.zip
[SCSI] zfcp: Handle failures during device allocation correctly
dev_set_name tries to allocate memory, so check the return value for allocation failures. After dev_set_name succeeds, call device_register as next step to be able to use put_device during error handling. Reviewed-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c65
1 files changed, 29 insertions, 36 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index a7954443ec19..1be6bf7e8ce6 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -274,6 +274,13 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
{
struct zfcp_unit *unit;
+ read_lock_irq(&zfcp_data.config_lock);
+ if (zfcp_get_unit_by_lun(port, fcp_lun)) {
+ read_unlock_irq(&zfcp_data.config_lock);
+ return ERR_PTR(-EINVAL);
+ }
+ read_unlock_irq(&zfcp_data.config_lock);
+
unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
if (!unit)
return ERR_PTR(-ENOMEM);
@@ -285,8 +292,11 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
unit->port = port;
unit->fcp_lun = fcp_lun;
- dev_set_name(&unit->sysfs_device, "0x%016llx",
- (unsigned long long) fcp_lun);
+ if (dev_set_name(&unit->sysfs_device, "0x%016llx",
+ (unsigned long long) fcp_lun)) {
+ kfree(unit);
+ return ERR_PTR(-ENOMEM);
+ }
unit->sysfs_device.parent = &port->sysfs_device;
unit->sysfs_device.release = zfcp_sysfs_unit_release;
dev_set_drvdata(&unit->sysfs_device, unit);
@@ -302,13 +312,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
unit->latencies.cmd.channel.min = 0xFFFFFFFF;
unit->latencies.cmd.fabric.min = 0xFFFFFFFF;
- read_lock_irq(&zfcp_data.config_lock);
- if (zfcp_get_unit_by_lun(port, fcp_lun)) {
- read_unlock_irq(&zfcp_data.config_lock);
- goto err_out_free;
- }
- read_unlock_irq(&zfcp_data.config_lock);
-
if (device_register(&unit->sysfs_device)) {
put_device(&unit->sysfs_device);
return ERR_PTR(-EINVAL);
@@ -317,7 +320,7 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
if (sysfs_create_group(&unit->sysfs_device.kobj,
&zfcp_sysfs_unit_attrs)) {
device_unregister(&unit->sysfs_device);
- return ERR_PTR(-EIO);
+ return ERR_PTR(-EINVAL);
}
zfcp_unit_get(unit);
@@ -332,10 +335,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
zfcp_port_get(port);
return unit;
-
-err_out_free:
- kfree(unit);
- return ERR_PTR(-EINVAL);
}
/**
@@ -642,7 +641,13 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
u32 status, u32 d_id)
{
struct zfcp_port *port;
- int retval;
+
+ read_lock_irq(&zfcp_data.config_lock);
+ if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
+ read_unlock_irq(&zfcp_data.config_lock);
+ return ERR_PTR(-EINVAL);
+ }
+ read_unlock_irq(&zfcp_data.config_lock);
port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
if (!port)
@@ -663,31 +668,24 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
atomic_set(&port->refcount, 0);
- dev_set_name(&port->sysfs_device, "0x%016llx",
- (unsigned long long)wwpn);
+ if (dev_set_name(&port->sysfs_device, "0x%016llx",
+ (unsigned long long)wwpn)) {
+ kfree(port);
+ return ERR_PTR(-ENOMEM);
+ }
port->sysfs_device.parent = &adapter->ccw_device->dev;
-
port->sysfs_device.release = zfcp_sysfs_port_release;
dev_set_drvdata(&port->sysfs_device, port);
- read_lock_irq(&zfcp_data.config_lock);
- if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
- read_unlock_irq(&zfcp_data.config_lock);
- goto err_out_free;
- }
- read_unlock_irq(&zfcp_data.config_lock);
-
if (device_register(&port->sysfs_device)) {
put_device(&port->sysfs_device);
- goto err_out;
+ return ERR_PTR(-EINVAL);
}
- retval = sysfs_create_group(&port->sysfs_device.kobj,
- &zfcp_sysfs_port_attrs);
-
- if (retval) {
+ if (sysfs_create_group(&port->sysfs_device.kobj,
+ &zfcp_sysfs_port_attrs)) {
device_unregister(&port->sysfs_device);
- goto err_out;
+ return ERR_PTR(-EINVAL);
}
zfcp_port_get(port);
@@ -701,11 +699,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
zfcp_adapter_get(adapter);
return port;
-
-err_out_free:
- kfree(port);
-err_out:
- return ERR_PTR(-EINVAL);
}
/**