hw/nvme: set error status code explicitly for misc commands

The nvme_aio_err() does not handle Verify, Compare, Copy and other misc
commands and defaults to setting the error status code to Internal
Device Error. For some of these commands, we know better, so set it
explicitly.

For the commands using the nvme_misc_cb() callback (Copy, Flush, ...),
if no status code has explicitly been set by the lower handlers, default
to Internal Device Error as previously.

Reviewed-by: Jesper Wendel Devantier <foss@defmacro.it>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
This commit is contained in:
Klaus Jensen 2024-12-16 13:53:09 +01:00
parent 304babd940
commit 6fc39228ff
2 changed files with 23 additions and 6 deletions

View file

@ -1771,7 +1771,6 @@ static void nvme_aio_err(NvmeRequest *req, int ret)
case NVME_CMD_READ:
status = NVME_UNRECOVERED_READ;
break;
case NVME_CMD_FLUSH:
case NVME_CMD_WRITE:
case NVME_CMD_WRITE_ZEROES:
case NVME_CMD_ZONE_APPEND:
@ -2157,11 +2156,16 @@ static inline bool nvme_is_write(NvmeRequest *req)
static void nvme_misc_cb(void *opaque, int ret)
{
NvmeRequest *req = opaque;
uint16_t cid = nvme_cid(req);
trace_pci_nvme_misc_cb(nvme_cid(req));
trace_pci_nvme_misc_cb(cid);
if (ret) {
nvme_aio_err(req, ret);
if (!req->status) {
req->status = NVME_INTERNAL_DEV_ERROR;
}
trace_pci_nvme_err_aio(cid, strerror(-ret), req->status);
}
nvme_enqueue_req_completion(nvme_cq(req), req);
@ -2264,7 +2268,10 @@ static void nvme_verify_cb(void *opaque, int ret)
if (ret) {
block_acct_failed(stats, acct);
nvme_aio_err(req, ret);
req->status = NVME_UNRECOVERED_READ;
trace_pci_nvme_err_aio(nvme_cid(req), strerror(-ret), req->status);
goto out;
}
@ -2363,7 +2370,10 @@ static void nvme_compare_mdata_cb(void *opaque, int ret)
if (ret) {
block_acct_failed(stats, acct);
nvme_aio_err(req, ret);
req->status = NVME_UNRECOVERED_READ;
trace_pci_nvme_err_aio(nvme_cid(req), strerror(-ret), req->status);
goto out;
}
@ -2445,7 +2455,10 @@ static void nvme_compare_data_cb(void *opaque, int ret)
if (ret) {
block_acct_failed(stats, acct);
nvme_aio_err(req, ret);
req->status = NVME_UNRECOVERED_READ;
trace_pci_nvme_err_aio(nvme_cid(req), strerror(-ret), req->status);
goto out;
}
@ -2924,6 +2937,7 @@ static void nvme_copy_out_completed_cb(void *opaque, int ret)
if (ret < 0) {
iocb->ret = ret;
req->status = NVME_WRITE_FAULT;
goto out;
} else if (iocb->ret < 0) {
goto out;
@ -2988,6 +3002,7 @@ static void nvme_copy_in_completed_cb(void *opaque, int ret)
if (ret < 0) {
iocb->ret = ret;
req->status = NVME_UNRECOVERED_READ;
goto out;
} else if (iocb->ret < 0) {
goto out;
@ -3510,6 +3525,7 @@ static void nvme_flush_ns_cb(void *opaque, int ret)
if (ret < 0) {
iocb->ret = ret;
iocb->req->status = NVME_WRITE_FAULT;
goto out;
} else if (iocb->ret < 0) {
goto out;

View file

@ -906,6 +906,7 @@ enum NvmeStatusCodes {
NVME_SGL_DESCR_TYPE_INVALID = 0x0011,
NVME_INVALID_USE_OF_CMB = 0x0012,
NVME_INVALID_PRP_OFFSET = 0x0013,
NVME_COMMAND_INTERRUPTED = 0x0021,
NVME_FDP_DISABLED = 0x0029,
NVME_INVALID_PHID_LIST = 0x002a,
NVME_LBA_RANGE = 0x0080,