[SCSI] fc class: fix scanning when devs are offline
When a rport is added back or the role is changed the fc class will queue a scan and then call scsi_target_unblock. The problem with this is if the devices are in the SDEV_OFFLINE state and the scan is run before the scsi_target_unblock, then the scan will see LUN0 as offline and the scan will fail. This patch moves the unblock call to before the scan, so we know the device state will be set correctly when the scan is run. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
7c018a901c
commit
8fb2ef89b6
@ -2808,17 +2808,20 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
|
|||||||
FC_RPORT_DEVLOSS_PENDING |
|
FC_RPORT_DEVLOSS_PENDING |
|
||||||
FC_RPORT_DEVLOSS_CALLBK_DONE);
|
FC_RPORT_DEVLOSS_CALLBK_DONE);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||||
|
|
||||||
/* if target, initiate a scan */
|
/* if target, initiate a scan */
|
||||||
if (rport->scsi_target_id != -1) {
|
if (rport->scsi_target_id != -1) {
|
||||||
|
scsi_target_unblock(&rport->dev);
|
||||||
|
|
||||||
|
spin_lock_irqsave(shost->host_lock,
|
||||||
|
flags);
|
||||||
rport->flags |= FC_RPORT_SCAN_PENDING;
|
rport->flags |= FC_RPORT_SCAN_PENDING;
|
||||||
scsi_queue_work(shost,
|
scsi_queue_work(shost,
|
||||||
&rport->scan_work);
|
&rport->scan_work);
|
||||||
spin_unlock_irqrestore(shost->host_lock,
|
spin_unlock_irqrestore(shost->host_lock,
|
||||||
flags);
|
flags);
|
||||||
scsi_target_unblock(&rport->dev);
|
}
|
||||||
} else
|
|
||||||
spin_unlock_irqrestore(shost->host_lock,
|
|
||||||
flags);
|
|
||||||
|
|
||||||
fc_bsg_goose_queue(rport);
|
fc_bsg_goose_queue(rport);
|
||||||
|
|
||||||
@ -2876,16 +2879,17 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
|
|||||||
if (fci->f->dd_fcrport_size)
|
if (fci->f->dd_fcrport_size)
|
||||||
memset(rport->dd_data, 0,
|
memset(rport->dd_data, 0,
|
||||||
fci->f->dd_fcrport_size);
|
fci->f->dd_fcrport_size);
|
||||||
|
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||||
|
|
||||||
|
if (ids->roles & FC_PORT_ROLE_FCP_TARGET) {
|
||||||
|
scsi_target_unblock(&rport->dev);
|
||||||
|
|
||||||
if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
|
|
||||||
/* initiate a scan of the target */
|
/* initiate a scan of the target */
|
||||||
|
spin_lock_irqsave(shost->host_lock, flags);
|
||||||
rport->flags |= FC_RPORT_SCAN_PENDING;
|
rport->flags |= FC_RPORT_SCAN_PENDING;
|
||||||
scsi_queue_work(shost, &rport->scan_work);
|
scsi_queue_work(shost, &rport->scan_work);
|
||||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||||
scsi_target_unblock(&rport->dev);
|
}
|
||||||
} else
|
|
||||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
|
||||||
|
|
||||||
return rport;
|
return rport;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3083,12 +3087,12 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
|
|||||||
/* ensure any stgt delete functions are done */
|
/* ensure any stgt delete functions are done */
|
||||||
fc_flush_work(shost);
|
fc_flush_work(shost);
|
||||||
|
|
||||||
|
scsi_target_unblock(&rport->dev);
|
||||||
/* initiate a scan of the target */
|
/* initiate a scan of the target */
|
||||||
spin_lock_irqsave(shost->host_lock, flags);
|
spin_lock_irqsave(shost->host_lock, flags);
|
||||||
rport->flags |= FC_RPORT_SCAN_PENDING;
|
rport->flags |= FC_RPORT_SCAN_PENDING;
|
||||||
scsi_queue_work(shost, &rport->scan_work);
|
scsi_queue_work(shost, &rport->scan_work);
|
||||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||||
scsi_target_unblock(&rport->dev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(fc_remote_port_rolechg);
|
EXPORT_SYMBOL(fc_remote_port_rolechg);
|
||||||
|
Loading…
Reference in New Issue
Block a user