Commit 902b467a authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Jim Harris
Browse files

lib/iscsi: Separate PDU header and payload handling for NOP-Out



As same as SCSI Command Request and SCSI Data-Out, separate PDU
header handling and payload handling into different functions.

In iscsi_op_nopout(), if it sees pdu->is_rejected is true, do nothing.

Signed-off-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: If50cd64bacf18c014e2aa232fd84357b877d9821
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/471011


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent cbdd8335
Loading
Loading
Loading
Loading
+44 −24
Original line number Diff line number Diff line
@@ -3927,36 +3927,25 @@ void spdk_iscsi_send_nopin(struct spdk_iscsi_conn *conn)
}

static int
iscsi_op_nopout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
iscsi_pdu_hdr_op_nopout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
{
	struct spdk_iscsi_pdu *rsp_pdu;
	struct iscsi_bhs_nop_out *reqh;
	struct iscsi_bhs_nop_in *rsph;
	uint8_t *data;
	uint64_t lun;
	uint32_t task_tag;
	uint32_t transfer_tag;
	int I_bit;
	int data_len;

	if (conn->sess->session_type == SESSION_TYPE_DISCOVERY) {
		SPDK_ERRLOG("ISCSI_OP_NOPOUT not allowed in discovery session\n");
		return SPDK_ISCSI_CONNECTION_FATAL;
	}

	if (pdu->data_segment_len > SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH) {
		return iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
	}

	reqh = (struct iscsi_bhs_nop_out *)&pdu->bhs;
	I_bit = reqh->immediate;

	data_len = pdu->data_segment_len;
	if (data_len > conn->MaxRecvDataSegmentLength) {
		data_len = conn->MaxRecvDataSegmentLength;
	if (pdu->data_segment_len > SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH) {
		return iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
	}

	lun = from_be64(&reqh->lun);
	task_tag = from_be32(&reqh->itt);
	transfer_tag = from_be32(&reqh->ttt);

@@ -3975,6 +3964,43 @@ iscsi_op_nopout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
		 */
	}

	if (task_tag == 0xffffffffU && I_bit == 0) {
		SPDK_ERRLOG("got NOPOUT ITT=0xffffffff, I=0\n");
		return SPDK_ISCSI_CONNECTION_FATAL;
	}

	return 0;
}

static int
iscsi_op_nopout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
{
	struct spdk_iscsi_pdu *rsp_pdu;
	struct iscsi_bhs_nop_out *reqh;
	struct iscsi_bhs_nop_in *rsph;
	uint8_t *data;
	uint64_t lun;
	uint32_t task_tag;
	int I_bit;
	int data_len;
	int rc;

	rc = iscsi_pdu_hdr_op_nopout(conn, pdu);
	if (rc != 0 || pdu->is_rejected) {
		return rc;
	}

	reqh = (struct iscsi_bhs_nop_out *)&pdu->bhs;
	I_bit = reqh->immediate;

	data_len = pdu->data_segment_len;
	if (data_len > conn->MaxRecvDataSegmentLength) {
		data_len = conn->MaxRecvDataSegmentLength;
	}

	lun = from_be64(&reqh->lun);
	task_tag = from_be32(&reqh->itt);

	/*
	 * We don't actually check to see if this is a response to the NOP-In
	 * that we sent.  Our goal is to just verify that the initiator is
@@ -3984,13 +4010,9 @@ iscsi_op_nopout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
	conn->nop_outstanding = false;

	if (task_tag == 0xffffffffU) {
		if (I_bit == 1) {
		assert(I_bit == 1);
		SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "got NOPOUT ITT=0xffffffff\n");
		return 0;
		} else {
			SPDK_ERRLOG("got NOPOUT ITT=0xffffffff, I=0\n");
			return SPDK_ISCSI_CONNECTION_FATAL;
		}
	}

	data = calloc(1, data_len);
@@ -4005,8 +4027,6 @@ iscsi_op_nopout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
		memcpy(data, pdu->data, data_len);
	}

	transfer_tag = 0xffffffffU;

	/* response PDU */
	rsp_pdu = spdk_get_pdu();
	if (rsp_pdu == NULL) {
@@ -4020,7 +4040,7 @@ iscsi_op_nopout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
	DSET24(rsph->data_segment_len, data_len);
	to_be64(&rsph->lun, lun);
	to_be32(&rsph->itt, task_tag);
	to_be32(&rsph->ttt, transfer_tag);
	to_be32(&rsph->ttt, 0xffffffffU);

	to_be32(&rsph->stat_sn, conn->StatSN);
	conn->StatSN++;