Merge pull request #231 from plieven/read_batch_pdu2
Batch pdu read in function iscsi_read_from_socket()
This commit is contained in:
@@ -61,7 +61,6 @@ struct iscsi_in_pdu {
|
|||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
};
|
};
|
||||||
void iscsi_free_iscsi_in_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in);
|
void iscsi_free_iscsi_in_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in);
|
||||||
void iscsi_free_iscsi_inqueue(struct iscsi_context *iscsi, struct iscsi_in_pdu *inqueue);
|
|
||||||
|
|
||||||
/* size of chap response field */
|
/* size of chap response field */
|
||||||
#define CHAP_R_SIZE 16
|
#define CHAP_R_SIZE 16
|
||||||
@@ -119,6 +118,7 @@ struct iscsi_context {
|
|||||||
int tcp_keepintvl;
|
int tcp_keepintvl;
|
||||||
int tcp_keepidle;
|
int tcp_keepidle;
|
||||||
int tcp_syncnt;
|
int tcp_syncnt;
|
||||||
|
int tcp_nonblocking;
|
||||||
|
|
||||||
int current_phase;
|
int current_phase;
|
||||||
int next_phase;
|
int next_phase;
|
||||||
@@ -142,7 +142,6 @@ struct iscsi_context {
|
|||||||
struct iscsi_pdu *waitpdu;
|
struct iscsi_pdu *waitpdu;
|
||||||
|
|
||||||
struct iscsi_in_pdu *incoming;
|
struct iscsi_in_pdu *incoming;
|
||||||
struct iscsi_in_pdu *inqueue;
|
|
||||||
|
|
||||||
uint32_t max_burst_length;
|
uint32_t max_burst_length;
|
||||||
uint32_t first_burst_length;
|
uint32_t first_burst_length;
|
||||||
|
|||||||
@@ -370,9 +370,6 @@ void iscsi_reconnect_cb(struct iscsi_context *iscsi _U_, int status,
|
|||||||
if (old_iscsi->incoming != NULL) {
|
if (old_iscsi->incoming != NULL) {
|
||||||
iscsi_free_iscsi_in_pdu(old_iscsi, old_iscsi->incoming);
|
iscsi_free_iscsi_in_pdu(old_iscsi, old_iscsi->incoming);
|
||||||
}
|
}
|
||||||
if (old_iscsi->inqueue != NULL) {
|
|
||||||
iscsi_free_iscsi_inqueue(old_iscsi, old_iscsi->inqueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (old_iscsi->outqueue_current != NULL && old_iscsi->outqueue_current->flags & ISCSI_PDU_DELETE_WHEN_SENT) {
|
if (old_iscsi->outqueue_current != NULL && old_iscsi->outqueue_current->flags & ISCSI_PDU_DELETE_WHEN_SENT) {
|
||||||
iscsi->drv->free_pdu(old_iscsi, old_iscsi->outqueue_current);
|
iscsi->drv->free_pdu(old_iscsi, old_iscsi->outqueue_current);
|
||||||
|
|||||||
@@ -378,9 +378,6 @@ iscsi_destroy_context(struct iscsi_context *iscsi)
|
|||||||
if (iscsi->incoming != NULL) {
|
if (iscsi->incoming != NULL) {
|
||||||
iscsi_free_iscsi_in_pdu(iscsi, iscsi->incoming);
|
iscsi_free_iscsi_in_pdu(iscsi, iscsi->incoming);
|
||||||
}
|
}
|
||||||
if (iscsi->inqueue != NULL) {
|
|
||||||
iscsi_free_iscsi_inqueue(iscsi, iscsi->inqueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
iscsi->connect_data = NULL;
|
iscsi->connect_data = NULL;
|
||||||
|
|
||||||
|
|||||||
188
lib/socket.c
188
lib/socket.c
@@ -126,15 +126,15 @@ void iscsi_decrement_iface_rr() {
|
|||||||
iface_rr--;
|
iface_rr--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_nonblocking(int fd)
|
static int set_nonblocking(int fd)
|
||||||
{
|
{
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
unsigned long opt = 1;
|
unsigned long opt = 1;
|
||||||
ioctlsocket(fd, FIONBIO, &opt);
|
return ioctlsocket(fd, FIONBIO, &opt);
|
||||||
#else
|
#else
|
||||||
unsigned v;
|
unsigned v;
|
||||||
v = fcntl(fd, F_GETFL, 0);
|
v = fcntl(fd, F_GETFL, 0);
|
||||||
fcntl(fd, F_SETFL, v | O_NONBLOCK);
|
return fcntl(fd, F_SETFL, v | O_NONBLOCK);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ static int iscsi_tcp_connect(struct iscsi_context *iscsi, union socket_address *
|
|||||||
iscsi->fd = iscsi->old_iscsi->fd;
|
iscsi->fd = iscsi->old_iscsi->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_nonblocking(iscsi->fd);
|
iscsi->tcp_nonblocking = !set_nonblocking(iscsi->fd);
|
||||||
|
|
||||||
iscsi_set_tcp_keepalive(iscsi, iscsi->tcp_keepidle, iscsi->tcp_keepcnt, iscsi->tcp_keepintvl);
|
iscsi_set_tcp_keepalive(iscsi, iscsi->tcp_keepidle, iscsi->tcp_keepcnt, iscsi->tcp_keepintvl);
|
||||||
|
|
||||||
@@ -569,109 +569,103 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
|||||||
struct iscsi_in_pdu *in;
|
struct iscsi_in_pdu *in;
|
||||||
ssize_t data_size, count, padding_size;
|
ssize_t data_size, count, padding_size;
|
||||||
|
|
||||||
if (iscsi->incoming == NULL) {
|
do {
|
||||||
iscsi->incoming = iscsi_szmalloc(iscsi, sizeof(struct iscsi_in_pdu));
|
|
||||||
iscsi->incoming->hdr = iscsi_smalloc(iscsi, ISCSI_HEADER_SIZE);
|
|
||||||
if (iscsi->incoming == NULL) {
|
if (iscsi->incoming == NULL) {
|
||||||
iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu");
|
iscsi->incoming = iscsi_szmalloc(iscsi, sizeof(struct iscsi_in_pdu));
|
||||||
return -1;
|
iscsi->incoming->hdr = iscsi_szmalloc(iscsi, ISCSI_RAW_HEADER_SIZE + ISCSI_DIGEST_SIZE);
|
||||||
}
|
if (iscsi->incoming == NULL) {
|
||||||
}
|
iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu");
|
||||||
in = iscsi->incoming;
|
return -1;
|
||||||
|
|
||||||
/* first we must read the header, including any digests */
|
|
||||||
if (in->hdr_pos < ISCSI_HEADER_SIZE) {
|
|
||||||
/* try to only read the header, the socket is nonblocking, so
|
|
||||||
* no need to limit the read to what is available in the socket
|
|
||||||
*/
|
|
||||||
count = ISCSI_HEADER_SIZE - in->hdr_pos;
|
|
||||||
count = recv(iscsi->fd, &in->hdr[in->hdr_pos], count, 0);
|
|
||||||
if (count == 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (count < 0) {
|
|
||||||
if (errno == EINTR || errno == EAGAIN) {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
iscsi_set_error(iscsi, "read from socket failed, "
|
|
||||||
"errno:%d", errno);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
in->hdr_pos += count;
|
in = iscsi->incoming;
|
||||||
}
|
|
||||||
|
|
||||||
if (in->hdr_pos < ISCSI_HEADER_SIZE) {
|
/* first we must read the header, including any digests */
|
||||||
/* we don't have the full header yet, so return */
|
if (in->hdr_pos < ISCSI_HEADER_SIZE) {
|
||||||
return 0;
|
/* try to only read the header, the socket is nonblocking, so
|
||||||
}
|
* no need to limit the read to what is available in the socket
|
||||||
|
*/
|
||||||
padding_size = iscsi_get_pdu_padding_size(&in->hdr[0]);
|
count = ISCSI_HEADER_SIZE - in->hdr_pos;
|
||||||
data_size = iscsi_get_pdu_data_size(&in->hdr[0]) + padding_size;
|
count = recv(iscsi->fd, &in->hdr[in->hdr_pos], count, 0);
|
||||||
|
if (count == 0) {
|
||||||
if (data_size < 0 || data_size > (ssize_t)iscsi->initiator_max_recv_data_segment_length) {
|
/* remote side has closed the socket. */
|
||||||
iscsi_set_error(iscsi, "Invalid data size received from target (%d)", (int)data_size);
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
if (count < 0) {
|
||||||
if (data_size != 0) {
|
if (errno == EINTR || errno == EAGAIN) {
|
||||||
unsigned char padding_buf[3];
|
break;
|
||||||
unsigned char *buf = padding_buf;
|
|
||||||
struct scsi_iovector * iovector_in;
|
|
||||||
|
|
||||||
count = data_size - in->data_pos;
|
|
||||||
|
|
||||||
/* first try to see if we already have a user buffer */
|
|
||||||
iovector_in = iscsi_get_scsi_task_iovector_in(iscsi, in);
|
|
||||||
if (iovector_in != NULL && count > padding_size) {
|
|
||||||
uint32_t offset = scsi_get_uint32(&in->hdr[40]);
|
|
||||||
count = iscsi_iovector_readv_writev(iscsi, iovector_in, in->data_pos + offset, count - padding_size, 0);
|
|
||||||
} else {
|
|
||||||
if (iovector_in == NULL) {
|
|
||||||
if (in->data == NULL) {
|
|
||||||
in->data = iscsi_malloc(iscsi, data_size);
|
|
||||||
if (in->data == NULL) {
|
|
||||||
iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu->data(%d)", (int)data_size);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
buf = &in->data[in->data_pos];
|
iscsi_set_error(iscsi, "read from socket failed, "
|
||||||
|
"errno:%d", errno);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
count = recv(iscsi->fd, buf, count, 0);
|
in->hdr_pos += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == 0) {
|
if (in->hdr_pos < ISCSI_HEADER_SIZE) {
|
||||||
|
/* we don't have the full header yet, so return */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
padding_size = iscsi_get_pdu_padding_size(&in->hdr[0]);
|
||||||
|
data_size = iscsi_get_pdu_data_size(&in->hdr[0]) + padding_size;
|
||||||
|
|
||||||
|
if (data_size < 0 || data_size > (ssize_t)iscsi->initiator_max_recv_data_segment_length) {
|
||||||
|
iscsi_set_error(iscsi, "Invalid data size received from target (%d)", (int)data_size);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (count < 0) {
|
if (data_size != 0) {
|
||||||
if (errno == EINTR || errno == EAGAIN) {
|
unsigned char padding_buf[3];
|
||||||
return 0;
|
unsigned char *buf = padding_buf;
|
||||||
|
struct scsi_iovector * iovector_in;
|
||||||
|
|
||||||
|
count = data_size - in->data_pos;
|
||||||
|
|
||||||
|
/* first try to see if we already have a user buffer */
|
||||||
|
iovector_in = iscsi_get_scsi_task_iovector_in(iscsi, in);
|
||||||
|
if (iovector_in != NULL && count > padding_size) {
|
||||||
|
uint32_t offset = scsi_get_uint32(&in->hdr[40]);
|
||||||
|
count = iscsi_iovector_readv_writev(iscsi, iovector_in, in->data_pos + offset, count - padding_size, 0);
|
||||||
|
} else {
|
||||||
|
if (iovector_in == NULL) {
|
||||||
|
if (in->data == NULL) {
|
||||||
|
in->data = iscsi_malloc(iscsi, data_size);
|
||||||
|
if (in->data == NULL) {
|
||||||
|
iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu->data(%d)", (int)data_size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf = &in->data[in->data_pos];
|
||||||
|
}
|
||||||
|
count = recv(iscsi->fd, buf, count, 0);
|
||||||
}
|
}
|
||||||
iscsi_set_error(iscsi, "read from socket failed, "
|
if (count == 0) {
|
||||||
"errno:%d %s", errno,
|
/* remote side has closed the socket. */
|
||||||
iscsi_get_error(iscsi));
|
return -1;
|
||||||
return -1;
|
}
|
||||||
|
if (count < 0) {
|
||||||
|
if (errno == EINTR || errno == EAGAIN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iscsi_set_error(iscsi, "read from socket failed, "
|
||||||
|
"errno:%d %s", errno,
|
||||||
|
iscsi_get_error(iscsi));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
in->data_pos += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
in->data_pos += count;
|
if (in->data_pos < data_size) {
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (in->data_pos < data_size) {
|
iscsi->incoming = NULL;
|
||||||
return 0;
|
if (iscsi_process_pdu(iscsi, in) != 0) {
|
||||||
}
|
iscsi_free_iscsi_in_pdu(iscsi, in);
|
||||||
|
|
||||||
ISCSI_LIST_ADD_END(&iscsi->inqueue, in);
|
|
||||||
iscsi->incoming = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
while (iscsi->inqueue != NULL) {
|
|
||||||
struct iscsi_in_pdu *current = iscsi->inqueue;
|
|
||||||
|
|
||||||
if (iscsi_process_pdu(iscsi, current) != 0) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ISCSI_LIST_REMOVE(&iscsi->inqueue, current);
|
iscsi_free_iscsi_in_pdu(iscsi, in);
|
||||||
iscsi_free_iscsi_in_pdu(iscsi, current);
|
} while (iscsi->tcp_nonblocking && iscsi->waitpdu && iscsi->is_loggedin);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -995,16 +989,6 @@ iscsi_free_iscsi_in_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in)
|
|||||||
in=NULL;
|
in=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
iscsi_free_iscsi_inqueue(struct iscsi_context *iscsi, struct iscsi_in_pdu *inqueue)
|
|
||||||
{
|
|
||||||
while (inqueue != NULL) {
|
|
||||||
struct iscsi_in_pdu *next = inqueue->next;
|
|
||||||
iscsi_free_iscsi_in_pdu(iscsi, inqueue);
|
|
||||||
inqueue = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void iscsi_set_tcp_syncnt(struct iscsi_context *iscsi, int value)
|
void iscsi_set_tcp_syncnt(struct iscsi_context *iscsi, int value)
|
||||||
{
|
{
|
||||||
iscsi->tcp_syncnt=value;
|
iscsi->tcp_syncnt=value;
|
||||||
|
|||||||
Reference in New Issue
Block a user