diff --git a/include/spdk/bdev.h b/include/spdk/bdev.h index 6abd10f60..e1da49cea 100644 --- a/include/spdk/bdev.h +++ b/include/spdk/bdev.h @@ -351,4 +351,14 @@ int spdk_bdev_reset(struct spdk_bdev *bdev, enum spdk_bdev_reset_type, struct spdk_io_channel *spdk_bdev_get_io_channel(struct spdk_bdev *bdev, uint32_t priority); void spdk_bdev_io_set_scsi_error(struct spdk_bdev_io *bdev_io, enum spdk_scsi_status sc, enum spdk_scsi_sense sk, uint8_t asc, uint8_t ascq); + +/** + * Get the status of bdev_io as an NVMe status code. + * + * \param bdev_io I/O to get the status from. + * \param sct Status Code Type return value, as defined by the NVMe specification. + * \param sc Status Code return value, as defined by the NVMe specification. + */ +void spdk_bdev_io_get_nvme_status(const struct spdk_bdev_io *bdev_io, int *sct, int *sc); + #endif /* SPDK_BDEV_H_ */ diff --git a/include/spdk_internal/bdev.h b/include/spdk_internal/bdev.h index 2f8c83f9a..a168b8dee 100644 --- a/include/spdk_internal/bdev.h +++ b/include/spdk_internal/bdev.h @@ -159,6 +159,16 @@ struct spdk_bdev_io *spdk_bdev_get_child_io(struct spdk_bdev_io *parent, void *cb_arg); void spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status); + +/** + * Complete a bdev_io with an NVMe status code. + * + * \param bdev_io I/O to complete. + * \param sct NVMe Status Code Type. + * \param sc NVMe Status Code. + */ +void spdk_bdev_io_complete_nvme_status(struct spdk_bdev_io *bdev_io, int sct, int sc); + void spdk_bdev_module_list_add(struct spdk_bdev_module_if *bdev_module); void spdk_vbdev_module_list_add(struct spdk_bdev_module_if *vbdev_module); diff --git a/lib/bdev/bdev.c b/lib/bdev/bdev.c index 4307da7f7..1c15512a6 100644 --- a/lib/bdev/bdev.c +++ b/lib/bdev/bdev.c @@ -44,6 +44,7 @@ #include #include "spdk/queue.h" +#include "spdk/nvme_spec.h" #include "spdk_internal/bdev.h" #include "spdk_internal/event.h" @@ -865,6 +866,38 @@ spdk_bdev_io_set_scsi_error(struct spdk_bdev_io *bdev_io, enum spdk_scsi_status bdev_io->error.scsi.ascq = ascq; } +void +spdk_bdev_io_complete_nvme_status(struct spdk_bdev_io *bdev_io, int sct, int sc) +{ + if (sct == SPDK_NVME_SCT_GENERIC && sc == SPDK_NVME_SC_SUCCESS) { + bdev_io->status = SPDK_BDEV_IO_STATUS_SUCCESS; + } else { + bdev_io->error.nvme.sct = sct; + bdev_io->error.nvme.sc = sc; + bdev_io->status = SPDK_BDEV_IO_STATUS_NVME_ERROR; + } + + spdk_bdev_io_complete(bdev_io, bdev_io->status); +} + +void +spdk_bdev_io_get_nvme_status(const struct spdk_bdev_io *bdev_io, int *sct, int *sc) +{ + assert(sct != NULL); + assert(sc != NULL); + + if (bdev_io->status == SPDK_BDEV_IO_STATUS_NVME_ERROR) { + *sct = bdev_io->error.nvme.sct; + *sc = bdev_io->error.nvme.sc; + } else if (bdev_io->status == SPDK_BDEV_IO_STATUS_SUCCESS) { + *sct = SPDK_NVME_SCT_GENERIC; + *sc = SPDK_NVME_SC_SUCCESS; + } else { + *sct = SPDK_NVME_SCT_GENERIC; + *sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; + } +} + void spdk_bdev_register(struct spdk_bdev *bdev) { diff --git a/lib/bdev/nvme/blockdev_nvme.c b/lib/bdev/nvme/blockdev_nvme.c index b99a9033c..82e227c21 100644 --- a/lib/bdev/nvme/blockdev_nvme.c +++ b/lib/bdev/nvme/blockdev_nvme.c @@ -762,17 +762,8 @@ static void queued_done(void *ref, const struct spdk_nvme_cpl *cpl) { struct spdk_bdev_io *bdev_io = spdk_bdev_io_from_ctx((struct nvme_blockio *)ref); - enum spdk_bdev_io_status status; - if (spdk_nvme_cpl_is_error(cpl)) { - bdev_io->error.nvme.sct = cpl->status.sct; - bdev_io->error.nvme.sc = cpl->status.sc; - status = SPDK_BDEV_IO_STATUS_NVME_ERROR; - } else { - status = SPDK_BDEV_IO_STATUS_SUCCESS; - } - - spdk_bdev_io_complete(bdev_io, status); + spdk_bdev_io_complete_nvme_status(bdev_io, cpl->status.sct, cpl->status.sc); } static void diff --git a/lib/nvmf/virtual.c b/lib/nvmf/virtual.c index 4a48badb0..80d949c6c 100644 --- a/lib/nvmf/virtual.c +++ b/lib/nvmf/virtual.c @@ -124,19 +124,16 @@ nvmf_virtual_ctrlr_complete_cmd(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_ struct spdk_nvmf_request *req = cb_arg; struct spdk_nvme_cpl *response = &req->rsp->nvme_cpl; struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd; + int sc, sct; if (cmd->opc == SPDK_NVME_OPC_DATASET_MANAGEMENT) { free(bdev_io->u.unmap.unmap_bdesc); } - if (status == SPDK_BDEV_IO_STATUS_SUCCESS) { - response->status.sc = SPDK_NVME_SC_SUCCESS; - } else if (status == SPDK_BDEV_IO_STATUS_NVME_ERROR) { - response->status.sct = bdev_io->error.nvme.sct; - response->status.sc = bdev_io->error.nvme.sc; - } else { - response->status.sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR; - } + spdk_bdev_io_get_nvme_status(bdev_io, &sc, &sct); + response->status.sc = sc; + response->status.sct = sct; + spdk_nvmf_request_complete(req); spdk_bdev_free_io(bdev_io); }