> James Bottomley [James.Bottomley@xxxxxxxxxxxx] wrote: >> This is a bit of a layering violation >> >> if the various discover functions are going to return an error, I think >> it's their job to clean up whatever they did before returning. Here's a reworked version of Malahal's patch that pushes the sas_rphy cleanups into the sas_discover_{sas,sata,expander}.* functions. It also checks the return value of sas_notify_lldd_dev_found(). This patch (since it includes discovery error cleanup for SATA) is against 2.6.19-rc4 + scsi-misc + scsi-rc-fixes + aic94xx-sas, though I can respin it without the SATA bits if desired. -- Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index 23461dc..0f790ea 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -564,12 +564,25 @@ int sas_discover_sata(struct domain_devi default: break; } + if (res) + goto out_err; sas_notify_lldd_dev_gone(dev); - if (!res) { - sas_notify_lldd_dev_found(dev); - res = sas_rphy_add(dev->rphy); - } + res = sas_notify_lldd_dev_found(dev); + if (res) + goto out_err2; + + res = sas_rphy_add(dev->rphy); + if (res) + goto out_err; + + return res; + +out_err: + sas_notify_lldd_dev_gone(dev); +out_err2: + sas_rphy_free(dev->rphy); + dev->rphy = NULL; return res; } @@ -594,12 +607,20 @@ int sas_discover_end_dev(struct domain_d /* do this to get the end device port attributes which will have * been scanned in sas_rphy_add */ sas_notify_lldd_dev_gone(dev); - sas_notify_lldd_dev_found(dev); + res = sas_notify_lldd_dev_found(dev); + if (res) + goto out_err2; return 0; out_err: sas_notify_lldd_dev_gone(dev); + sas_rphy_free(dev->rphy); + dev->rphy = NULL; + return res; +out_err2: + sas_rphy_delete(dev->rphy); + dev->rphy = NULL; return res; } @@ -689,6 +710,10 @@ static void sas_discover_domain(void *da } if (error) { + spin_lock(&port->dev_list_lock); + list_del_init(&port->port_dev->dev_list_node); + spin_unlock(&port->dev_list_lock); + kfree(port->port_dev); /* not kobject_register-ed yet */ port->port_dev = NULL; } diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 4cc7457..a79e89c 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -1474,14 +1474,27 @@ int sas_discover_root_expander(struct do int res; struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy); - sas_rphy_add(dev->rphy); + res = sas_rphy_add(dev->rphy); + if (res) + goto out_err; ex->level = dev->port->disc.max_level; /* 0 */ res = sas_discover_expander(dev); - if (!res) - sas_ex_bfs_disc(dev->port); + if (res) + goto out_err2; + + sas_ex_bfs_disc(dev->port); return res; + +out_err2: + sas_rphy_delete(dev->rphy); + dev->rphy = NULL; + return res; +out_err: + sas_rphy_free(dev->rphy); + dev->rphy = NULL; + return res; } /* ---------- Domain revalidation ---------- */ - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html