reconnect: we must re-queue any missing data-outs during reconnect

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>
This commit is contained in:
Ronnie Sahlberg
2015-02-17 06:46:58 -08:00
parent 8ae706630e
commit b001d980ef
4 changed files with 17 additions and 5 deletions

View File

@@ -245,6 +245,7 @@ struct iscsi_pdu {
struct iscsi_scsi_cbdata scsi_cbdata;
time_t scsi_timeout;
uint32_t expxferlen;
};
struct iscsi_pdu *iscsi_allocate_pdu(struct iscsi_context *iscsi,

View File

@@ -242,6 +242,10 @@ void iscsi_defer_reconnect(struct iscsi_context *iscsi)
}
}
int
iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu,
uint32_t ttt, uint32_t offset, uint32_t tot_len);
int iscsi_reconnect(struct iscsi_context *old_iscsi)
{
struct iscsi_context *iscsi;
@@ -342,10 +346,8 @@ try_again:
}
if (pdu->flags & ISCSI_PDU_DROP_ON_RECONNECT) {
/* We don't want to requeue things like DATA-OUT since these guys
* will be reissued automatically anyway once the corresponding
* write command is replayed.
* Similarly we don't want to requeue NOPs.
/*
* We don't want to requeue NOPs.
*/
iscsi_free_pdu(old_iscsi, pdu);
continue;
@@ -365,6 +367,14 @@ try_again:
pdu->outdata_written = 0;
pdu->payload_written = 0;
iscsi_queue_pdu(iscsi, pdu);
/* All PDUs that write data and do not have final set
* needs some additional data-out to be requeued.
*/
if ((pdu->outdata.data[1] & (ISCSI_PDU_SCSI_WRITE | ISCSI_PDU_SCSI_FINAL)) == ISCSI_PDU_SCSI_WRITE) {
iscsi_send_data_out(iscsi, pdu, 0xffffffff,
pdu->payload_len,
pdu->expxferlen - pdu->payload_len);
}
}
if (dup2(iscsi->fd, old_iscsi->fd) == -1) {

View File

@@ -67,7 +67,7 @@ iscsi_scsi_response_cb(struct iscsi_context *iscsi, int status,
}
}
static int
int
iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu,
uint32_t ttt, uint32_t offset, uint32_t tot_len)
{

View File

@@ -670,5 +670,6 @@ iscsi_pdu_set_lun(struct iscsi_pdu *pdu, uint32_t lun)
void
iscsi_pdu_set_expxferlen(struct iscsi_pdu *pdu, uint32_t expxferlen)
{
pdu->expxferlen = expxferlen;
scsi_set_uint32(&pdu->outdata.data[20], expxferlen);
}