bdev: add members for SCSI sense information in spdk_bdev_io (#59)
Custom bdev modules can return any SCSI status and SCSI sense information to a host by this patch. This is usefull when a custome bdev module detect an error in the module and need to return meaningful information to a host.
This commit is contained in:
parent
1ffec5d53a
commit
6583441f54
@ -137,6 +137,7 @@ struct spdk_bdev_fn_table {
|
||||
|
||||
/** Blockdev I/O completion status */
|
||||
enum spdk_bdev_io_status {
|
||||
SPDK_BDEV_IO_STATUS_SCSI_ERROR = -3,
|
||||
SPDK_BDEV_IO_STATUS_NVME_ERROR = -2,
|
||||
SPDK_BDEV_IO_STATUS_FAILED = -1,
|
||||
SPDK_BDEV_IO_STATUS_PENDING = 0,
|
||||
@ -252,6 +253,17 @@ struct spdk_bdev_io {
|
||||
/** NVMe status code */
|
||||
int sc;
|
||||
} nvme;
|
||||
/** Only valid when status is SPDK_BDEV_IO_STATUS_SCSI_ERROR */
|
||||
struct {
|
||||
/** SCSI status code */
|
||||
enum spdk_scsi_status sc;
|
||||
/** SCSI sense key */
|
||||
enum spdk_scsi_sense sk;
|
||||
/** SCSI additional sense code */
|
||||
uint8_t asc;
|
||||
/** SCSI additional sense code qualifier */
|
||||
uint8_t ascq;
|
||||
} scsi;
|
||||
} error;
|
||||
|
||||
/** User function that will be called when this completes */
|
||||
@ -321,4 +333,6 @@ int spdk_bdev_free_io(struct spdk_bdev_io *bdev_io);
|
||||
int spdk_bdev_reset(struct spdk_bdev *bdev, enum spdk_bdev_reset_type,
|
||||
spdk_bdev_io_completion_cb cb, void *cb_arg);
|
||||
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);
|
||||
#endif /* SPDK_BDEV_H_ */
|
||||
|
@ -836,6 +836,17 @@ spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status sta
|
||||
spdk_event_call(bdev_io->cb_event);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
bdev_io->status = SPDK_BDEV_IO_STATUS_SCSI_ERROR;
|
||||
bdev_io->error.scsi.sc = sc;
|
||||
bdev_io->error.scsi.sk = sk;
|
||||
bdev_io->error.scsi.asc = asc;
|
||||
bdev_io->error.scsi.ascq = ascq;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_bdev_register(struct spdk_bdev *bdev)
|
||||
{
|
||||
|
@ -1283,23 +1283,29 @@ spdk_bdev_scsi_task_complete(spdk_event_t event)
|
||||
enum spdk_bdev_io_status status = bdev_io->status;
|
||||
|
||||
if (task->type == SPDK_SCSI_TASK_TYPE_CMD) {
|
||||
int sc, sk, asc, ascq;
|
||||
|
||||
switch (bdev_io->status) {
|
||||
case SPDK_BDEV_IO_STATUS_SUCCESS:
|
||||
if (status == SPDK_BDEV_IO_STATUS_SUCCESS) {
|
||||
task->status = SPDK_SCSI_STATUS_GOOD;
|
||||
break;
|
||||
case SPDK_BDEV_IO_STATUS_NVME_ERROR:
|
||||
spdk_scsi_nvme_translate(bdev_io, &sc, &sk, &asc, &ascq);
|
||||
} else {
|
||||
int sc, sk, asc, ascq;
|
||||
|
||||
switch (status) {
|
||||
case SPDK_BDEV_IO_STATUS_NVME_ERROR:
|
||||
spdk_scsi_nvme_translate(bdev_io, &sc, &sk, &asc, &ascq);
|
||||
break;
|
||||
case SPDK_BDEV_IO_STATUS_SCSI_ERROR:
|
||||
sc = bdev_io->error.scsi.sc;
|
||||
sk = bdev_io->error.scsi.sk;
|
||||
asc = bdev_io->error.scsi.asc;
|
||||
ascq = bdev_io->error.scsi.ascq;
|
||||
break;
|
||||
default:
|
||||
sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
|
||||
sk = SPDK_SCSI_SENSE_ABORTED_COMMAND;
|
||||
asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
|
||||
ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
break;
|
||||
}
|
||||
spdk_scsi_task_set_status(task, sc, sk, asc, ascq);
|
||||
break;
|
||||
default:
|
||||
sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
|
||||
sk = SPDK_SCSI_SENSE_ABORTED_COMMAND;
|
||||
asc = SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE;
|
||||
ascq = SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE;
|
||||
spdk_scsi_task_set_status(task, sc, sk, asc, ascq);
|
||||
break;
|
||||
}
|
||||
|
||||
/* command completed. remove from outstanding task list */
|
||||
|
@ -483,10 +483,21 @@ task_complete_test(void)
|
||||
spdk_bdev_scsi_task_complete(&event);
|
||||
CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_GOOD);
|
||||
|
||||
bdev_io.status = SPDK_BDEV_IO_STATUS_SCSI_ERROR;
|
||||
bdev_io.error.scsi.sc = SPDK_SCSI_STATUS_CHECK_CONDITION;
|
||||
bdev_io.error.scsi.sk = SPDK_SCSI_SENSE_HARDWARE_ERROR;
|
||||
bdev_io.error.scsi.asc = SPDK_SCSI_ASC_WARNING;
|
||||
bdev_io.error.scsi.ascq = SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED;
|
||||
spdk_bdev_scsi_task_complete(&event);
|
||||
CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
|
||||
CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_HARDWARE_ERROR);
|
||||
CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_WARNING);
|
||||
CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_POWER_LOSS_EXPECTED);
|
||||
|
||||
bdev_io.status = SPDK_BDEV_IO_STATUS_FAILED;
|
||||
spdk_bdev_scsi_task_complete(&event);
|
||||
CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
|
||||
CU_ASSERT_EQUAL(task.sense_data[2], SPDK_SCSI_SENSE_ABORTED_COMMAND);
|
||||
CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ABORTED_COMMAND);
|
||||
CU_ASSERT_EQUAL(task.sense_data[12], SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE);
|
||||
CU_ASSERT_EQUAL(task.sense_data[13], SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user