Commit 9e5fe170 authored by Mike Christie's avatar Mike Christie Committed by Martin K. Petersen
Browse files

scsi: iscsi: Rel ref after iscsi_lookup_endpoint()

Subsequent commits allow the kernel to do ep_disconnect. In that case we
will have to get a proper refcount on the ep so one thread does not delete
it from under another.

Link: https://lore.kernel.org/r/20210525181821.7617-7-michael.christie@oracle.com


Reviewed-by: default avatarLee Duncan <lduncan@suse.com>
Signed-off-by: default avatarMike Christie <michael.christie@oracle.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent b25b957d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -506,6 +506,7 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
	iser_conn->iscsi_conn = conn;

out:
	iscsi_put_endpoint(ep);
	mutex_unlock(&iser_conn->state_mutex);
	return error;
}
+13 −6
Original line number Diff line number Diff line
@@ -182,6 +182,7 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
	struct beiscsi_endpoint *beiscsi_ep;
	struct iscsi_endpoint *ep;
	uint16_t cri_index;
	int rc = 0;

	ep = iscsi_lookup_endpoint(transport_fd);
	if (!ep)
@@ -189,15 +190,17 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,

	beiscsi_ep = ep->dd_data;

	if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
		return -EINVAL;
	if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) {
		rc = -EINVAL;
		goto put_ep;
	}

	if (beiscsi_ep->phba != phba) {
		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
			    "BS_%d : beiscsi_ep->hba=%p not equal to phba=%p\n",
			    beiscsi_ep->phba, phba);

		return -EEXIST;
		rc = -EEXIST;
		goto put_ep;
	}
	cri_index = BE_GET_CRI_FROM_CID(beiscsi_ep->ep_cid);
	if (phba->conn_table[cri_index]) {
@@ -209,7 +212,8 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
				      beiscsi_ep->ep_cid,
				      beiscsi_conn,
				      phba->conn_table[cri_index]);
			return -EINVAL;
			rc = -EINVAL;
			goto put_ep;
		}
	}

@@ -226,7 +230,10 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
		    "BS_%d : cid %d phba->conn_table[%u]=%p\n",
		    beiscsi_ep->ep_cid, cri_index, beiscsi_conn);
	phba->conn_table[cri_index] = beiscsi_conn;
	return 0;

put_ep:
	iscsi_put_endpoint(ep);
	return rc;
}

static int beiscsi_iface_create_ipv4(struct beiscsi_hba *phba)
+16 −7
Original line number Diff line number Diff line
@@ -1420,17 +1420,23 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
	 * Forcefully terminate all in progress connection recovery at the
	 * earliest, either in bind(), send_pdu(LOGIN), or conn_start()
	 */
	if (bnx2i_adapter_ready(hba))
		return -EIO;
	if (bnx2i_adapter_ready(hba)) {
		ret_code = -EIO;
		goto put_ep;
	}

	bnx2i_ep = ep->dd_data;
	if ((bnx2i_ep->state == EP_STATE_TCP_FIN_RCVD) ||
	    (bnx2i_ep->state == EP_STATE_TCP_RST_RCVD))
	    (bnx2i_ep->state == EP_STATE_TCP_RST_RCVD)) {
		/* Peer disconnect via' FIN or RST */
		return -EINVAL;
		ret_code = -EINVAL;
		goto put_ep;
	}

	if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
		return -EINVAL;
	if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) {
		ret_code = -EINVAL;
		goto put_ep;
	}

	if (bnx2i_ep->hba != hba) {
		/* Error - TCP connection does not belong to this device
@@ -1441,7 +1447,8 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
		iscsi_conn_printk(KERN_ALERT, cls_conn->dd_data,
				  "belong to hba (%s)\n",
				  hba->netdev->name);
		return -EEXIST;
		ret_code = -EEXIST;
		goto put_ep;
	}
	bnx2i_ep->conn = bnx2i_conn;
	bnx2i_conn->ep = bnx2i_ep;
@@ -1458,6 +1465,8 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
		bnx2i_put_rq_buf(bnx2i_conn, 0);

	bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE);
put_ep:
	iscsi_put_endpoint(ep);
	return ret_code;
}

+8 −4
Original line number Diff line number Diff line
@@ -2690,11 +2690,13 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
	err = csk->cdev->csk_ddp_setup_pgidx(csk, csk->tid,
					     ppm->tformat.pgsz_idx_dflt);
	if (err < 0)
		return err;
		goto put_ep;

	err = iscsi_conn_bind(cls_session, cls_conn, is_leading);
	if (err)
		return -EINVAL;
	if (err) {
		err = -EINVAL;
		goto put_ep;
	}

	/*  calculate the tag idx bits needed for this conn based on cmds_max */
	cconn->task_idx_bits = (__ilog2_u32(conn->session->cmds_max - 1)) + 1;
@@ -2715,7 +2717,9 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
	/*  init recv engine */
	iscsi_tcp_hdr_recv_prep(tcp_conn);

	return 0;
put_ep:
	iscsi_put_endpoint(ep);
	return err;
}
EXPORT_SYMBOL_GPL(cxgbi_bind_conn);

+18 −7
Original line number Diff line number Diff line
@@ -377,6 +377,7 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session,
	struct qedi_ctx *qedi = iscsi_host_priv(shost);
	struct qedi_endpoint *qedi_ep;
	struct iscsi_endpoint *ep;
	int rc = 0;

	ep = iscsi_lookup_endpoint(transport_fd);
	if (!ep)
@@ -384,11 +385,16 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session,

	qedi_ep = ep->dd_data;
	if ((qedi_ep->state == EP_STATE_TCP_FIN_RCVD) ||
	    (qedi_ep->state == EP_STATE_TCP_RST_RCVD))
		return -EINVAL;
	    (qedi_ep->state == EP_STATE_TCP_RST_RCVD)) {
		rc = -EINVAL;
		goto put_ep;
	}

	if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) {
		rc = -EINVAL;
		goto put_ep;
	}

	if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
		return -EINVAL;

	qedi_ep->conn = qedi_conn;
	qedi_conn->ep = qedi_ep;
@@ -398,13 +404,18 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session,
	qedi_conn->cmd_cleanup_req = 0;
	qedi_conn->cmd_cleanup_cmpl = 0;

	if (qedi_bind_conn_to_iscsi_cid(qedi, qedi_conn))
		return -EINVAL;
	if (qedi_bind_conn_to_iscsi_cid(qedi, qedi_conn)) {
		rc = -EINVAL;
		goto put_ep;
	}


	spin_lock_init(&qedi_conn->tmf_work_lock);
	INIT_LIST_HEAD(&qedi_conn->tmf_work_list);
	init_waitqueue_head(&qedi_conn->wait_queue);
	return 0;
put_ep:
	iscsi_put_endpoint(ep);
	return rc;
}

static int qedi_iscsi_update_conn(struct qedi_ctx *qedi,
Loading