diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 0fdd237..2e87c43 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -74,6 +74,7 @@ struct iscsi_context { unsigned char isid[6]; uint32_t itt; uint32_t cmdsn; + uint32_t maxcmdsn; uint32_t statsn; enum iscsi_header_digest want_header_digest; enum iscsi_header_digest header_digest; diff --git a/lib/login.c b/lib/login.c index fb3a5b9..b685743 100644 --- a/lib/login.c +++ b/lib/login.c @@ -970,7 +970,7 @@ int iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in) { - int status; + uint32_t status, maxcmdsn; char *ptr = (char *)in->data; int size = in->data_pos; @@ -978,6 +978,11 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, iscsi->statsn = ntohs(*(uint16_t *)&in->hdr[24]); + maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); + if (maxcmdsn > iscsi->maxcmdsn) { + iscsi->maxcmdsn = maxcmdsn; + } + /* XXX here we should parse the data returned in case the target * renegotiated some some parameters. * we should also do proper handshaking if the target is not yet @@ -1161,8 +1166,15 @@ iscsi_logout_async(struct iscsi_context *iscsi, iscsi_command_cb cb, int iscsi_process_logout_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, -struct iscsi_in_pdu *in _U_) +struct iscsi_in_pdu *in) { + uint32_t maxcmdsn; + + maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); + if (maxcmdsn > iscsi->maxcmdsn) { + iscsi->maxcmdsn = maxcmdsn; + } + iscsi->is_loggedin = 0; pdu->callback(iscsi, SCSI_STATUS_GOOD, NULL, pdu->private_data); diff --git a/lib/scsi-command.c b/lib/scsi-command.c index a96582e..1996ec6 100644 --- a/lib/scsi-command.c +++ b/lib/scsi-command.c @@ -324,15 +324,20 @@ int iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in) { - int statsn, flags, status; + uint32_t statsn, maxcmdsn, flags, status; struct iscsi_scsi_cbdata *scsi_cbdata = pdu->scsi_cbdata; struct scsi_task *task = scsi_cbdata->task; statsn = ntohl(*(uint32_t *)&in->hdr[24]); - if (statsn > (int)iscsi->statsn) { + if (statsn > iscsi->statsn) { iscsi->statsn = statsn; } + maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); + if (maxcmdsn > iscsi->maxcmdsn) { + iscsi->maxcmdsn = maxcmdsn; + } + flags = in->hdr[1]; if ((flags&ISCSI_PDU_DATA_FINAL) == 0) { iscsi_set_error(iscsi, "scsi response pdu but Final bit is " @@ -419,16 +424,21 @@ int iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in, int *is_finished) { - int statsn, flags, status; + uint32_t statsn, maxcmdsn, flags, status; struct iscsi_scsi_cbdata *scsi_cbdata = pdu->scsi_cbdata; struct scsi_task *task = scsi_cbdata->task; int dsl; statsn = ntohl(*(uint32_t *)&in->hdr[24]); - if (statsn > (int)iscsi->statsn) { + if (statsn > iscsi->statsn) { iscsi->statsn = statsn; } + maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); + if (maxcmdsn > iscsi->maxcmdsn) { + iscsi->maxcmdsn = maxcmdsn; + } + flags = in->hdr[1]; if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) { iscsi_set_error(iscsi, "scsi response asked for ACK " @@ -497,12 +507,17 @@ int iscsi_process_r2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in) { - uint32_t ttt, offset, len; + uint32_t ttt, offset, len, maxcmdsn; ttt = ntohl(*(uint32_t *)&in->hdr[20]); offset = ntohl(*(uint32_t *)&in->hdr[40]); len = ntohl(*(uint32_t *)&in->hdr[44]); + maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); + if (maxcmdsn > iscsi->maxcmdsn) { + iscsi->maxcmdsn = maxcmdsn; + } + pdu->datasn = 0; iscsi_send_data_out(iscsi, pdu, ttt, offset, len); return 0; diff --git a/lib/task_mgmt.c b/lib/task_mgmt.c index 513a8d4..286072d 100644 --- a/lib/task_mgmt.c +++ b/lib/task_mgmt.c @@ -21,6 +21,7 @@ #endif #include +#include #include "iscsi.h" #include "iscsi-private.h" #include "scsi-lowlevel.h" @@ -82,10 +83,15 @@ int iscsi_process_task_mgmt_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in) { - uint32_t response; + uint32_t response, maxcmdsn; response = in->hdr[2]; + maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); + if (maxcmdsn > iscsi->maxcmdsn) { + iscsi->maxcmdsn = maxcmdsn; + } + pdu->callback(iscsi, SCSI_STATUS_GOOD, &response, pdu->private_data); return 0;