diff --git a/lib/nvme/nvme.c b/lib/nvme/nvme.c index 83cca14bf..dc0da06f6 100644 --- a/lib/nvme/nvme.c +++ b/lib/nvme/nvme.c @@ -103,7 +103,9 @@ nvme_completion_poll_cb(void *arg, const struct spdk_nvme_cpl *cpl) * \param status completion status * \param robust_mutex optional robust mutex to lock while polling qpair * - * \return 0 if command completed without error, negative errno on failure + * \return 0 if command completed without error, + * -EIO if command completed with error, + * -ECANCELED if command is not completed due to transport/device error * * The command to wait upon must be submitted with nvme_completion_poll_cb as the callback * and status as the callback argument. @@ -116,21 +118,24 @@ spdk_nvme_wait_for_completion_robust_lock( { memset(&status->cpl, 0, sizeof(status->cpl)); status->done = false; + int rc; while (status->done == false) { if (robust_mutex) { nvme_robust_mutex_lock(robust_mutex); } - if (spdk_nvme_qpair_process_completions(qpair, 0) < 0) { - status->done = true; - status->cpl.status.sct = SPDK_NVME_SCT_GENERIC; - status->cpl.status.sc = SPDK_NVME_SC_ABORTED_SQ_DELETION; - } + rc = spdk_nvme_qpair_process_completions(qpair, 0); if (robust_mutex) { nvme_robust_mutex_unlock(robust_mutex); } + + if (rc < 0) { + status->cpl.status.sct = SPDK_NVME_SCT_GENERIC; + status->cpl.status.sc = SPDK_NVME_SC_ABORTED_SQ_DELETION; + return -ECANCELED; + } } return spdk_nvme_cpl_is_error(&status->cpl) ? -EIO : 0; diff --git a/test/unit/lib/nvme/nvme.c/nvme_ut.c b/test/unit/lib/nvme/nvme.c/nvme_ut.c index b95beb34c..1fc2575a8 100644 --- a/test/unit/lib/nvme/nvme.c/nvme_ut.c +++ b/test/unit/lib/nvme/nvme.c/nvme_ut.c @@ -1257,6 +1257,22 @@ test_nvme_wait_for_completion(void) rc = spdk_nvme_wait_for_completion_timeout(&qpair, &g_status, timeout_in_secs); CU_ASSERT(g_status.done == true); CU_ASSERT(rc == 0); + + /* spdk_nvme_wait_for_completion */ + /* spdk_nvme_qpair_process_completions returns error */ + g_process_comp_result = -1; + rc = spdk_nvme_wait_for_completion(&qpair, &g_status); + CU_ASSERT(rc == -ECANCELED); + CU_ASSERT(g_status.done == false); + CU_ASSERT(g_status.cpl.status.sct == SPDK_NVME_SCT_GENERIC); + CU_ASSERT(g_status.cpl.status.sc == SPDK_NVME_SC_ABORTED_SQ_DELETION); + + g_process_comp_result = 0; + + /* successful completion */ + rc = spdk_nvme_wait_for_completion(&qpair, &g_status); + CU_ASSERT(rc == 0); + CU_ASSERT(g_status.done == true); } static void