bdev: Add spdk_bdev_io_get_nvme_fused_status function

Added new function for getting NVMe specific return code
for fused commands. Also changed one of the return codes
in fused commands so that we could distinguish error
cases.

Signed-off-by: Maciej Szwed <maciej.szwed@intel.com>
Change-Id: I86417ea4f5b8f3e6496162be3d6c6128076e35d4

Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/481666
Community-CI: Broadcom SPDK FC-NVMe CI <spdk-ci.pdl@broadcom.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Maciej Szwed 2020-01-15 09:53:12 +01:00 committed by Tomasz Zawadzki
parent d417768c00
commit adf90938b1
4 changed files with 72 additions and 1 deletions

View File

@ -130,6 +130,11 @@ The functions `spdk_reactor_enable_framework_monitor_context_switch()` and
`spdk_framework_enable_context_switch_monitor()` and
`spdk_framework_context_switch_monitor_enabled()`, respectively.
### bdev
Added spdk_bdev_io_get_nvme_fused_status function for translating bdev_io status to NVMe status
code for fused compare-and-write operation.
## v19.10:
### rpc

View File

@ -1139,6 +1139,9 @@ int spdk_bdev_comparev_blocks_with_md(struct spdk_bdev_desc *desc, struct spdk_i
* data and may not be able to directly transfer out of the buffers provided. In
* this case, the request may fail.
*
* spdk_bdev_io_get_nvme_fused_status() function should be called in callback function
* to get status for the individual operation.
*
* \ingroup bdev_io_submit_functions
*
* \param desc Block device descriptor.
@ -1559,6 +1562,20 @@ void spdk_bdev_get_device_stat(struct spdk_bdev *bdev, struct spdk_bdev_io_stat
void spdk_bdev_io_get_nvme_status(const struct spdk_bdev_io *bdev_io, uint32_t *cdw0, int *sct,
int *sc);
/**
* Get the status of bdev_io as an NVMe status codes and command specific
* completion queue value for fused operations such as compare-and-write.
*
* \param bdev_io I/O to get the status from.
* \param cdw0 Command specific completion queue value
* \param first_sct Status Code Type return value for the first operation, as defined by the NVMe specification.
* \param first_sc Status Code return value for the first operation, as defined by the NVMe specification.
* \param second_sct Status Code Type return value for the second operation, as defined by the NVMe specification.
* \param second_sc Status Code return value for the second operation, as defined by the NVMe specification.
*/
void spdk_bdev_io_get_nvme_fused_status(const struct spdk_bdev_io *bdev_io, uint32_t *cdw0,
int *first_sct, int *first_sc, int *second_sct, int *second_sc);
/**
* Get the status of bdev_io as a SCSI status code.
*

View File

@ -222,6 +222,7 @@ struct spdk_bdev_fn_table {
/** bdev I/O completion status */
enum spdk_bdev_io_status {
SPDK_BDEV_IO_STATUS_FIRST_FUSED_FAILED = -6,
SPDK_BDEV_IO_STATUS_MISCOMPARE = -5,
/*
* NOMEM should be returned when a bdev module cannot start an I/O because of

View File

@ -3691,7 +3691,7 @@ bdev_compare_and_write_do_compare(void *_bdev_io)
if (rc == -ENOMEM) {
bdev_queue_io_wait_with_cb(bdev_io, bdev_compare_and_write_do_compare);
} else if (rc != 0) {
bdev_io->internal.status = SPDK_BDEV_IO_STATUS_FAILED;
bdev_io->internal.status = SPDK_BDEV_IO_STATUS_FIRST_FUSED_FAILED;
bdev_io->internal.cb(bdev_io, false, bdev_io->internal.caller_ctx);
}
}
@ -4639,6 +4639,54 @@ spdk_bdev_io_get_nvme_status(const struct spdk_bdev_io *bdev_io, uint32_t *cdw0,
*cdw0 = bdev_io->internal.error.nvme.cdw0;
}
void
spdk_bdev_io_get_nvme_fused_status(const struct spdk_bdev_io *bdev_io, uint32_t *cdw0,
int *first_sct, int *first_sc, int *second_sct, int *second_sc)
{
assert(first_sct != NULL);
assert(first_sc != NULL);
assert(second_sct != NULL);
assert(second_sc != NULL);
assert(cdw0 != NULL);
if (bdev_io->internal.status == SPDK_BDEV_IO_STATUS_NVME_ERROR) {
if (bdev_io->internal.error.nvme.sct == SPDK_NVME_SCT_MEDIA_ERROR &&
bdev_io->internal.error.nvme.sc == SPDK_NVME_SC_COMPARE_FAILURE) {
*first_sct = bdev_io->internal.error.nvme.sct;
*first_sc = bdev_io->internal.error.nvme.sc;
*second_sct = SPDK_NVME_SCT_GENERIC;
*second_sc = SPDK_NVME_SC_ABORTED_FAILED_FUSED;
} else {
*first_sct = SPDK_NVME_SCT_GENERIC;
*first_sc = SPDK_NVME_SC_SUCCESS;
*second_sct = bdev_io->internal.error.nvme.sct;
*second_sc = bdev_io->internal.error.nvme.sc;
}
} else if (bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS) {
*first_sct = SPDK_NVME_SCT_GENERIC;
*first_sc = SPDK_NVME_SC_SUCCESS;
*second_sct = SPDK_NVME_SCT_GENERIC;
*second_sc = SPDK_NVME_SC_SUCCESS;
} else if (bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FIRST_FUSED_FAILED) {
*first_sct = SPDK_NVME_SCT_GENERIC;
*first_sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
*second_sct = SPDK_NVME_SCT_GENERIC;
*second_sc = SPDK_NVME_SC_ABORTED_FAILED_FUSED;
} else if (bdev_io->internal.status == SPDK_BDEV_IO_STATUS_MISCOMPARE) {
*first_sct = SPDK_NVME_SCT_MEDIA_ERROR;
*first_sc = SPDK_NVME_SC_COMPARE_FAILURE;
*second_sct = SPDK_NVME_SCT_GENERIC;
*second_sc = SPDK_NVME_SC_ABORTED_FAILED_FUSED;
} else {
*first_sct = SPDK_NVME_SCT_GENERIC;
*first_sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
*second_sct = SPDK_NVME_SCT_GENERIC;
*second_sc = SPDK_NVME_SC_INTERNAL_DEVICE_ERROR;
}
*cdw0 = bdev_io->internal.error.nvme.cdw0;
}
struct spdk_thread *
spdk_bdev_io_get_thread(struct spdk_bdev_io *bdev_io)
{