diff --git a/include/iscsi-private.h b/include/iscsi-private.h index aedbbe0..218cf74 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -284,6 +284,7 @@ void iscsi_pdu_set_itt(struct iscsi_pdu *pdu, uint32_t itt); void iscsi_pdu_set_ritt(struct iscsi_pdu *pdu, uint32_t ritt); void iscsi_pdu_set_datasn(struct iscsi_pdu *pdu, uint32_t datasn); void iscsi_pdu_set_bufferoffset(struct iscsi_pdu *pdu, uint32_t bufferoffset); +void iscsi_cancel_pdus(struct iscsi_context *iscsi); int iscsi_pdu_add_data(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, unsigned char *dptr, int dsize); int iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu); diff --git a/lib/connect.c b/lib/connect.c index 4043f7c..d13cc62 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -270,34 +270,11 @@ void iscsi_set_reconnect_max_retries(struct iscsi_context *iscsi, int count) void iscsi_defer_reconnect(struct iscsi_context *iscsi) { - struct iscsi_pdu *pdu; - iscsi->reconnect_deferred = 1; ISCSI_LOG(iscsi, 2, "reconnect deferred, cancelling all tasks"); - while ((pdu = iscsi->outqueue)) { - ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu); - if (iscsi->is_loggedin && pdu->callback) { - /* If an error happened during connect/login, - we don't want to call any of the callbacks. - */ - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, - NULL, pdu->private_data); - } - iscsi->drv->free_pdu(iscsi, pdu); - } - while ((pdu = iscsi->waitpdu)) { - ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu); - if (iscsi->is_loggedin && pdu->callback) { - /* If an error happened during connect/login, - we don't want to call any of the callbacks. - */ - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, - NULL, pdu->private_data); - } - iscsi->drv->free_pdu(iscsi, pdu); - } + iscsi_cancel_pdus(iscsi); } void iscsi_reconnect_cb(struct iscsi_context *iscsi _U_, int status, diff --git a/lib/init.c b/lib/init.c index 34a95a5..0bcf1b7 100644 --- a/lib/init.c +++ b/lib/init.c @@ -338,7 +338,6 @@ iscsi_set_targetname(struct iscsi_context *iscsi, const char *target_name) int iscsi_destroy_context(struct iscsi_context *iscsi) { - struct iscsi_pdu *pdu; int i; if (iscsi == NULL) { @@ -349,28 +348,7 @@ iscsi_destroy_context(struct iscsi_context *iscsi) iscsi_disconnect(iscsi); } - while ((pdu = iscsi->outqueue)) { - ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu); - if (iscsi->is_loggedin && pdu->callback) { - /* If an error happened during connect/login, we don't want to - call any of the callbacks. - */ - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, - pdu->private_data); - } - iscsi->drv->free_pdu(iscsi, pdu); - } - while ((pdu = iscsi->waitpdu)) { - ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu); - if (iscsi->is_loggedin && pdu->callback) { - /* If an error happened during connect/login, we don't want to - call any of the callbacks. - */ - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, - pdu->private_data); - } - iscsi->drv->free_pdu(iscsi, pdu); - } + iscsi_cancel_pdus(iscsi); if (iscsi->outqueue_current != NULL && iscsi->outqueue_current->flags & ISCSI_PDU_DELETE_WHEN_SENT) { iscsi->drv->free_pdu(iscsi, iscsi->outqueue_current); diff --git a/lib/iscsi-command.c b/lib/iscsi-command.c index 5be7ee2..8b6859a 100644 --- a/lib/iscsi-command.c +++ b/lib/iscsi-command.c @@ -2697,22 +2697,5 @@ iscsi_scsi_cancel_task(struct iscsi_context *iscsi, void iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi) { - struct iscsi_pdu *pdu; - - while ((pdu = iscsi->waitpdu)) { - ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu); - if (pdu->callback) { - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, - pdu->private_data); - } - iscsi->drv->free_pdu(iscsi, pdu); - } - while ((pdu = iscsi->outqueue)) { - ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu); - if (pdu->callback) { - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL, - pdu->private_data); - } - iscsi->drv->free_pdu(iscsi, pdu); - } + iscsi_cancel_pdus(iscsi); } diff --git a/lib/pdu.c b/lib/pdu.c index 0bcbe11..441efa7 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -168,7 +168,6 @@ iscsi_tcp_free_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) iscsi_sfree(iscsi, pdu); } - int iscsi_add_data(struct iscsi_context *iscsi, struct iscsi_data *data, unsigned char *dptr, int dsize, int pdualignment) @@ -252,7 +251,6 @@ iscsi_get_pdu_data_size(const unsigned char *hdr) return size; } - int iscsi_get_pdu_padding_size(const unsigned char *hdr) { @@ -332,7 +330,6 @@ int iscsi_process_target_nop_in(struct iscsi_context *iscsi, return 0; } - static void iscsi_reconnect_after_logout(struct iscsi_context *iscsi, int status, void *command_data _U_, void *opaque _U_) { @@ -392,7 +389,6 @@ int iscsi_process_reject(struct iscsi_context *iscsi, return 0; } - static void iscsi_process_pdu_serials(struct iscsi_context *iscsi, struct iscsi_in_pdu *in) { uint32_t itt = scsi_get_uint32(&in->hdr[16]); @@ -770,5 +766,34 @@ iscsi_timeout_scan(struct iscsi_context *iscsi) int iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - return iscsi->drv->queue_pdu(iscsi, pdu); + return iscsi->drv->queue_pdu(iscsi, pdu); +} + +void +iscsi_cancel_pdus(struct iscsi_context *iscsi) +{ + struct iscsi_pdu *pdu; + + while ((pdu = iscsi->outqueue)) { + ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu); + if (iscsi->is_loggedin && pdu->callback) { + /* If an error happened during connect/login, + we don't want to call any of the callbacks. + */ + pdu->callback(iscsi, SCSI_STATUS_CANCELLED, + NULL, pdu->private_data); + } + iscsi->drv->free_pdu(iscsi, pdu); + } + while ((pdu = iscsi->waitpdu)) { + ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu); + if (iscsi->is_loggedin && pdu->callback) { + /* If an error happened during connect/login, + we don't want to call any of the callbacks. + */ + pdu->callback(iscsi, SCSI_STATUS_CANCELLED, + NULL, pdu->private_data); + } + iscsi->drv->free_pdu(iscsi, pdu); + } } diff --git a/lib/sync.c b/lib/sync.c index ce59c29..f8a139c 100644 --- a/lib/sync.c +++ b/lib/sync.c @@ -114,6 +114,11 @@ iscsi_connect_sync(struct iscsi_context *iscsi, const char *portal) /* clear connect_data so it doesnt point to our stack */ iscsi->connect_data = NULL; + /* in case of error, cancel any pending pdus */ + if (state.status != SCSI_STATUS_GOOD) { + iscsi_cancel_pdus(iscsi); + } + return (state.status == SCSI_STATUS_GOOD) ? 0 : -1; } @@ -135,6 +140,11 @@ iscsi_full_connect_sync(struct iscsi_context *iscsi, event_loop(iscsi, &state); + /* in case of error, cancel any pending pdus */ + if (state.status != SCSI_STATUS_GOOD) { + iscsi_cancel_pdus(iscsi); + } + return (state.status == SCSI_STATUS_GOOD) ? 0 : -1; }