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:
parent
cbdd8335fa
commit
902b467aad
@ -3927,36 +3927,25 @@ void spdk_iscsi_send_nopin(struct spdk_iscsi_conn *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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_out *reqh;
|
||||||
struct iscsi_bhs_nop_in *rsph;
|
|
||||||
uint8_t *data;
|
|
||||||
uint64_t lun;
|
|
||||||
uint32_t task_tag;
|
uint32_t task_tag;
|
||||||
uint32_t transfer_tag;
|
uint32_t transfer_tag;
|
||||||
int I_bit;
|
int I_bit;
|
||||||
int data_len;
|
|
||||||
|
|
||||||
if (conn->sess->session_type == SESSION_TYPE_DISCOVERY) {
|
if (conn->sess->session_type == SESSION_TYPE_DISCOVERY) {
|
||||||
SPDK_ERRLOG("ISCSI_OP_NOPOUT not allowed in discovery session\n");
|
SPDK_ERRLOG("ISCSI_OP_NOPOUT not allowed in discovery session\n");
|
||||||
return SPDK_ISCSI_CONNECTION_FATAL;
|
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) {
|
if (pdu->data_segment_len > SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH) {
|
||||||
return iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR);
|
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);
|
task_tag = from_be32(&reqh->itt);
|
||||||
transfer_tag = from_be32(&reqh->ttt);
|
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
|
* 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
|
* 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;
|
conn->nop_outstanding = false;
|
||||||
|
|
||||||
if (task_tag == 0xffffffffU) {
|
if (task_tag == 0xffffffffU) {
|
||||||
if (I_bit == 1) {
|
assert(I_bit == 1);
|
||||||
SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "got NOPOUT ITT=0xffffffff\n");
|
SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "got NOPOUT ITT=0xffffffff\n");
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
|
||||||
SPDK_ERRLOG("got NOPOUT ITT=0xffffffff, I=0\n");
|
|
||||||
return SPDK_ISCSI_CONNECTION_FATAL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data = calloc(1, data_len);
|
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);
|
memcpy(data, pdu->data, data_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer_tag = 0xffffffffU;
|
|
||||||
|
|
||||||
/* response PDU */
|
/* response PDU */
|
||||||
rsp_pdu = spdk_get_pdu();
|
rsp_pdu = spdk_get_pdu();
|
||||||
if (rsp_pdu == NULL) {
|
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);
|
DSET24(rsph->data_segment_len, data_len);
|
||||||
to_be64(&rsph->lun, lun);
|
to_be64(&rsph->lun, lun);
|
||||||
to_be32(&rsph->itt, task_tag);
|
to_be32(&rsph->itt, task_tag);
|
||||||
to_be32(&rsph->ttt, transfer_tag);
|
to_be32(&rsph->ttt, 0xffffffffU);
|
||||||
|
|
||||||
to_be32(&rsph->stat_sn, conn->StatSN);
|
to_be32(&rsph->stat_sn, conn->StatSN);
|
||||||
conn->StatSN++;
|
conn->StatSN++;
|
||||||
|
Loading…
Reference in New Issue
Block a user