From e4c4799f29252be07ba922fdb273241d542e1368 Mon Sep 17 00:00:00 2001 From: Anatoliy Glagolev Date: Tue, 19 Sep 2023 18:40:13 -0600 Subject: [PATCH] checking if task is in outqueue Users need to check if a task is queued to send (not sent yet) before invoking functions such as iscsi_task_mgmt_abort_task_async. Otherwise, because task management requests are automatically treated as "immediate", a request to abort a task is sent before the task itself. if (iscsi_scsi_is_task_in_outqueue(iscsi_, task_)) { iscsi_scsi_cancel_task(iscsi_, task_); } else { iscsi_task_mgmt_abort_task_async(iscsi_, task_, AbortCb, context_); } --- include/iscsi.h | 7 +++++++ lib/iscsi-command.c | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/include/iscsi.h b/include/iscsi.h index c9f097d..8196f64 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -1537,6 +1537,13 @@ EXTERN void scsi_task_set_iov_in(struct scsi_task *task, struct scsi_iovec *iov, EXTERN int scsi_task_get_status(struct scsi_task *task, struct scsi_sense *sense); +/* + * This function returns 1 if the task is queued for send (for example, the task has been created + * with an asynchronous request and has not been put on the wire right away due to the socket + * or the ISCSI session state); otherwise returns 0. + */ +EXTERN int iscsi_scsi_is_task_in_outqueue(struct iscsi_context *iscsi, struct scsi_task *task); + /* * This function is used when you want to cancel a scsi task. * The callback for the task will immediately be invoked with SCSI_STATUS_CANCELLED. diff --git a/lib/iscsi-command.c b/lib/iscsi-command.c index 9a240ab..d218060 100644 --- a/lib/iscsi-command.c +++ b/lib/iscsi-command.c @@ -2675,6 +2675,19 @@ iscsi_scsi_get_task_from_pdu(struct iscsi_pdu *pdu) return pdu->scsi_cbdata.task; } +int iscsi_scsi_is_task_in_outqueue(struct iscsi_context *iscsi, struct scsi_task *task) +{ + struct iscsi_pdu *pdu; + + for (pdu = iscsi->outqueue; pdu; pdu = pdu->next) { + if (pdu->itt == task->itt) { + return 1; + } + } + + return 0; +} + int iscsi_scsi_cancel_task(struct iscsi_context *iscsi, struct scsi_task *task)