mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-16 07:35:14 +00:00
[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>
This commit is contained in:
parent
f4395b6526
commit
0fac3f477b
1 changed files with 29 additions and 36 deletions
|
@ -274,6 +274,13 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
|
||||||
{
|
{
|
||||||
struct zfcp_unit *unit;
|
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);
|
unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
|
||||||
if (!unit)
|
if (!unit)
|
||||||
return ERR_PTR(-ENOMEM);
|
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->port = port;
|
||||||
unit->fcp_lun = fcp_lun;
|
unit->fcp_lun = fcp_lun;
|
||||||
|
|
||||||
dev_set_name(&unit->sysfs_device, "0x%016llx",
|
if (dev_set_name(&unit->sysfs_device, "0x%016llx",
|
||||||
(unsigned long long) fcp_lun);
|
(unsigned long long) fcp_lun)) {
|
||||||
|
kfree(unit);
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
unit->sysfs_device.parent = &port->sysfs_device;
|
unit->sysfs_device.parent = &port->sysfs_device;
|
||||||
unit->sysfs_device.release = zfcp_sysfs_unit_release;
|
unit->sysfs_device.release = zfcp_sysfs_unit_release;
|
||||||
dev_set_drvdata(&unit->sysfs_device, unit);
|
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.channel.min = 0xFFFFFFFF;
|
||||||
unit->latencies.cmd.fabric.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)) {
|
if (device_register(&unit->sysfs_device)) {
|
||||||
put_device(&unit->sysfs_device);
|
put_device(&unit->sysfs_device);
|
||||||
return ERR_PTR(-EINVAL);
|
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,
|
if (sysfs_create_group(&unit->sysfs_device.kobj,
|
||||||
&zfcp_sysfs_unit_attrs)) {
|
&zfcp_sysfs_unit_attrs)) {
|
||||||
device_unregister(&unit->sysfs_device);
|
device_unregister(&unit->sysfs_device);
|
||||||
return ERR_PTR(-EIO);
|
return ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
zfcp_unit_get(unit);
|
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);
|
zfcp_port_get(port);
|
||||||
|
|
||||||
return unit;
|
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)
|
u32 status, u32 d_id)
|
||||||
{
|
{
|
||||||
struct zfcp_port *port;
|
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);
|
port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
|
||||||
if (!port)
|
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_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
|
||||||
atomic_set(&port->refcount, 0);
|
atomic_set(&port->refcount, 0);
|
||||||
|
|
||||||
dev_set_name(&port->sysfs_device, "0x%016llx",
|
if (dev_set_name(&port->sysfs_device, "0x%016llx",
|
||||||
(unsigned long long)wwpn);
|
(unsigned long long)wwpn)) {
|
||||||
|
kfree(port);
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
port->sysfs_device.parent = &adapter->ccw_device->dev;
|
port->sysfs_device.parent = &adapter->ccw_device->dev;
|
||||||
|
|
||||||
port->sysfs_device.release = zfcp_sysfs_port_release;
|
port->sysfs_device.release = zfcp_sysfs_port_release;
|
||||||
dev_set_drvdata(&port->sysfs_device, port);
|
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)) {
|
if (device_register(&port->sysfs_device)) {
|
||||||
put_device(&port->sysfs_device);
|
put_device(&port->sysfs_device);
|
||||||
goto err_out;
|
return ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = sysfs_create_group(&port->sysfs_device.kobj,
|
if (sysfs_create_group(&port->sysfs_device.kobj,
|
||||||
&zfcp_sysfs_port_attrs);
|
&zfcp_sysfs_port_attrs)) {
|
||||||
|
|
||||||
if (retval) {
|
|
||||||
device_unregister(&port->sysfs_device);
|
device_unregister(&port->sysfs_device);
|
||||||
goto err_out;
|
return ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
zfcp_port_get(port);
|
zfcp_port_get(port);
|
||||||
|
@ -701,11 +699,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
|
||||||
|
|
||||||
zfcp_adapter_get(adapter);
|
zfcp_adapter_get(adapter);
|
||||||
return port;
|
return port;
|
||||||
|
|
||||||
err_out_free:
|
|
||||||
kfree(port);
|
|
||||||
err_out:
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue