diff --git a/include/iscsi-private.h b/include/iscsi-private.h index ddf7807..528b9a1 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -215,11 +215,21 @@ void iscsi_free_scsi_cbdata(struct iscsi_context *iscsi, struct iscsi_scsi_cbdat struct iscsi_pdu *iscsi_allocate_pdu(struct iscsi_context *iscsi, enum iscsi_opcode opcode, enum iscsi_opcode response_opcode); +struct iscsi_pdu *iscsi_allocate_pdu_size(struct iscsi_context *iscsi, + enum iscsi_opcode opcode, + enum iscsi_opcode response_opcode, + size_t payload_size); struct iscsi_pdu *iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode opcode, enum iscsi_opcode response_opcode, uint32_t itt, uint32_t flags); +struct iscsi_pdu *iscsi_allocate_pdu_with_itt_flags_size(struct iscsi_context *iscsi, + enum iscsi_opcode opcode, + enum iscsi_opcode response_opcode, + uint32_t itt, + uint32_t flags, + size_t payload_size); void iscsi_free_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu); void iscsi_pdu_set_pduflags(struct iscsi_pdu *pdu, unsigned char flags); void iscsi_pdu_set_immediate(struct iscsi_pdu *pdu); diff --git a/include/iscsi.h b/include/iscsi.h index 9753d22..6ac7f0e 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -33,7 +33,6 @@ struct iscsi_context; struct sockaddr; #define MAX_STRING_SIZE (255) -#define PAGE_SIZE (4096) /* * Syntax for normal and portal/discovery URLs. diff --git a/lib/login.c b/lib/login.c index 04368d2..5728007 100644 --- a/lib/login.c +++ b/lib/login.c @@ -735,10 +735,10 @@ iscsi_login_async(struct iscsi_context *iscsi, iscsi_command_cb cb, return -1; } - pdu = iscsi_allocate_pdu_with_itt_flags(iscsi, + pdu = iscsi_allocate_pdu_with_itt_flags_size(iscsi, ISCSI_PDU_LOGIN_REQUEST, ISCSI_PDU_LOGIN_RESPONSE, - iscsi->itt, 0); + iscsi->itt, 0, 1024); if (pdu == NULL) { iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate " "login pdu."); diff --git a/lib/pdu.c b/lib/pdu.c index 86dc2b1..f2e11ba 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -31,8 +31,8 @@ #include "slist.h" struct iscsi_pdu * -iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode opcode, - enum iscsi_opcode response_opcode, uint32_t itt, uint32_t flags) +iscsi_allocate_pdu_with_itt_flags_size(struct iscsi_context *iscsi, enum iscsi_opcode opcode, + enum iscsi_opcode response_opcode, uint32_t itt, uint32_t flags, size_t payload_size) { struct iscsi_pdu *pdu; @@ -43,7 +43,10 @@ iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode } pdu->outdata.size = ISCSI_HEADER_SIZE; - pdu->outdata.data = iscsi_zmalloc(iscsi, pdu->outdata.size); + pdu->outdata.alloc_size = 64; + while (pdu->outdata.alloc_size < ISCSI_HEADER_SIZE+payload_size) pdu->outdata.alloc_size<<=1; + pdu->outdata.data = iscsi_malloc(iscsi, pdu->outdata.alloc_size); + memset(pdu->outdata.data, 0, ISCSI_HEADER_SIZE); if (pdu->outdata.data == NULL) { iscsi_set_error(iscsi, "failed to allocate pdu header"); @@ -70,6 +73,13 @@ iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode return pdu; } +struct iscsi_pdu * +iscsi_allocate_pdu_with_itt_flags(struct iscsi_context *iscsi, enum iscsi_opcode opcode, + enum iscsi_opcode response_opcode, uint32_t itt, uint32_t flags) +{ + return iscsi_allocate_pdu_with_itt_flags_size(iscsi, opcode, response_opcode, itt, flags, 0); +} + struct iscsi_pdu * iscsi_allocate_pdu(struct iscsi_context *iscsi, enum iscsi_opcode opcode, enum iscsi_opcode response_opcode) @@ -77,6 +87,13 @@ iscsi_allocate_pdu(struct iscsi_context *iscsi, enum iscsi_opcode opcode, return iscsi_allocate_pdu_with_itt_flags(iscsi, opcode, response_opcode, iscsi->itt++, 0); } +struct iscsi_pdu * +iscsi_allocate_pdu_size(struct iscsi_context *iscsi, enum iscsi_opcode opcode, + enum iscsi_opcode response_opcode, size_t payload_size) +{ + return iscsi_allocate_pdu_with_itt_flags_size(iscsi, opcode, response_opcode, iscsi->itt++, 0, payload_size); +} + void @@ -120,18 +137,20 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data, aligned = (aligned+3)&0xfffffffc; } - int new_alloc_size=data->alloc_size; - if (new_alloc_size < PAGE_SIZE) new_alloc_size=PAGE_SIZE; + int new_alloc_size = data->alloc_size; + if (new_alloc_size < 64) new_alloc_size=64; while (aligned > new_alloc_size) new_alloc_size<<=1; if (data->data != NULL && data->alloc_size == 0) data->alloc_size=data->size; - if (data->alloc_size == 0) + if (data->alloc_size == 0) { data->data = iscsi_malloc(iscsi, new_alloc_size); + } else - if (data->alloc_size != new_alloc_size) + if (data->alloc_size != new_alloc_size) { data->data = realloc(data->data, new_alloc_size); + } if (data->data == NULL) { iscsi_set_error(iscsi, "failed to allocate buffer for %d " diff --git a/lib/scsi-command.c b/lib/scsi-command.c index f3f4cef..57c50d3 100644 --- a/lib/scsi-command.c +++ b/lib/scsi-command.c @@ -85,10 +85,11 @@ iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu, len = iscsi->target_max_recv_data_segment_length; } - pdu = iscsi_allocate_pdu_with_itt_flags(iscsi, ISCSI_PDU_DATA_OUT, + pdu = iscsi_allocate_pdu_with_itt_flags_size(iscsi, ISCSI_PDU_DATA_OUT, ISCSI_PDU_NO_PDU, cmd_pdu->itt, - ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK); + ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK, + len); if (pdu == NULL) { iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate " "scsi data out pdu."); @@ -198,8 +199,16 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun, scsi_set_task_private_ptr(task, scsi_cbdata); - pdu = iscsi_allocate_pdu(iscsi, ISCSI_PDU_SCSI_REQUEST, - ISCSI_PDU_SCSI_RESPONSE); + u_int32_t payload_size = 0; + if (iscsi->use_immediate_data == ISCSI_IMMEDIATE_DATA_YES) { + payload_size=data.size; + if (payload_size > iscsi->first_burst_length) { + payload_size = iscsi->first_burst_length; + } + } + + pdu = iscsi_allocate_pdu_size(iscsi, ISCSI_PDU_SCSI_REQUEST, + ISCSI_PDU_SCSI_RESPONSE, payload_size); if (pdu == NULL) { iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate " "scsi pdu.");