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; struct iscsi_scsi_cbdata scsi_cbdata;
time_t scsi_timeout; time_t scsi_timeout;
uint32_t expxferlen;
}; };
struct iscsi_pdu *iscsi_allocate_pdu(struct iscsi_context *iscsi, 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) int iscsi_reconnect(struct iscsi_context *old_iscsi)
{ {
struct iscsi_context *iscsi; struct iscsi_context *iscsi;
@@ -342,10 +346,8 @@ try_again:
} }
if (pdu->flags & ISCSI_PDU_DROP_ON_RECONNECT) { 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 * We don't want to requeue NOPs.
* write command is replayed.
* Similarly we don't want to requeue NOPs.
*/ */
iscsi_free_pdu(old_iscsi, pdu); iscsi_free_pdu(old_iscsi, pdu);
continue; continue;
@@ -365,6 +367,14 @@ try_again:
pdu->outdata_written = 0; pdu->outdata_written = 0;
pdu->payload_written = 0; pdu->payload_written = 0;
iscsi_queue_pdu(iscsi, pdu); 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) { 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, iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu,
uint32_t ttt, uint32_t offset, uint32_t tot_len) 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 void
iscsi_pdu_set_expxferlen(struct iscsi_pdu *pdu, uint32_t expxferlen) iscsi_pdu_set_expxferlen(struct iscsi_pdu *pdu, uint32_t expxferlen)
{ {
pdu->expxferlen = expxferlen;
scsi_set_uint32(&pdu->outdata.data[20], expxferlen); scsi_set_uint32(&pdu->outdata.data[20], expxferlen);
} }