diff options
author | James Smart <jsmart2021@gmail.com> | 2018-04-09 14:24:27 -0700 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-04-18 19:34:04 -0400 |
commit | 01466024d2de1c05652d69411461e8e7908f0d1e (patch) | |
tree | a1c0c6a70f1a0fb0da29af9a8e2358952bc905f2 /drivers/scsi/lpfc/lpfc_nvme.c | |
parent | 0cdb84ec26e455326a8ee1b7c69ce1c281ba38cb (diff) | |
download | linux-01466024d2de1c05652d69411461e8e7908f0d1e.tar.bz2 |
scsi: lpfc: Fix NULL pointer access in lpfc_nvme_info_show
After making remoteport unregister requests, the ndlp nrport pointer was
stale.
Track when waiting for waiting for unregister completion callback and
adjust nldp pointer assignment. Add a few safety checks for NULL
pointer values.
Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <james.smart@broadcom.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nvme.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nvme.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 1414c581c0b6..1cb2c634e9f7 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -335,6 +335,7 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport) remoteport); spin_lock_irq(&vport->phba->hbalock); ndlp->nrport = NULL; + ndlp->upcall_flags &= ~NLP_WAIT_FOR_UNREG; spin_unlock_irq(&vport->phba->hbalock); /* Remove original register reference. The host transport @@ -2646,6 +2647,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) struct nvme_fc_local_port *localport; struct lpfc_nvme_lport *lport; struct lpfc_nvme_rport *rport; + struct lpfc_nvme_rport *oldrport; struct nvme_fc_remote_port *remote_port; struct nvme_fc_port_info rpinfo; struct lpfc_nodelist *prev_ndlp; @@ -2678,7 +2680,9 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) rpinfo.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn); rpinfo.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn); - if (!ndlp->nrport) + + oldrport = lpfc_ndlp_get_nrport(ndlp); + if (!oldrport) lpfc_nlp_get(ndlp); ret = nvme_fc_register_remoteport(localport, &rpinfo, &remote_port); @@ -2688,8 +2692,8 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) * new rport. */ rport = remote_port->private; - if (ndlp->nrport) { - if (ndlp->nrport == remote_port->private) { + if (oldrport) { + if (oldrport == remote_port->private) { /* Same remoteport. Just reuse. */ lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NVME_DISC, @@ -2713,6 +2717,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) */ spin_lock_irq(&vport->phba->hbalock); ndlp->nrport = NULL; + ndlp->upcall_flags &= ~NLP_WAIT_FOR_UNREG; spin_unlock_irq(&vport->phba->hbalock); rport->ndlp = NULL; rport->remoteport = NULL; @@ -2785,7 +2790,7 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) if (!lport) goto input_err; - rport = ndlp->nrport; + rport = lpfc_ndlp_get_nrport(ndlp); if (!rport) goto input_err; |