diff --git a/include/iscsi.h b/include/iscsi.h index af7e1ba..9753d22 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -33,6 +33,7 @@ struct iscsi_context; struct sockaddr; #define MAX_STRING_SIZE (255) +#define PAGE_SIZE (4096) /* * Syntax for normal and portal/discovery URLs. @@ -533,6 +534,7 @@ iscsi_task_mgmt_target_cold_reset_async(struct iscsi_context *iscsi, struct iscsi_data { int size; + int alloc_size; unsigned char *data; }; diff --git a/lib/pdu.c b/lib/pdu.c index 7109511..86dc2b1 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -107,7 +107,6 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data, unsigned char *dptr, int dsize, int pdualignment) { int len, aligned; - unsigned char *buf; if (dsize == 0) { iscsi_set_error(iscsi, "Trying to append zero size data to " @@ -121,25 +120,33 @@ iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data, aligned = (aligned+3)&0xfffffffc; } - buf = iscsi_malloc(iscsi, aligned); - if (buf == NULL) { + int new_alloc_size=data->alloc_size; + if (new_alloc_size < PAGE_SIZE) new_alloc_size=PAGE_SIZE; + + 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) + data->data = iscsi_malloc(iscsi, new_alloc_size); + else + 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 " "bytes", len); return -1; } + + data->alloc_size = new_alloc_size; + memcpy(data->data + data->size, dptr, dsize); - if (data->size > 0) { - memcpy(buf, data->data, data->size); - } - memcpy(buf + data->size, dptr, dsize); if (len != aligned) { /* zero out any padding at the end */ - memset(buf+len, 0, aligned-len); + memset(data->data+len, 0, aligned-len); } - iscsi_free(iscsi, data->data); - - data->data = buf; data->size = len; return 0;