Merge pull request #254 from franciozzy/master
PDU cancellation fixes for sync connect calls
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
24
lib/init.c
24
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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
35
lib/pdu.c
35
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);
|
||||
}
|
||||
}
|
||||
|
||||
10
lib/sync.c
10
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user