@@ -686,6 +686,7 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number)
{
struct Scsi_Host *shost = dev_to_shost(parent);
struct sas_phy *phy;
+ int rc;
phy = kzalloc(sizeof(*phy), GFP_KERNEL);
if (!phy)
@@ -700,10 +701,16 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number)
INIT_LIST_HEAD(&phy->port_siblings);
if (scsi_is_sas_expander_device(parent)) {
struct sas_rphy *rphy = dev_to_rphy(parent);
- dev_set_name(&phy->dev, "phy-%d:%d:%d", shost->host_no,
- rphy->scsi_target_id, number);
+ rc = dev_set_name(&phy->dev, "phy-%d:%d:%d", shost->host_no,
+ rphy->scsi_target_id, number);
} else
- dev_set_name(&phy->dev, "phy-%d:%d", shost->host_no, number);
+ rc = dev_set_name(&phy->dev, "phy-%d:%d", shost->host_no, number);
+
+ if (rc) {
+ put_device(&phy->dev);
+ kfree(phy);
+ return NULL;
+ }
transport_setup_device(&phy->dev);
@@ -880,6 +887,7 @@ struct sas_port *sas_port_alloc(struct device *parent, int port_id)
{
struct Scsi_Host *shost = dev_to_shost(parent);
struct sas_port *port;
+ int rc;
port = kzalloc(sizeof(*port), GFP_KERNEL);
if (!port)
@@ -897,11 +905,17 @@ struct sas_port *sas_port_alloc(struct device *parent, int port_id)
if (scsi_is_sas_expander_device(parent)) {
struct sas_rphy *rphy = dev_to_rphy(parent);
- dev_set_name(&port->dev, "port-%d:%d:%d", shost->host_no,
- rphy->scsi_target_id, port->port_identifier);
+ rc = dev_set_name(&port->dev, "port-%d:%d:%d", shost->host_no,
+ rphy->scsi_target_id, port->port_identifier);
} else
- dev_set_name(&port->dev, "port-%d:%d", shost->host_no,
- port->port_identifier);
+ rc = dev_set_name(&port->dev, "port-%d:%d", shost->host_no,
+ port->port_identifier);
+
+ if (rc) {
+ put_device(&port->dev);
+ kfree(port);
+ return NULL;
+ }
transport_setup_device(&port->dev);
@@ -1439,6 +1453,7 @@ struct sas_rphy *sas_end_device_alloc(struct sas_port *parent)
{
struct Scsi_Host *shost = dev_to_shost(&parent->dev);
struct sas_end_device *rdev;
+ int rc;
rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
if (!rdev) {
@@ -1450,12 +1465,18 @@ struct sas_rphy *sas_end_device_alloc(struct sas_port *parent)
rdev->rphy.dev.release = sas_end_device_release;
if (scsi_is_sas_expander_device(parent->dev.parent)) {
struct sas_rphy *rphy = dev_to_rphy(parent->dev.parent);
- dev_set_name(&rdev->rphy.dev, "end_device-%d:%d:%d",
- shost->host_no, rphy->scsi_target_id,
- parent->port_identifier);
+ rc = dev_set_name(&rdev->rphy.dev, "end_device-%d:%d:%d",
+ shost->host_no, rphy->scsi_target_id,
+ parent->port_identifier);
+
} else
- dev_set_name(&rdev->rphy.dev, "end_device-%d:%d",
- shost->host_no, parent->port_identifier);
+ rc = dev_set_name(&rdev->rphy.dev, "end_device-%d:%d",
+ shost->host_no, parent->port_identifier);
+ if (rc) {
+ put_device(&rdev->rphy.dev);
+ kfree(rdev);
+ return NULL;
+ }
rdev->rphy.identify.device_type = SAS_END_DEVICE;
sas_rphy_initialize(&rdev->rphy);
transport_setup_device(&rdev->rphy.dev);
@@ -1480,6 +1501,7 @@ struct sas_rphy *sas_expander_alloc(struct sas_port *parent,
struct Scsi_Host *shost = dev_to_shost(&parent->dev);
struct sas_expander_device *rdev;
struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
+ int rc;
BUG_ON(type != SAS_EDGE_EXPANDER_DEVICE &&
type != SAS_FANOUT_EXPANDER_DEVICE);
@@ -1495,8 +1517,16 @@ struct sas_rphy *sas_expander_alloc(struct sas_port *parent,
mutex_lock(&sas_host->lock);
rdev->rphy.scsi_target_id = sas_host->next_expander_id++;
mutex_unlock(&sas_host->lock);
- dev_set_name(&rdev->rphy.dev, "expander-%d:%d",
- shost->host_no, rdev->rphy.scsi_target_id);
+ rc = dev_set_name(&rdev->rphy.dev, "expander-%d:%d",
+ shost->host_no, rdev->rphy.scsi_target_id);
+ if (rc) {
+ put_device(&rdev->rphy.dev);
+ kfree(rdev);
+ mutex_lock(&sas_host->lock);
+ sas_host->next_expander_id--;
+ mutex_unlock(&sas_host->lock);
+ return NULL;
+ }
rdev->rphy.identify.device_type = type;
sas_rphy_initialize(&rdev->rphy);
transport_setup_device(&rdev->rphy.dev);
The driver do not handle the possible returning error of dev_set_name, if it returned fail, some operations should be rollback or there may be possible memory leak. For example, we use put_device to free the device and use kfree to free the memory in the error handle path. Fixes: 71610f55fa4d ("[SCSI] struct device - replace bus_id with dev_name(), dev_set_name()") Signed-off-by: Zhu Wang <wangzhu9@huawei.com> --- drivers/scsi/scsi_transport_sas.c | 58 +++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 14 deletions(-)