[SCSI] libsas: enforce eh strategy handlers only in eh context
The strategy handlers may be called in places that are problematic for libsas (i.e. sata resets outside of domain revalidation filtering / libata link recovery), or problematic for userspace (non-blocking ioctl to sleeping reset functions). However, these routines are also called for eh escalations and recovery of scsi_eh_prep_cmnd(), so permit them as long as we are running in the host's error handler, otherwise arrange for them to be triggered in eh_context. Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:

committed by
James Bottomley

parent
b9d5c6b7ef
commit
5db45bdc87
@@ -39,6 +39,7 @@ void sas_init_dev(struct domain_device *dev)
|
||||
{
|
||||
switch (dev->dev_type) {
|
||||
case SAS_END_DEV:
|
||||
INIT_LIST_HEAD(&dev->ssp_dev.eh_list_node);
|
||||
break;
|
||||
case EDGE_DEV:
|
||||
case FANOUT_DEV:
|
||||
@@ -286,6 +287,8 @@ void sas_free_device(struct kref *kref)
|
||||
|
||||
static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_device *dev)
|
||||
{
|
||||
struct sas_ha_struct *ha = port->ha;
|
||||
|
||||
sas_notify_lldd_dev_gone(dev);
|
||||
if (!dev->parent)
|
||||
dev->port->port_dev = NULL;
|
||||
@@ -298,6 +301,14 @@ static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_d
|
||||
sas_ata_end_eh(dev->sata_dev.ap);
|
||||
spin_unlock_irq(&port->dev_list_lock);
|
||||
|
||||
spin_lock_irq(&ha->lock);
|
||||
if (dev->dev_type == SAS_END_DEV &&
|
||||
!list_empty(&dev->ssp_dev.eh_list_node)) {
|
||||
list_del_init(&dev->ssp_dev.eh_list_node);
|
||||
ha->eh_active--;
|
||||
}
|
||||
spin_unlock_irq(&ha->lock);
|
||||
|
||||
sas_put_device(dev);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user