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: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: If50cd64bacf18c014e2aa232fd84357b877d9821
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/471011
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Shuhei Matsumoto 2019-10-16 16:36:55 +09:00 committed by Jim Harris
parent cbdd8335fa
commit 902b467aad

View File

@ -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;
}
reqh = (struct iscsi_bhs_nop_out *)&pdu->bhs;
I_bit = reqh->immediate;
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;
}
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++;