From 4e129d385c27e7b26172ed1f93c688eabca11654 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Tue, 17 Jun 2014 10:56:18 +0200 Subject: [PATCH] pdu: fix statsn and factor out sn comparision Signed-off-by: Peter Lieven --- include/iscsi-private.h | 8 ++++---- lib/iscsi-command.c | 45 ++++++++--------------------------------- lib/login.c | 25 ++++------------------- lib/pdu.c | 31 +++++++++++++++++++++++----- lib/task_mgmt.c | 11 ++-------- 5 files changed, 44 insertions(+), 76 deletions(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index c74390c..e69fdce 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -349,11 +349,11 @@ iscsi_log_message(struct iscsi_context *iscsi, int level, const char *format, .. void iscsi_add_to_outqueue(struct iscsi_context *iscsi, struct iscsi_pdu *pdu); -int -iscsi_serial32_compare(uint32_t s1, uint32_t s2); +int iscsi_serial32_compare(uint32_t s1, uint32_t s2); +void iscsi_adjust_statsn(struct iscsi_context *iscsi, struct iscsi_in_pdu *in); +void iscsi_adjust_maxexpcmdsn(struct iscsi_context *iscsi, struct iscsi_in_pdu *in); -uint32_t -iscsi_itt_post_increment(struct iscsi_context *iscsi); +uint32_t iscsi_itt_post_increment(struct iscsi_context *iscsi); void iscsi_timeout_scan(struct iscsi_context *iscsi); diff --git a/lib/iscsi-command.c b/lib/iscsi-command.c index e4f6e8e..6a7bec7 100644 --- a/lib/iscsi-command.c +++ b/lib/iscsi-command.c @@ -347,23 +347,12 @@ int iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in) { - uint32_t statsn, maxcmdsn, expcmdsn, flags, status; + uint32_t flags, status; struct iscsi_scsi_cbdata *scsi_cbdata = &pdu->scsi_cbdata; struct scsi_task *task = scsi_cbdata->task; - statsn = scsi_get_uint32(&in->hdr[24]); - if (statsn > iscsi->statsn) { - iscsi->statsn = statsn; - } - - maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (iscsi_serial32_compare(maxcmdsn, iscsi->maxcmdsn) > 0) { - iscsi->maxcmdsn = maxcmdsn; - } - expcmdsn = scsi_get_uint32(&in->hdr[28]); - if (iscsi_serial32_compare(expcmdsn, iscsi->expcmdsn) > 0) { - iscsi->expcmdsn = expcmdsn; - } + iscsi_adjust_statsn(iscsi, in); + iscsi_adjust_maxexpcmdsn(iscsi, in); flags = in->hdr[1]; if ((flags&ISCSI_PDU_DATA_FINAL) == 0) { @@ -489,24 +478,13 @@ int iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in, int *is_finished) { - uint32_t statsn, maxcmdsn, expcmdsn, flags, status; + uint32_t flags, status; struct iscsi_scsi_cbdata *scsi_cbdata = &pdu->scsi_cbdata; struct scsi_task *task = scsi_cbdata->task; int dsl; - statsn = scsi_get_uint32(&in->hdr[24]); - if (statsn > iscsi->statsn) { - iscsi->statsn = statsn; - } - - maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (iscsi_serial32_compare(maxcmdsn, iscsi->maxcmdsn) > 0) { - iscsi->maxcmdsn = maxcmdsn; - } - expcmdsn = scsi_get_uint32(&in->hdr[28]); - if (iscsi_serial32_compare(expcmdsn, iscsi->expcmdsn) > 0) { - iscsi->expcmdsn = expcmdsn; - } + iscsi_adjust_statsn(iscsi, in); + iscsi_adjust_maxexpcmdsn(iscsi, in); flags = in->hdr[1]; if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) { @@ -579,20 +557,13 @@ int iscsi_process_r2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in) { - uint32_t ttt, offset, len, maxcmdsn, expcmdsn; + uint32_t ttt, offset, len; ttt = scsi_get_uint32(&in->hdr[20]); offset = scsi_get_uint32(&in->hdr[40]); len = scsi_get_uint32(&in->hdr[44]); - maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (iscsi_serial32_compare(maxcmdsn, iscsi->maxcmdsn) > 0) { - iscsi->maxcmdsn = maxcmdsn; - } - expcmdsn = scsi_get_uint32(&in->hdr[28]); - if (iscsi_serial32_compare(expcmdsn, iscsi->expcmdsn) > 0) { - iscsi->expcmdsn = expcmdsn; - } + iscsi_adjust_maxexpcmdsn(iscsi, in); pdu->datasn = 0; iscsi_send_data_out(iscsi, pdu, ttt, offset, len); diff --git a/lib/login.c b/lib/login.c index 493b2bc..59c55d2 100644 --- a/lib/login.c +++ b/lib/login.c @@ -965,22 +965,14 @@ int iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in) { - uint32_t status, maxcmdsn, expcmdsn; + uint32_t status; char *ptr = (char *)in->data; int size = in->data_pos; status = scsi_get_uint16(&in->hdr[36]); - iscsi->statsn = scsi_get_uint16(&in->hdr[24]); - - maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (iscsi_serial32_compare(maxcmdsn, iscsi->maxcmdsn) > 0) { - iscsi->maxcmdsn = maxcmdsn; - } - expcmdsn = scsi_get_uint32(&in->hdr[28]); - if (iscsi_serial32_compare(expcmdsn, iscsi->expcmdsn) > 0) { - iscsi->expcmdsn = expcmdsn; - } + iscsi_adjust_statsn(iscsi, in); + iscsi_adjust_maxexpcmdsn(iscsi, in); /* XXX here we should parse the data returned in case the target * renegotiated some some parameters. @@ -1176,16 +1168,7 @@ int iscsi_process_logout_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in) { - uint32_t maxcmdsn, expcmdsn; - - maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (iscsi_serial32_compare(maxcmdsn, iscsi->maxcmdsn) > 0) { - iscsi->maxcmdsn = maxcmdsn; - } - expcmdsn = scsi_get_uint32(&in->hdr[28]); - if (iscsi_serial32_compare(expcmdsn, iscsi->expcmdsn) > 0) { - iscsi->expcmdsn = expcmdsn; - } + iscsi_adjust_maxexpcmdsn(iscsi, in); iscsi->is_loggedin = 0; pdu->callback(iscsi, SCSI_STATUS_GOOD, NULL, pdu->private_data); diff --git a/lib/pdu.c b/lib/pdu.c index 72a6e3f..292e6e5 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -69,6 +69,31 @@ iscsi_itt_post_increment(struct iscsi_context *iscsi) { return old_itt; } +void iscsi_adjust_statsn(struct iscsi_context *iscsi, struct iscsi_in_pdu *in) { + uint32_t statsn = scsi_get_uint32(&in->hdr[24]); + uint32_t itt = scsi_get_uint32(&in->hdr[16]); + + if (itt == 0xffffffff) { + /* target will not increase statsn if itt == 0xffffffff */ + statsn--; + } + + if (iscsi_serial32_compare(statsn, iscsi->statsn) > 0) { + iscsi->statsn = statsn; + } +} + +void iscsi_adjust_maxexpcmdsn(struct iscsi_context *iscsi, struct iscsi_in_pdu *in) { + uint32_t maxcmdsn = scsi_get_uint32(&in->hdr[32]); + if (iscsi_serial32_compare(maxcmdsn, iscsi->maxcmdsn) > 0) { + iscsi->maxcmdsn = maxcmdsn; + } + uint32_t expcmdsn = scsi_get_uint32(&in->hdr[28]); + if (iscsi_serial32_compare(expcmdsn, iscsi->expcmdsn) > 0) { + iscsi->expcmdsn = expcmdsn; + } +} + void iscsi_dump_pdu_header(struct iscsi_context *iscsi, unsigned char *data) { char dump[ISCSI_RAW_HEADER_SIZE*3+1]={0}; int i; @@ -297,14 +322,10 @@ int iscsi_process_target_nop_in(struct iscsi_context *iscsi, struct iscsi_in_pdu *in) { uint32_t ttt; - uint32_t statsn; ttt = scsi_get_uint32(&in->hdr[20]); - statsn = scsi_get_uint32(&in->hdr[24]); - if (statsn > iscsi->statsn) { - iscsi->statsn = statsn; - } + iscsi_adjust_statsn(iscsi, in); /* if the server does not want a response */ if (ttt == 0xffffffff) { diff --git a/lib/task_mgmt.c b/lib/task_mgmt.c index 68889a4..7a3d749 100644 --- a/lib/task_mgmt.c +++ b/lib/task_mgmt.c @@ -92,18 +92,11 @@ int iscsi_process_task_mgmt_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in) { - uint32_t response, maxcmdsn, expcmdsn; + uint32_t response; response = in->hdr[2]; - maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (iscsi_serial32_compare(maxcmdsn, iscsi->maxcmdsn) > 0) { - iscsi->maxcmdsn = maxcmdsn; - } - expcmdsn = scsi_get_uint32(&in->hdr[28]); - if (iscsi_serial32_compare(expcmdsn, iscsi->expcmdsn) > 0) { - iscsi->expcmdsn = expcmdsn; - } + iscsi_adjust_maxexpcmdsn(iscsi, in); pdu->callback(iscsi, SCSI_STATUS_GOOD, &response, pdu->private_data);