Commit 79080d34 authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: correct rcu unlock issue in lpfc_nvme_info_show

Many of the exit cases were not releasing the rcu read lock.  Corrected the
exit paths.
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Tested-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent e2a8be56
...@@ -355,7 +355,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, ...@@ -355,7 +355,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
phba->sli4_hba.io_xri_max, phba->sli4_hba.io_xri_max,
lpfc_sli4_get_els_iocb_cnt(phba)); lpfc_sli4_get_els_iocb_cnt(phba));
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
/* Port state is only one of two values for now. */ /* Port state is only one of two values for now. */
if (localport->port_id) if (localport->port_id)
...@@ -371,7 +371,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, ...@@ -371,7 +371,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
wwn_to_u64(vport->fc_nodename.u.wwn), wwn_to_u64(vport->fc_nodename.u.wwn),
localport->port_id, statep); localport->port_id, statep);
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
nrport = NULL; nrport = NULL;
...@@ -398,39 +398,39 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, ...@@ -398,39 +398,39 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
/* Tab in to show lport ownership. */ /* Tab in to show lport ownership. */
if (strlcat(buf, "NVME RPORT ", PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, "NVME RPORT ", PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
if (phba->brd_no >= 10) { if (phba->brd_no >= 10) {
if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
} }
scnprintf(tmp, sizeof(tmp), "WWPN x%llx ", scnprintf(tmp, sizeof(tmp), "WWPN x%llx ",
nrport->port_name); nrport->port_name);
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
scnprintf(tmp, sizeof(tmp), "WWNN x%llx ", scnprintf(tmp, sizeof(tmp), "WWNN x%llx ",
nrport->node_name); nrport->node_name);
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
scnprintf(tmp, sizeof(tmp), "DID x%06x ", scnprintf(tmp, sizeof(tmp), "DID x%06x ",
nrport->port_id); nrport->port_id);
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
/* An NVME rport can have multiple roles. */ /* An NVME rport can have multiple roles. */
if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) { if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) {
if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
} }
if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) { if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) {
if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
} }
if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) { if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) {
if (strlcat(buf, "DISCSRVC ", PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, "DISCSRVC ", PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
} }
if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR | if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
FC_PORT_ROLE_NVME_TARGET | FC_PORT_ROLE_NVME_TARGET |
...@@ -438,12 +438,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, ...@@ -438,12 +438,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x", scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x",
nrport->port_role); nrport->port_role);
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
} }
scnprintf(tmp, sizeof(tmp), "%s\n", statep); scnprintf(tmp, sizeof(tmp), "%s\n", statep);
if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
goto buffer_done; goto rcu_unlock_buf_done;
} }
rcu_read_unlock(); rcu_read_unlock();
...@@ -505,7 +505,13 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, ...@@ -505,7 +505,13 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
atomic_read(&lport->cmpl_fcp_err)); atomic_read(&lport->cmpl_fcp_err));
strlcat(buf, tmp, PAGE_SIZE); strlcat(buf, tmp, PAGE_SIZE);
buffer_done: /* RCU is already unlocked. */
goto buffer_done;
rcu_unlock_buf_done:
rcu_read_unlock();
buffer_done:
len = strnlen(buf, PAGE_SIZE); len = strnlen(buf, PAGE_SIZE);
if (unlikely(len >= (PAGE_SIZE - 1))) { if (unlikely(len >= (PAGE_SIZE - 1))) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment