bdev: add API to translate to and from NVMe status

This prevents the need for bdev users and modules to manipulate the
internal bdev_io error.nvme fields.

For now, all non-NVMe error types are treated as a generic device error,
but translation from SCSI to NVMe could be added in the future.

Change-Id: I4e831b26a2f41bf2f405c7576d5019bb898d4d1b
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Daniel Verkamp 2017-01-18 14:43:15 -07:00
parent d946f92079
commit a53f617423
5 changed files with 59 additions and 18 deletions

View File

@ -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_ */

View File

@ -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);

View File

@ -44,6 +44,7 @@
#include <rte_version.h>
#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)
{

View File

@ -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

View File

@ -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);
}