Honour MaxRecvDataSegmentLength from the target and split DATAOUT into

chunks of this size.
This commit is contained in:
Ronnie Sahlberg
2011-01-02 18:50:49 +11:00
parent d240e8b5aa
commit 502843d64a

View File

@@ -82,72 +82,87 @@ iscsi_scsi_response_cb(struct iscsi_context *iscsi, int status,
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 offset, uint32_t len) uint32_t offset, uint32_t tot_len)
{ {
struct iscsi_pdu *pdu; while (tot_len > 0) {
int flags; uint32_t len = tot_len;
struct iscsi_pdu *pdu;
int flags;
pdu = iscsi_allocate_pdu_with_itt_flags(iscsi, ISCSI_PDU_DATA_OUT, if (len > iscsi->target_max_recv_data_segment_length) {
len = iscsi->target_max_recv_data_segment_length;
}
pdu = iscsi_allocate_pdu_with_itt_flags(iscsi, ISCSI_PDU_DATA_OUT,
ISCSI_PDU_NO_PDU, ISCSI_PDU_NO_PDU,
cmd_pdu->itt, cmd_pdu->itt,
ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK); ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK);
if (pdu == NULL) { if (pdu == NULL) {
iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate " iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate "
"scsi data out pdu."); "scsi data out pdu.");
SLIST_REMOVE(&iscsi->outqueue, cmd_pdu); SLIST_REMOVE(&iscsi->outqueue, cmd_pdu);
SLIST_REMOVE(&iscsi->waitpdu, cmd_pdu); SLIST_REMOVE(&iscsi->waitpdu, cmd_pdu);
cmd_pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, cmd_pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
cmd_pdu->private_data); cmd_pdu->private_data);
iscsi_free_pdu(iscsi, cmd_pdu); iscsi_free_pdu(iscsi, cmd_pdu);
return -1; return -1;
}
flags = ISCSI_PDU_SCSI_FINAL; }
/* flags */ if (tot_len == len) {
iscsi_pdu_set_pduflags(pdu, flags); flags = ISCSI_PDU_SCSI_FINAL;
} else {
flags = 0;
}
/* lun */ /* flags */
iscsi_pdu_set_lun(pdu, cmd_pdu->lun); iscsi_pdu_set_pduflags(pdu, flags);
/* ttt */ /* lun */
iscsi_pdu_set_ttt(pdu, 0xffffffff); iscsi_pdu_set_lun(pdu, cmd_pdu->lun);
/* exp statsn */ /* ttt */
iscsi_pdu_set_expstatsn(pdu, iscsi->statsn+1); iscsi_pdu_set_ttt(pdu, 0xffffffff);
/* data sn */ /* exp statsn */
iscsi_pdu_set_datasn(pdu, 0); iscsi_pdu_set_expstatsn(pdu, iscsi->statsn+1);
/* buffer offset */ /* data sn */
iscsi_pdu_set_bufferoffset(pdu, offset); iscsi_pdu_set_datasn(pdu, 0);
if (iscsi_pdu_add_data(iscsi, pdu, cmd_pdu->nidata.data + offset, len) /* buffer offset */
iscsi_pdu_set_bufferoffset(pdu, offset);
if (iscsi_pdu_add_data(iscsi, pdu, cmd_pdu->nidata.data + offset, len)
!= 0) { != 0) {
iscsi_set_error(iscsi, "Out-of-memory: Failed to " iscsi_set_error(iscsi, "Out-of-memory: Failed to "
"add outdata to the pdu."); "add outdata to the pdu.");
SLIST_REMOVE(&iscsi->outqueue, cmd_pdu); SLIST_REMOVE(&iscsi->outqueue, cmd_pdu);
SLIST_REMOVE(&iscsi->waitpdu, cmd_pdu); SLIST_REMOVE(&iscsi->waitpdu, cmd_pdu);
cmd_pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, cmd_pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
cmd_pdu->private_data); cmd_pdu->private_data);
iscsi_free_pdu(iscsi, cmd_pdu); iscsi_free_pdu(iscsi, cmd_pdu);
iscsi_free_pdu(iscsi, pdu); iscsi_free_pdu(iscsi, pdu);
return -1; return -1;
} }
pdu->callback = cmd_pdu->callback; pdu->callback = cmd_pdu->callback;
pdu->private_data = cmd_pdu->private_data;; pdu->private_data = cmd_pdu->private_data;;
if (iscsi_queue_pdu(iscsi, pdu) != 0) { if (iscsi_queue_pdu(iscsi, pdu) != 0) {
iscsi_set_error(iscsi, "Out-of-memory: failed to queue iscsi " iscsi_set_error(iscsi, "Out-of-memory: failed to queue iscsi "
"scsi pdu."); "scsi pdu.");
SLIST_REMOVE(&iscsi->outqueue, cmd_pdu); SLIST_REMOVE(&iscsi->outqueue, cmd_pdu);
SLIST_REMOVE(&iscsi->waitpdu, cmd_pdu); SLIST_REMOVE(&iscsi->waitpdu, cmd_pdu);
cmd_pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, cmd_pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
cmd_pdu->private_data); cmd_pdu->private_data);
iscsi_free_pdu(iscsi, cmd_pdu); iscsi_free_pdu(iscsi, cmd_pdu);
iscsi_free_pdu(iscsi, pdu); iscsi_free_pdu(iscsi, pdu);
return -1; return -1;
}
tot_len -= len;
offset += len;
} }
return 0; return 0;
} }