> From: Sumit Rai <sumit....@calsoftinc.com>
> Subject: LIO seems to use SCSI Allocation Length instead of SPDTL for 
> calculating ResidualCount
> Date: June 22, 2016 at 7:43:50 PM GMT+5:30
> To: target-de...@vger.kernel.org
> 
> We are trying to test if LIO target sets ResidualCount correctly in case of 
> ResidualOverflow for Data-In by following the below Steps:
> 1. Send SCSI Inquiry command to iSCSI target, if there are no exceptions in 
> the response (and no residual overflow) we are able to determine how many 
> bytes the target SCSI layer on target side attempted to transfer to target 
> iSCSI layer. On the initiator side when response is received: in the absence 
> of any exceptions or residual overflow we assume all the data was 
> successfully transferred and is equal to iSCSI DataSegmentLength. We will use 
> this value as SPDTL for SCSI Inquiry command.
> 
> Note: SPDTL is detailed in RFC 7143 11.4.5.2 (and you may also refer to 
> discussion on T10 mailing list: 
> http://www.t10.org/pipermail/t10/2014-June/017367.html).
> 
> 2. Send out the same SCSI inquiry command as in Step 1. but set iSCSI EDTL to 
> a value lower than SPDTL.
> 
> Assumption: Since we are not making any changes to iSCSI target LU 
> configuration in our setup b/w Step 1. and 2, we assume amount of Inquiry 
> Data target generates will be same of 1. and 2. since inquiry command is the 
> same. During our testing we find this assumption to be true.
> 
> Expected Result:
> Since in Step 2, SPDTL > EDTL, iSCSI target is expected to set 
> ResidualOverflow flag and ResidualCount to SPDTL - EDTL.
> In the attached PCAP text file, frame no. 11 (SCSI Inquiry Req.) and 12 
> (Inquiry Response) are for Step 1. As explained, SPDTL = 0x24 or 36D.
> Frame no. 14 is for (SCSI Inq. Req.) Step 2. EDTL = 0x08.
> Hence, expected ResidualCount = 0x1C (28D) i.e. 0x24 (36D) - 0x08 (8D)
> 
> Observed Result:
> iSCSI target sets the Residual Overflow flag correctly but value of 
> ResidualCount doesn’t match expected value.
> Target is setting, ResidualCount to 0x3f8 (1016D) as seen in frame no 16. In 
> the frame no. 14, in the SCSI Inquiry CDB allocation length (SPC 5r01 Section 
> 4.2.5.6) was set to 0x0400 (1024D) and target seems to be using this value to 
> calculate ResidualCount i.e. 0x0400 (1024D) - 0x08.
> To further verify this we  changed the allocation length value in SCSI 
> Inquiry CDB to 0x0200 (512D) bytes instead, we get ResidualCount of 0x1f8 
> (504D).
> 
> Allocation Length is the maximum value of the SPDTL and not substitute for 
> it, hence it shouldn’t be used to calculate ResidualCount except for cases 
> where SPDTL > Allocation Length and Data is truncated (in that case both 
> Alloc Len and SPDTL are same). (SPC 5r01 Section 4.2.5.6).
> 
> LIO Version: Datera Inc. iSCSI Target v4.1.0
> Linux Kernel: 4.4.0-22-generic
> 
> RFC 7143:
> 
> 11.4.5.2.  Residuals Concepts Overview
> 
> 
>   "SCSI-Presented Data Transfer Length (SPDTL)" is the term this
>   document uses (see 
> Section 2.2
> for definition) to represent the
>   aggregate data length that the target SCSI layer attempts to transfer
>   using the local iSCSI layer for a task.  "Expected Data Transfer
> 
>   Length (EDTL)" is the iSCSI term that represents the length of data
>   that the iSCSI layer expects to transfer for a task.  EDTL is
>   specified in the SCSI Command PDU.
> 
>   When SPDTL = EDTL for a task, the target iSCSI layer completes the
>   task with no residuals.  Whenever SPDTL differs from EDTL for a task,
>   that task is said to have a residual.
> 
>   If SPDTL > EDTL for a task, iSCSI Overflow MUST be signaled in the
>   SCSI Response PDU as specified in 
> Section 11.4.5.1
> .  The Residual
>   Count MUST be set to the numerical value of (SPDTL - EDTL).
> 
>   If SPDTL < EDTL for a task, iSCSI Underflow MUST be signaled in the
>   SCSI Response PDU as specified in 
> Section 11.4.5.1
> .  The Residual
>   Count MUST be set to the numerical value of (EDTL - SPDTL).
> 
>   Note that the Overflow and Underflow scenarios are independent of
>   Data-In and Data-Out.  Either scenario is logically possible in
> 
> 
> SPC 5r01
> 4.2.5.6 Allocation length
> 
> The ALLOCATION LENGTH field specifies the maximum number of bytes or blocks 
> that an application client has allocated in the Data-In Buffer. The 
> ALLOCATION LENGTH field specifies bytes unless a different requirement is 
> stated in the command definition.
> 
> An allocation length of zero specifies that no data shall be transferred. 
> This condition shall not be considered an error.
> 
> The device server shall terminate transfers to the Data-In Buffer when the 
> number of bytes or blocks specified by the ALLOCATION LENGTH field have been 
> transferred or when all available data have been transferred, whichever is 
> less. The allocation length is used to limit the maximum amount of variable 
> length data (e.g., mode data, log data, diagnostic data) returned to an 
> application client. If the information being transferred to the Data-In 
> Buffer includes fields containing counts of the number of bytes in some or 
> all of the data (e.g., a PARAMETER DATA LENGTH field, a PAGE LENGTH field, a 
> DESCRIPTOR LENGTH field, an AVAILABLE DATA field), then the contents of these 
> fields shall not be altered to reflect the truncation, if any, that results 
> from an insufficient ALLOCATION LENGTH value, unless the standard that 
> describes the Data-In Buffer format states otherwise.
> 
> If the amount of information that is available to be transferred exceeds the 
> maximum value that the ALLOCATION LENGTH field in combination with other 
> fields in the CDB is capable of specifying, then no data shall be transferred 
> and the command shall be terminated with CHECK CONDITION status, with the 
> sense key set to ILLEGAL REQUEST, and the additional sense code set to 
> INVALID FIELD IN CDB. 

I havn't received any comments on this issue, I guess the maintainer(s) are 
occpied with
other high priority issues, so I tried to fix the issue. I have successfully 
tested
the patch and it calculates the residual count as expected. I would appreciate 
it if someone
can do a review of the below patch:

--- linux/drivers/target/target_core_transport.c.orig   2016-07-03 
18:09:28.949281611 +0530
+++ linux/drivers/target/target_core_transport.c        2016-07-03 
18:10:44.007293696 +0530
@@ -754,7 +754,15 @@ EXPORT_SYMBOL(target_complete_cmd);
 
 void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int 
length)
 {
-       if (scsi_status == SAM_STAT_GOOD && length < cmd->data_length) {
+       if (scsi_status != SAM_STAT_GOOD) {
+               return;
+       }
+
+       /*
+        * Calculate new residual count based upon length of SCSI data
+        * transferred.
+        */
+       if (length < cmd->data_length) {
                if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
                        cmd->residual_count += cmd->data_length - length;
                } else {
@@ -763,6 +771,12 @@ void target_complete_cmd_with_length(str
                }
 
                cmd->data_length = length;
+       } else if (length > cmd->data_length) {
+               cmd->se_cmd_flags |= SCF_OVERFLOW_BIT;
+               cmd->residual_count = length - cmd->data_length;
+       } else {
+               cmd->se_cmd_flags &= ~(SCF_OVERFLOW_BIT | SCF_UNDERFLOW_BIT);
+               cmd->residual_count = 0;
        }
 
        target_complete_cmd(cmd, scsi_status);
Signed-off-by: Sumit Rai <sumitra...@gmail.com>

Thanks to Ajay Nair in assisting with this patch.

Thanks,
Sumit Rai
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to