Rework the reconnect logic so we just call iscsi_scsi_command_async()
for the scsi commands we are re-quining instead of poking into the
private fields of the structures themself.
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Remove iscsi_allocate_pdu() which is just a wrapper.
Rename iscsi_allocate_pdu_with_itt_flags() to iscsi_allocate_pdu()
and update all callers.
This only removes a wrapper function and contains no logic changes.
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
the recent implementation allows to send
iscsi->first_burst_length + iscsi->target_max_recv_data_segment_length
bytes if immediate and unsolicited data-out is send and
iscsi->target_max_recv_data_segment_length < iscsi->first_burst_length.
RFC3720 defines the length as:
Length=(min(FirstBurstLength, Expected Data
Transfer Length) - Received Immediate Data Length).
so that immediate data and unsolicited data-out are together
FirstBurstLength at maximum.
Signed-off-by: Peter Lieven <pl@kamp.de>
We write unsolicited data-out PDUs from two places;
when we originally write the command in iscsi_scsi_command_async()
but also when we re-queue the PDUs during a session reconnect.
The re-queuing during the session re-connect was recently (almost) fixed
but was still buggy in that it did not correctly clamp the amount of written
data as per first burst length restriction.
This attempts to fix that.
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Both are the same value at this point but it is better to
do the computation only based on pdy-> fields.
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
If we have writes that do not have the Final bit set during reconnect
we must send out any missing data-out PDU.
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
If we have send unsolicited immediate data and are ALSO sending
unsilocoted data-out, then we have to exclude the length of data we have already sent.
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
From the SPC-4 paragraph about WRITE SAME(10): "The WRITE SAME (10)
command requests that the device server transfer a single logical
block from the Data-Out Buffer [ ... ]". Hence always pass a data
buffer when sending a WRITE SAME(10) command.
Set the NDOB bit in the WRITE SAME(16) command if no data out buffer
is present.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Rename the macros for managing the linked lists from SLIST_* to ISCSI_LIST_*
to avoid a clash on *BSD which already have other macros SLIST_*
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Previously COMPAREANDWRITE was only sending verify instance data which
can cause targets to generate COMMAND ABORTED/NOT ENOUGH UNSOLICITED
DATA errors due to the buffer being obviously too small to contain
verify AND write instance data.
The buffer size check has been modified and compareandwrite tests
updated to pass a larger buffer with interesting write instance data.
Default to 0 meaning no timeout.
Implement a test for iSCS to test what happens if we send a command
with CMDSN being higher than the target allows.
In this case we dont strictly know what will happen, just that what should
NOT happen is the target responding with success.
But we have to be prepared for any kind of failure, including a timeout,
scsi sense, or even iscsi reject or session failure.
Add support for BUSY status coide from the target and just pass this
back to the application as is (instead of converting it to _ERROR).
This allows the application to trap task->status==SCSI_STATUS_BUSY and
decide what/how to proceed.
This patch adds support for read/writev to directly read and write
from/to iovectors. Before this patch on read and write from/to socket
the operation was limited by the iovec boundaries. If there is enough
data in the buffer or enough buffer space available its now possible
to transfer the whole data in one atomic operaion.
Signed-off-by: Peter Lieven <pl@kamp.de>
Just like DATA_OUT we should just discard NOPs instead of requeueing them
on session reconnect.
Add new flag that to indicate this behaviour on reconnect and set it for
both data out and nops
The preallocation logic was messing with size and offset of pdu->indata.
This was broken when we removed iscsi_data->alloc_size. Removing
entirely since reading without iovectors is deprecated.
Signed-off-by: Peter Lieven <pl@kamp.de>
Add comments to explain how/why we send unsolicited data.
This is a somewhat hairy area and it is easy to make mistakes here, so
extra comments on the how/why is useful.
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
...
If we do a write that spans more than first-burst-length amount of data
and we can use immediate data.
This will lead to a sequence
I->T SCSI_COMMAND + furst_burst_length of immediate data
T->I R2T
I->T DATA-OUT with the remainder of the data.
T->I SCSI_RESPONSE
In this situation we still have to set the F-bit in the flags for the ISCSI_COMMAND.
The F-bit indicates that the PDU is the final PDU in the current sequence
and is what will trigger the target to process what it has currently received
after which the target will either respond with a SCSI-RESULT or DATA-IN if this
was the final sequence of the command,
Or in the case this was not the last sequence, then the target will send a R2T
to request the next sequence for this command.
In this scenario above we have two sequences.
the first sequence is the SCSI_COMMAND with immediate data and since it has filled the full amount of immediate data and can not send any more data until an R2T, this means this pdu ends the sequence and thus has the F-bit set.
Once we receive the R2T the second sequence starts, which also will have the F-bit set in the PDU.
This fixes the IMMEDIATE_DATA_YES case if the paylaod did
not fit into the first PDU and fixes no unsolicited data
sent out iff IMMEDIATE_DATA_NO and INITIAL_R2T_NO.
Signed-off-by: Peter Lieven <pl@kamp.de>
set the cmdsn in the pdu struct so we can compare with
maxcmdsn when sending to socket even if data-out pdus
do not carry a cmdsn on the wire.
if we would not set pdu->cmdsn comparsion with
iscsi->maxcmdsn would cause a deadlock after
maxcmdsn increases to 2^31.
Signed-off-by: Peter Lieven <pl@kamp.de>
The send logic was completely broken for any cases except
ISCSI_INITIAL_R2T_NO and ISCSI_IMMEDIATE_DATA_YES.
The final flag was set wrong or no data was sent.
It was also broken if the data did not fit into the cmd_pdu as
the consecutive pdus did not have the scsi_cbdata set which
lead to a segfault in iscsi_get_user_out_buffer().
Unfortunately we need to include scsi-lowlevel.h again in iscsi-private.h.
This should be fixed asap by introduction of an iscsi_task struct
to avoid to store iscsi relevant data in the scsi_task.
Signed-off-by: Peter Lieven <pl@kamp.de>
Conflicts:
lib/iscsi-command.c
Signed-off-by: Peter Lieven <pl@kamp.de>