diff options
author | Hannes Reinecke <hare@suse.com> | 2019-03-26 10:38:49 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2019-03-28 04:54:53 +0300 |
commit | 56efc304b18cbfa4a2b355c0ae817f61acea38c4 (patch) | |
tree | 3d07b1605b8dcb121ee71eaa655bcb5f469e9180 /drivers/scsi/qedf/qedf_io.c | |
parent | 6f15d0c02950c75f85542031ccbf6a9725ca9925 (diff) | |
download | linux-56efc304b18cbfa4a2b355c0ae817f61acea38c4.tar.xz |
scsi: qedf: fc_rport_priv reference counting fixes
The fc_rport_priv structure is reference counted, so we need to ensure that
the reference is increased before accessing the structure.
Signed-off-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/qedf/qedf_io.c')
-rw-r--r-- | drivers/scsi/qedf/qedf_io.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c index 57c3aa4fb708..56d211674a9a 100644 --- a/drivers/scsi/qedf/qedf_io.c +++ b/drivers/scsi/qedf/qedf_io.c @@ -1799,6 +1799,7 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) goto out; } + qedf = fcport->qedf; rdata = fcport->rdata; if (!rdata || !kref_get_unless_zero(&rdata->kref)) { @@ -1808,32 +1809,31 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) } r_a_tov = rdata->r_a_tov; - qedf = fcport->qedf; lport = qedf->lport; if (lport->state != LPORT_ST_READY || !(lport->link_up)) { QEDF_ERR(&(qedf->dbg_ctx), "link is not ready\n"); rc = 1; - goto out; + goto drop_rdata_kref; } if (atomic_read(&qedf->link_down_tmo_valid) > 0) { QEDF_ERR(&(qedf->dbg_ctx), "link_down_tmo active.\n"); rc = 1; - goto out; + goto drop_rdata_kref; } /* Ensure room on SQ */ if (!atomic_read(&fcport->free_sqes)) { QEDF_ERR(&(qedf->dbg_ctx), "No SQ entries available\n"); rc = 1; - goto out; + goto drop_rdata_kref; } if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) { QEDF_ERR(&qedf->dbg_ctx, "fcport is uploading.\n"); rc = 1; - goto out; + goto drop_rdata_kref; } if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || @@ -1843,7 +1843,7 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) "cleanup or abort processing or already " "completed.\n", io_req->xid); rc = 1; - goto out; + goto drop_rdata_kref; } kref_get(&io_req->refcount); @@ -1876,6 +1876,8 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts) spin_unlock_irqrestore(&fcport->rport_lock, flags); +drop_rdata_kref: + kref_put(&rdata->kref, fc_rport_destroy); out: return rc; } @@ -2217,6 +2219,7 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, unsigned long flags; struct fcoe_wqe *sqe; u16 sqe_idx; + struct fc_rport_priv *rdata = fcport->rdata; if (!sc_cmd) { QEDF_ERR(&(qedf->dbg_ctx), "invalid arg\n"); @@ -2230,8 +2233,13 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd, return FAILED; } - QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_SCSI_TM, "portid = 0x%x " - "tm_flags = %d\n", fcport->rdata->ids.port_id, tm_flags); + if (!rdata || !kref_get_unless_zero(&rdata->kref)) { + QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_SCSI_TM, "stale rport\n"); + return FAILED; + } + QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_SCSI_TM, + "portid = 0x%x tm_flags = %d\n", + rdata->ids.port_id, tm_flags); io_req = qedf_alloc_cmd(fcport, QEDF_TASK_MGMT_CMD); if (!io_req) { @@ -2327,6 +2335,7 @@ no_flush: rc = SUCCESS; } reset_tmf_err: + kref_put(&rdata->kref, fc_rport_destroy); return rc; } |