Fix sending of unsolicited data in the first burst
When deciding if to generate a data out queue for the first sequence the test was wrong. We should not check if INITIAL_R2T is NO and IMMEDIATE_DATA=NO. Immediate data does not matter here. What we should check is IF we have more data we need to send and IF INITIAL_R2T allows us to send more data, then we generate a train of DATA-OUT. If MaxRecvDataSegmentLength is less than FirstBurstLength we will often have to send unsolicited data as both ImmediateData and also as unsolicited DATA-OUT PDUs. Example: Assume Target has responded : MaxRecvDataSegmentLength = 8k FirstBurstLength = 64k ImmediateData=YES InitialR2T=NO Then this should generate the following sequence : I->T ISCSI_COMMAND + 8K of immediate data. F-Bit is not set. I->T DATA-OUT 8K I->T DATA-OUT 8K I->T DATA-OUT 8K I->T DATA-OUT 8K I->T DATA-OUT 8K I->T DATA-OUT 8K I->T DATA-OUT 8K. Final PDU in sequence so F-bit is set. T->I R2T ...
This commit is contained in:
@@ -265,14 +265,15 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can we send some unsolicited data ? */
|
/* Can we send more data that did not fit as immediate data ? */
|
||||||
if (task->xfer_dir == SCSI_XFER_WRITE
|
if (task->xfer_dir == SCSI_XFER_WRITE
|
||||||
&& iscsi->use_initial_r2t == ISCSI_INITIAL_R2T_NO
|
&& iscsi->use_initial_r2t == ISCSI_INITIAL_R2T_NO
|
||||||
&& iscsi->use_immediate_data == ISCSI_IMMEDIATE_DATA_NO) {
|
&& pdu->out_len < (uint32_t)task->expxferlen
|
||||||
|
&& pdu->out_len < iscsi->first_burst_length) {
|
||||||
uint32_t len = task->expxferlen;
|
uint32_t len = task->expxferlen;
|
||||||
|
|
||||||
if (len > iscsi->first_burst_length) {
|
if (len + pdu->out_len > iscsi->first_burst_length) {
|
||||||
len = iscsi->first_burst_length;
|
len = iscsi->first_burst_length - pdu->out_len;
|
||||||
}
|
}
|
||||||
iscsi_send_data_out(iscsi, pdu, 0xffffffff,
|
iscsi_send_data_out(iscsi, pdu, 0xffffffff,
|
||||||
pdu->out_offset, len);
|
pdu->out_offset, len);
|
||||||
|
|||||||
Reference in New Issue
Block a user