iscsi: Get LUN ID from task instead of Data-Out PDU to fix SCSI compliance test failure

A major SCSI compliance test expects that the LUN field is reserved
(not to be checked) in the SCSI Data-Out PDU.

In that test, the LUN field in the first SCSI Command PDU is 0 and
the LUN field in the SCSI Data-Out PDU sent in response to the R2T
is 0xFFFFFFFFFFFFFFFF. The TTT field in the SCSI Data-Out PDU is 0xF that
is copied from the R2T. 0xF is valid as TTT.

Hence spdk_iscsi_op_data() returns Check Condition because LUN is
not found.

This patch changes to get LUN ID from not the LUN field in the SCSI
Data-Out PDU but the saved task.

The following is excerpts from iSCSI specification (RFC7143). The
behavior of the SCSI compliance test looks against the specification
but changing SPDK will be safer.

11.7.4.  Target Transfer Tag and LUN

   On outgoing data, the Target Transfer Tag is provided to the target
   if the transfer is honoring an R2T.  In this case, the Target
   Transfer Tag field is a replica of the Target Transfer Tag provided
   with the R2T.

   On incoming data, the Target Transfer Tag and LUN MUST be provided by
   the target if the A bit is set to 1; otherwise, they are reserved.
   The Target Transfer Tag and LUN are copied by the initiator into the
   SNACK of type DataACK that it issues as a result of receiving a SCSI
   Data-In PDU with the A bit set to 1.

   The Target Transfer Tag values are not specified by this protocol,
   except that the value 0xffffffff is reserved and means that the
   Target Transfer Tag is not supplied.  If the Target Transfer Tag is
   provided, then the LUN field MUST hold a valid value and be
   consistent with whatever was specified with the command; otherwise,
   the LUN field is reserved.

Change-Id: I110a7e396d1e517b2a39ca5e586ab2bb2d45e5f3
Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/425333
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Shuhei Matsumoto 2018-09-12 11:14:42 +09:00 committed by Jim Harris
parent b67d175529
commit 855633a597

View File

@ -3935,8 +3935,6 @@ static int spdk_iscsi_op_data(struct spdk_iscsi_conn *conn,
uint32_t DataSN; uint32_t DataSN;
uint32_t buffer_offset; uint32_t buffer_offset;
uint32_t len; uint32_t len;
uint64_t lun;
int lun_i;
int F_bit; int F_bit;
int rc; int rc;
int reject_reason = ISCSI_REASON_INVALID_PDU_FIELD; int reject_reason = ISCSI_REASON_INVALID_PDU_FIELD;
@ -3952,9 +3950,6 @@ static int spdk_iscsi_op_data(struct spdk_iscsi_conn *conn,
task_tag = from_be32(&reqh->itt); task_tag = from_be32(&reqh->itt);
DataSN = from_be32(&reqh->data_sn); DataSN = from_be32(&reqh->data_sn);
buffer_offset = from_be32(&reqh->buffer_offset); buffer_offset = from_be32(&reqh->buffer_offset);
lun = from_be64(&reqh->lun);
lun_i = spdk_islun2lun(lun);
lun_dev = spdk_scsi_dev_get_lun(conn->dev, lun_i);
task = spdk_get_transfer_task(conn, transfer_tag); task = spdk_get_transfer_task(conn, transfer_tag);
if (task == NULL) { if (task == NULL) {
@ -3962,6 +3957,8 @@ static int spdk_iscsi_op_data(struct spdk_iscsi_conn *conn,
goto reject_return; goto reject_return;
} }
lun_dev = spdk_scsi_dev_get_lun(conn->dev, task->lun_id);
if (pdu->data_segment_len > task->desired_data_transfer_length) { if (pdu->data_segment_len > task->desired_data_transfer_length) {
SPDK_ERRLOG("the dataout pdu data length is larger than the value sent by R2T PDU\n"); SPDK_ERRLOG("the dataout pdu data length is larger than the value sent by R2T PDU\n");
return SPDK_ISCSI_CONNECTION_FATAL; return SPDK_ISCSI_CONNECTION_FATAL;
@ -4033,7 +4030,8 @@ static int spdk_iscsi_op_data(struct spdk_iscsi_conn *conn,
} }
if (lun_dev == NULL) { if (lun_dev == NULL) {
SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "LUN %d is removed, complete the task immediately\n", lun_i); SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "LUN %d is removed, complete the task immediately\n",
task->lun_id);
subtask->scsi.transfer_len = subtask->scsi.length; subtask->scsi.transfer_len = subtask->scsi.length;
spdk_scsi_task_process_null_lun(&subtask->scsi); spdk_scsi_task_process_null_lun(&subtask->scsi);
spdk_iscsi_task_cpl(&subtask->scsi); spdk_iscsi_task_cpl(&subtask->scsi);