[SCSI] lpfc 8.2.6 : Multiple discovery fixes
Multiple Discovery Fixes: - Fix race on discovery due to link events coinciding with vport_delete. - Use NLP_FABRIC state to filter out switch-based pseudo initiators that reuse the same WWNs. - Correct erroneous setting of DID=0 in lpfc_matchdid() - Correct extra reference count that was in the lookup path for the remoteid from an unsolicited ELS. - Correct double-free bug in els abort path. - Correct FDMI server discovery logic for switch that return a WWN of 0. - Fix bugs in ndlp mgmt when a node changes address - Correct bug that did not delete RSCNs for vports upon link transitions - Fix "0216 Link event during NS query" error which pops up when vports are swapped to different switch ports. - Add sanity checks on ndlp structures - Fix devloss log message to dump WWN correctly - Hold off mgmt commands that were interferring with discovery mailbox cmds - Remove unnecessary FC_ESTABLISH_LINK logic. - Correct some race conditions in the worker thread, resulting in devloss: - Clear the work_port_events field before handling the work port events - Clear the deferred ring event before handling a deferred ring event - Hold the hba lock when waking up the work thread - Send an acc for the rscn even when we aren't going to handle it - Fix locking behavior that was not properly protecting the ACTIVE flag, thus allowing mailbox command order to shift. Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:

committed by
James Bottomley

parent
b35c07d007
commit
58da1ffb2b
@@ -578,14 +578,14 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
||||
lpfc_cmd->result == IOERR_NO_RESOURCES ||
|
||||
lpfc_cmd->result == RJT_LOGIN_REQUIRED) {
|
||||
cmd->result = ScsiResult(DID_REQUEUE, 0);
|
||||
break;
|
||||
} /* else: fall through */
|
||||
break;
|
||||
} /* else: fall through */
|
||||
default:
|
||||
cmd->result = ScsiResult(DID_ERROR, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((pnode == NULL )
|
||||
if (!pnode || !NLP_CHK_NODE_ACT(pnode)
|
||||
|| (pnode->nlp_state != NLP_STE_MAPPED_NODE))
|
||||
cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY);
|
||||
} else {
|
||||
@@ -626,7 +626,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
||||
if (!result)
|
||||
lpfc_rampup_queue_depth(vport, sdev);
|
||||
|
||||
if (!result && pnode != NULL &&
|
||||
if (!result && pnode && NLP_CHK_NODE_ACT(pnode) &&
|
||||
((jiffies - pnode->last_ramp_up_time) >
|
||||
LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
|
||||
((jiffies - pnode->last_q_full_time) >
|
||||
@@ -654,7 +654,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
|
||||
* Check for queue full. If the lun is reporting queue full, then
|
||||
* back off the lun queue depth to prevent target overloads.
|
||||
*/
|
||||
if (result == SAM_STAT_TASK_SET_FULL && pnode != NULL) {
|
||||
if (result == SAM_STAT_TASK_SET_FULL && pnode &&
|
||||
NLP_CHK_NODE_ACT(pnode)) {
|
||||
pnode->last_q_full_time = jiffies;
|
||||
|
||||
shost_for_each_device(tmp_sdev, sdev->host) {
|
||||
@@ -704,6 +705,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
|
||||
int datadir = scsi_cmnd->sc_data_direction;
|
||||
char tag[2];
|
||||
|
||||
if (!pnode || !NLP_CHK_NODE_ACT(pnode))
|
||||
return;
|
||||
|
||||
lpfc_cmd->fcp_rsp->rspSnsLen = 0;
|
||||
/* clear task management bits */
|
||||
lpfc_cmd->fcp_cmnd->fcpCntl2 = 0;
|
||||
@@ -785,9 +789,9 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport,
|
||||
struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
|
||||
struct lpfc_nodelist *ndlp = rdata->pnode;
|
||||
|
||||
if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
|
||||
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) ||
|
||||
ndlp->nlp_state != NLP_STE_MAPPED_NODE)
|
||||
return 0;
|
||||
}
|
||||
|
||||
piocbq = &(lpfc_cmd->cur_iocbq);
|
||||
piocbq->vport = vport;
|
||||
@@ -842,7 +846,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport,
|
||||
struct lpfc_iocbq *iocbqrsp;
|
||||
int ret;
|
||||
|
||||
if (!rdata->pnode)
|
||||
if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode))
|
||||
return FAILED;
|
||||
|
||||
lpfc_cmd->rdata = rdata;
|
||||
@@ -959,7 +963,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
|
||||
* Catch race where our node has transitioned, but the
|
||||
* transport is still transitioning.
|
||||
*/
|
||||
if (!ndlp) {
|
||||
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
|
||||
cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
|
||||
goto out_fail_command;
|
||||
}
|
||||
@@ -1146,7 +1150,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
|
||||
* target is rediscovered or devloss timeout expires.
|
||||
*/
|
||||
while (1) {
|
||||
if (!pnode)
|
||||
if (!pnode || !NLP_CHK_NODE_ACT(pnode))
|
||||
goto out;
|
||||
|
||||
if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
|
||||
@@ -1162,7 +1166,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
|
||||
goto out;
|
||||
}
|
||||
pnode = rdata->pnode;
|
||||
if (!pnode)
|
||||
if (!pnode || !NLP_CHK_NODE_ACT(pnode))
|
||||
goto out;
|
||||
}
|
||||
if (pnode->nlp_state == NLP_STE_MAPPED_NODE)
|
||||
|
Reference in New Issue
Block a user