scsi: refactor usage of iov from spdk_scsi_task

This patch is preparation for fixing alloc_len overrun in SENSE 6/10 and
READCAP 6/10. To simplify code forbid usage of iov outside of
scsi/task.c.

This also drop SPDK_SCSI_TASK_ALLOC_BUFFER flag that obfuscate code. As
a replacement assume that if field alloc_len is non zero it mean that
iov.buffer is internally allocated. Functions
spdk_scsi_task_free_data(), spdk_scsi_task_set_data() and
spdk_scsi_task_alloc_data() manage this field.

Change-Id: Ife357a5bc36121f93a4c5d259b9a5a01559e7708
Signed-off-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
This commit is contained in:
Pawel Wodkowski 2016-11-04 19:45:54 +01:00 committed by Daniel Verkamp
parent 51c6917fad
commit f30f0c76f1
7 changed files with 205 additions and 76 deletions

View File

@ -63,10 +63,6 @@
#define SPDK_SCSI_LUN_MAX_NAME_LENGTH 16
/* This flag indicated that data buffers are allocated
* internally and hence need to be freed by the SCSI layer.*/
#define SPDK_SCSI_TASK_ALLOC_BUFFER 1
enum spdk_scsi_data_dir {
SPDK_SCSI_DIR_NONE = 0,
SPDK_SCSI_DIR_TO_DEV = 1,
@ -125,7 +121,6 @@ struct spdk_scsi_task {
* transfer_len - i.e. SCSI INQUIRY.
*/
uint32_t data_transferred;
uint32_t alloc_len;
uint64_t offset;
struct spdk_scsi_task *parent;
@ -134,10 +129,18 @@ struct spdk_scsi_task {
uint8_t *cdb;
/**
* \internal
* Size of internal buffer or zero when iov.iov_base is not internally managed.
*/
uint32_t alloc_len;
/**
* \internal
* iov is internal buffer. Use iovs to access elements of IO.
*/
struct iovec iov;
struct iovec *iovs;
uint16_t iovcnt;
uint8_t iov_flags;
uint8_t sense_data[32];
size_t sense_data_len;
@ -256,8 +259,30 @@ int spdk_scsi_port_construct(struct spdk_scsi_port *port, uint64_t id,
void spdk_scsi_task_construct(struct spdk_scsi_task *task, uint32_t *owner_task_ctr,
struct spdk_scsi_task *parent);
void spdk_scsi_task_put(struct spdk_scsi_task *task);
void spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len,
uint8_t **data);
void spdk_scsi_task_free_data(struct spdk_scsi_task *task);
/**
* Set internal buffer to given one. Caller is owner of that buffer.
*
* \param task Task struct
* \param data Pointer to buffer
* \param len Buffer length
*/
void spdk_scsi_task_set_data(struct spdk_scsi_task *task, void *data, uint32_t len);
/**
* Allocate internal buffer of requested size. Caller is not owner of
* returned buffer and must not free it. Caller is permitted to call
* spdk_scsi_task_free_data() to free internal buffer if it is not required
* anymore, but must assert that task is done and not used by library.
* The count of io vectors must by one. Any previously allocated buffer will be
* invalid after this call.
*
* \param task Task struct
* \param alloc_len Size of allocated buffer.
* \return Pointer to buffer or NULL on error.
*/
void *spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len);
void spdk_scsi_task_build_sense_data(struct spdk_scsi_task *task, int sk, int asc,
int ascq);
void spdk_scsi_task_set_status(struct spdk_scsi_task *task, int sc, int sk, int asc,

View File

@ -2602,7 +2602,7 @@ spdk_iscsi_send_datain(struct spdk_iscsi_conn *conn,
/* DATA PDU */
rsp_pdu = spdk_get_pdu();
rsph = (struct iscsi_bhs_data_in *)&rsp_pdu->bhs;
rsp_pdu->data = task->scsi.iov.iov_base + offset;
rsp_pdu->data = task->scsi.iovs[0].iov_base + offset;
rsp_pdu->data_from_mempool = true;
task_tag = task->scsi.id;
@ -2844,7 +2844,7 @@ int spdk_iscsi_conn_handle_queued_tasks(struct spdk_iscsi_conn *conn)
assert(subtask != NULL);
subtask->scsi.offset = task->current_datain_offset;
subtask->scsi.length = DMIN32(SPDK_BDEV_LARGE_RBUF_MAX_SIZE, remaining_size);
subtask->scsi.iov.iov_base = NULL;
spdk_scsi_task_set_data(&subtask->scsi, NULL, 0);
spdk_iscsi_queue_task(conn, subtask);
task->current_datain_offset += subtask->scsi.length;
conn->data_in_cnt++;
@ -2866,7 +2866,7 @@ static int spdk_iscsi_op_scsi_read(struct spdk_iscsi_conn *conn,
task->scsi.parent = NULL;
task->scsi.offset = 0;
task->scsi.length = DMIN32(SPDK_BDEV_LARGE_RBUF_MAX_SIZE, task->scsi.transfer_len);
task->scsi.iov.iov_base = NULL;
spdk_scsi_task_set_data(&task->scsi, NULL, 0);
remaining_size = task->scsi.transfer_len - task->scsi.length;
task->current_datain_offset = 0;
@ -2985,16 +2985,14 @@ spdk_iscsi_op_scsi(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
else {
/* we are doing the first partial write task */
task->scsi.ref++;
task->scsi.iov.iov_base = pdu->data;
task->scsi.iov.iov_len = pdu->data_segment_len;
spdk_scsi_task_set_data(&task->scsi, pdu->data, pdu->data_segment_len);
task->scsi.length = pdu->data_segment_len;
}
}
if (pdu->data_segment_len == transfer_len) {
/* we are doing small writes with no R2T */
task->scsi.iov.iov_len = transfer_len;
task->scsi.iov.iov_base = pdu->data;
spdk_scsi_task_set_data(&task->scsi, pdu->data, transfer_len);
task->scsi.length = transfer_len;
}
} else {
@ -4083,8 +4081,7 @@ static int spdk_iscsi_op_data(struct spdk_iscsi_conn *conn,
}
subtask->scsi.offset = buffer_offset;
subtask->scsi.length = pdu->data_segment_len;
subtask->scsi.iov.iov_base = pdu->data;
subtask->scsi.iov.iov_len = pdu->data_segment_len;
spdk_scsi_task_set_data(&subtask->scsi, pdu->data, pdu->data_segment_len);
spdk_iscsi_task_associate_pdu(subtask, pdu);
if (task->next_expected_r2t_offset == transfer_len) {

View File

@ -194,7 +194,7 @@ complete_task_with_no_lun(struct spdk_scsi_task *task)
* PERIPHERAL DEVICE TYPE = 0x1F.
*/
allocation_len = from_be16(&task->cdb[3]);
spdk_scsi_task_alloc_data(task, allocation_len, &data);
data = spdk_scsi_task_alloc_data(task, allocation_len);
data_len = 36;
memset(data, 0, data_len);
/* PERIPHERAL QUALIFIER(7-5) PERIPHERAL DEVICE TYPE(4-0) */

View File

@ -1317,8 +1317,9 @@ spdk_bdev_scsi_task_complete(spdk_event_t event)
spdk_scsi_lun_clear_all(task->lun);
}
}
if (bdev_io->type == SPDK_BDEV_IO_TYPE_READ) {
task->iov.iov_base = bdev_io->u.read.iovs[0].iov_base;
if (bdev_io->type == SPDK_BDEV_IO_TYPE_READ && task->iovs != bdev_io->u.read.iovs) {
assert(task->iovcnt == bdev_io->u.read.iovcnt);
memcpy(task->iovs, bdev_io->u.read.iovs, sizeof(task->iovs[0]) * task->iovcnt);
}
spdk_scsi_lun_complete_task(task->lun, task);
@ -1510,7 +1511,7 @@ spdk_bdev_scsi_unmap(struct spdk_bdev *bdev,
uint8_t *data;
uint16_t bdesc_data_len, bdesc_count;
data = (uint8_t *)task->iov.iov_base;
data = (uint8_t *)task->iovs[0].iov_base;
/*
* The UNMAP BLOCK DESCRIPTOR DATA LENGTH field specifies the length in
@ -1591,7 +1592,7 @@ spdk_bdev_scsi_process_block(struct spdk_bdev *bdev,
return spdk_bdev_scsi_readwrite(bdev, task, lba, xfer_len);
case SPDK_SBC_READ_CAPACITY_10:
spdk_scsi_task_alloc_data(task, 8, &data);
data = spdk_scsi_task_alloc_data(task, 8);
if (bdev->blockcnt - 1 > 0xffffffffULL) {
memset(data, 0xff, 4);
} else {
@ -1605,7 +1606,7 @@ spdk_bdev_scsi_process_block(struct spdk_bdev *bdev,
case SPDK_SPC_SERVICE_ACTION_IN_16:
switch (cdb[1] & 0x1f) { /* SERVICE ACTION */
case SPDK_SBC_SAI_READ_CAPACITY_16:
spdk_scsi_task_alloc_data(task, 32, &data);
data = spdk_scsi_task_alloc_data(task, 32);
to_be64(&data[0], bdev->blockcnt - 1);
to_be32(&data[8], bdev->blocklen);
/*
@ -1669,7 +1670,7 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
switch (cdb[0]) {
case SPDK_SPC_INQUIRY:
alloc_len = from_be16(&cdb[3]);
spdk_scsi_task_alloc_data(task, alloc_len, &data);
data = spdk_scsi_task_alloc_data(task, alloc_len);
data_len = spdk_bdev_scsi_inquiry(bdev, task, cdb,
data, alloc_len);
if (data_len < 0) {
@ -1697,7 +1698,7 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
break;
}
spdk_scsi_task_alloc_data(task, alloc_len, &data);
data = spdk_scsi_task_alloc_data(task, alloc_len);
data_len = spdk_bdev_scsi_report_luns(task->lun, sel, data, task->alloc_len);
if (data_len < 0) {
spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
@ -1715,7 +1716,7 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
case SPDK_SPC_MODE_SELECT_6:
case SPDK_SPC_MODE_SELECT_10:
data = task->iov.iov_base;
data = task->iovs[0].iov_base;
if (cdb[0] == SPDK_SPC_MODE_SELECT_6) {
md = 4;
@ -1792,7 +1793,7 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
page = cdb[2] & 0x3f;
subpage = cdb[3];
spdk_scsi_task_alloc_data(task, alloc_len, &data);
data = spdk_scsi_task_alloc_data(task, alloc_len);
if (md == 6) {
data_len = spdk_bdev_scsi_mode_sense6(bdev,
@ -1838,7 +1839,7 @@ spdk_bdev_scsi_process_primary(struct spdk_bdev *bdev,
}
alloc_len = cdb[4];
spdk_scsi_task_alloc_data(task, alloc_len, &data);
data = spdk_scsi_task_alloc_data(task, alloc_len);
/* NO ADDITIONAL SENSE INFORMATION */
sk = SPDK_SCSI_SENSE_NO_SENSE;

View File

@ -59,11 +59,11 @@ spdk_scsi_task_put(struct spdk_scsi_task *task)
bdev_io->status = SPDK_BDEV_IO_STATUS_FAILED;
}
spdk_bdev_free_io(bdev_io);
} else if (task->iov_flags & SPDK_SCSI_TASK_ALLOC_BUFFER) {
spdk_free(task->iov.iov_base);
}
spdk_scsi_task_free_data(task);
assert(task->owner_task_ctr != NULL);
if (*(task->owner_task_ctr) > 0) {
*(task->owner_task_ctr) -= 1;
} else {
@ -87,6 +87,7 @@ spdk_scsi_task_construct(struct spdk_scsi_task *task, uint32_t *owner_task_ctr,
/*
* Pre-fill the iov_buffers to point to the embedded iov
*/
assert(task->iov.iov_base == NULL);
task->iovs = &task->iov;
task->iovcnt = 1;
@ -105,8 +106,19 @@ spdk_scsi_task_construct(struct spdk_scsi_task *task, uint32_t *owner_task_ctr,
}
void
spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len,
uint8_t **data)
spdk_scsi_task_free_data(struct spdk_scsi_task *task)
{
if (task->alloc_len != 0) {
spdk_free(task->iov.iov_base);
task->alloc_len = 0;
}
task->iov.iov_base = NULL;
task->iov.iov_len = 0;
}
void *
spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len)
{
/*
* SPDK iSCSI target depends on allocating at least 4096 bytes, even if
@ -117,17 +129,37 @@ spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len,
* care of only sending back the amount of data specified in the
* allocation length.
*/
assert(task->alloc_len == 0);
/* Only one buffer is managable */
if (task->iovcnt != 1) {
return NULL;
}
if (alloc_len < 4096) {
alloc_len = 4096;
}
/* This is workaround for buffers shorter than 4kb */
if (task->iov.iov_base == NULL) {
task->iov.iov_base = spdk_zmalloc(alloc_len, 0, NULL);
task->iov_flags |= SPDK_SCSI_TASK_ALLOC_BUFFER;
task->alloc_len = alloc_len;
}
task->alloc_len = alloc_len;
*data = task->iov.iov_base;
memset(task->iov.iov_base, 0, task->alloc_len);
task->iov.iov_len = alloc_len;
assert(&task->iov == task->iovs);
return task->iov.iov_base;
}
void
spdk_scsi_task_set_data(struct spdk_scsi_task *task, void *data, uint32_t len)
{
assert(task->iovcnt == 1);
assert(task->alloc_len == 0);
task->iovs[0].iov_base = data;
task->iovs[0].iov_len = len;
}
void

View File

@ -66,6 +66,8 @@ spdk_get_task(uint32_t *owner_task_ctr)
}
task->id = g_task_count;
task->iovs = &task->iov;
task->iovcnt = 1;
g_task_count++;
@ -76,7 +78,7 @@ void
spdk_scsi_task_put(struct spdk_scsi_task *task)
{
g_task_count--;
if (task->iov_flags & SPDK_SCSI_TASK_ALLOC_BUFFER) {
if (task->alloc_len) {
free(task->iov.iov_base);
}
free(task);
@ -89,15 +91,17 @@ spdk_scsi_task_set_status(struct spdk_scsi_task *task, int sc, int sk,
task->status = sc;
}
void
spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len,
uint8_t **data)
void *
spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len)
{
if (alloc_len < 4096)
alloc_len = 4096;
task->iovs = &task->iov;
task->iov.iov_base = malloc(alloc_len);
task->iov.iov_len = alloc_len;
task->alloc_len = alloc_len;
*data = task->iov.iov_base;
return task->iov.iov_base;
}
void spdk_scsi_dev_queue_mgmt_task(struct spdk_scsi_dev *dev,
@ -419,8 +423,6 @@ lun_append_task_null_lun_task_cdb_spc_inquiry(void)
/* alloc_len >= 4096 */
task->cdb[3] = 0xFF;
task->cdb[4] = 0xFF;
task->iov.iov_base = malloc(65536);
task->iov_flags |= SPDK_SCSI_TASK_ALLOC_BUFFER;
task->lun = NULL;
spdk_scsi_lun_append_task(NULL, task);
@ -446,8 +448,6 @@ lun_append_task_null_lun_alloc_len_lt_4096(void)
task->cdb[4] = 0;
/* alloc_len is set to a minimal value of 4096
* Hence, rbuf of size 4096 is allocated*/
task->iov.iov_base = malloc(4096);
task->iov_flags |= SPDK_SCSI_TASK_ALLOC_BUFFER;
spdk_scsi_lun_append_task(NULL, task);
CU_ASSERT_EQUAL(task->status, SPDK_SCSI_STATUS_GOOD);

View File

@ -37,7 +37,7 @@
#include "scsi_bdev.c"
#include "CUnit/Basic.h"
#include "spdk_cunit.h"
SPDK_LOG_REGISTER_TRACE_FLAG("scsi", SPDK_TRACE_SCSI)
@ -61,16 +61,66 @@ spdk_scsi_task_set_status(struct spdk_scsi_task *task, int sc, int sk,
task->status = sc;
}
static void
spdk_put_task(struct spdk_scsi_task *task)
{
spdk_scsi_task_free_data(task);
}
static void
spdk_init_task(struct spdk_scsi_task *task)
{
memset(task, 0, sizeof(*task));
task->id = 1;
task->iovs = &task->iov;
task->iovcnt = 1;
}
void
spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len,
uint8_t **data)
spdk_scsi_task_set_data(struct spdk_scsi_task *task, void *data, uint32_t len)
{
assert(task->alloc_len == 0);
task->iov.iov_base = data;
task->iov.iov_len = len;
task->alloc_len = 0;
}
void *
spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len)
{
if (alloc_len < 4096) {
alloc_len = 4096;
}
task->alloc_len = alloc_len;
*data = task->iov.iov_base;
if (task->iov.iov_base != NULL) {
if (task->alloc_len != 0 && alloc_len > task->alloc_len) {
spdk_put_task(task);
} else if (task->alloc_len == 0 && alloc_len > task->iov.iov_len) {
/* External data buffer less than requested. */
return NULL;
}
}
if (task->iov.iov_base == NULL) {
task->iov.iov_base = calloc(alloc_len, 1);
task->alloc_len = alloc_len;
}
task->iov.iov_len = alloc_len;
return task->iov.iov_base;
}
void
spdk_scsi_task_free_data(struct spdk_scsi_task *task)
{
if (task->alloc_len)
free(task->iov.iov_base);
task->iov.iov_base = NULL;
task->iov.iov_len = 0;
task->alloc_len = 0;
}
void
@ -184,6 +234,8 @@ mode_select_6_test(void)
char data[24];
int rc;
spdk_init_task(&task);
cdb[0] = 0x15;
cdb[1] = 0x11;
cdb[2] = 0x00;
@ -199,11 +251,13 @@ mode_select_6_test(void)
memset(data, 0, sizeof(data));
data[4] = 0x08;
data[5] = 0x02;
task.iov.iov_base = data;
spdk_scsi_task_set_data(&task, data, sizeof(data));
rc = spdk_bdev_scsi_execute(&bdev, &task);
CU_ASSERT_EQUAL(rc, 0);
spdk_put_task(&task);
}
/*
@ -220,6 +274,8 @@ mode_select_6_test2(void)
char cdb[16];
int rc;
spdk_init_task(&task);
cdb[0] = 0x15;
cdb[1] = 0x00;
cdb[2] = 0x00;
@ -232,11 +288,11 @@ mode_select_6_test2(void)
lun.dev = &dev;
task.lun = &lun;
task.iov.iov_base = NULL;
rc = spdk_bdev_scsi_execute(&bdev, &task);
CU_ASSERT_EQUAL(rc, 0);
spdk_put_task(&task);
}
/*
@ -251,14 +307,15 @@ mode_sense_6_test(void)
struct spdk_scsi_lun lun;
struct spdk_scsi_dev dev;
char cdb[12];
unsigned char data[4096];
int rc = 0;
unsigned char *data;
int rc;
unsigned char mode_data_len = 0;
unsigned char medium_type = 0;
unsigned char dev_specific_param = 0;
unsigned char blk_descriptor_len = 0;
memset(&bdev, 0 , sizeof(struct spdk_bdev));
spdk_init_task(&task);
memset(cdb, 0, sizeof(cdb));
cdb[0] = 0x1A;
@ -270,9 +327,10 @@ mode_sense_6_test(void)
lun.dev = &dev;
task.lun = &lun;
task.iov.iov_base = data;
rc = spdk_bdev_scsi_execute(&bdev, &task);
SPDK_CU_ASSERT_FATAL(rc == 0);
data = task.iovs[0].iov_base;
mode_data_len = data[0];
medium_type = data[1];
dev_specific_param = data[2];
@ -282,7 +340,8 @@ mode_sense_6_test(void)
CU_ASSERT_EQUAL(medium_type, 0);
CU_ASSERT_EQUAL(dev_specific_param, 0);
CU_ASSERT_EQUAL(blk_descriptor_len, 8);
CU_ASSERT_EQUAL(rc, 0);
spdk_put_task(&task);
}
/*
@ -297,7 +356,7 @@ mode_sense_10_test(void)
struct spdk_scsi_lun lun;
struct spdk_scsi_dev dev;
char cdb[12];
unsigned char data[4096];
unsigned char *data;
int rc;
unsigned short mode_data_len = 0;
unsigned char medium_type = 0;
@ -305,6 +364,7 @@ mode_sense_10_test(void)
unsigned short blk_descriptor_len = 0;
memset(&bdev, 0 , sizeof(struct spdk_bdev));
spdk_init_task(&task);
memset(cdb, 0, sizeof(cdb));
cdb[0] = 0x5A;
cdb[2] = 0x3F;
@ -315,9 +375,10 @@ mode_sense_10_test(void)
lun.dev = &dev;
task.lun = &lun;
task.iov.iov_base = data;
rc = spdk_bdev_scsi_execute(&bdev, &task);
SPDK_CU_ASSERT_FATAL(rc == 0);
data = task.iovs[0].iov_base;
mode_data_len = ((data[0] << 8) + data[1]);
medium_type = data[2];
dev_specific_param = data[3];
@ -327,7 +388,8 @@ mode_sense_10_test(void)
CU_ASSERT_EQUAL(medium_type, 0);
CU_ASSERT_EQUAL(dev_specific_param, 0);
CU_ASSERT_EQUAL(blk_descriptor_len, 8);
CU_ASSERT_EQUAL(rc, 0);
spdk_put_task(&task);
}
/*
@ -343,9 +405,10 @@ inquiry_evpd_test(void)
struct spdk_scsi_lun lun;
struct spdk_scsi_dev dev;
char cdb[6];
char data[4096];
int rc;
spdk_init_task(&task);
cdb[0] = 0x12;
cdb[1] = 0x00; // EVPD = 0
cdb[2] = 0xff; // PageCode non-zero
@ -358,16 +421,15 @@ inquiry_evpd_test(void)
lun.dev = &dev;
task.lun = &lun;
memset(data, 0, 4096);
task.iov.iov_base = data;
rc = spdk_bdev_scsi_execute(&bdev, &task);
SPDK_CU_ASSERT_FATAL(rc == 0);
CU_ASSERT_EQUAL(task.status, SPDK_SCSI_STATUS_CHECK_CONDITION);
CU_ASSERT_EQUAL(task.sense_data[2] & 0xf, SPDK_SCSI_SENSE_ILLEGAL_REQUEST);
CU_ASSERT_EQUAL(task.sense_data[12], 0x24);
CU_ASSERT_EQUAL(task.sense_data[13], 0x0);
CU_ASSERT_EQUAL(rc, 0);
spdk_put_task(&task);
}
/*
@ -383,10 +445,12 @@ inquiry_standard_test(void)
struct spdk_scsi_dev dev;
char cdb[6];
/* expects a 4K internal data buffer */
char data[4096];
char *data;
struct spdk_scsi_cdb_inquiry_data *inq_data;
int rc;
spdk_init_task(&task);
cdb[0] = 0x12;
cdb[1] = 0x00; // EVPD = 0
cdb[2] = 0x00; // PageCode zero - requesting standard inquiry
@ -399,15 +463,15 @@ inquiry_standard_test(void)
lun.dev = &dev;
task.lun = &lun;
memset(data, 0, 4096);
task.iov.iov_base = data;
rc = spdk_bdev_scsi_execute(&bdev, &task);
data = task.iovs[0].iov_base;
inq_data = (struct spdk_scsi_cdb_inquiry_data *)&data[0];
CU_ASSERT_EQUAL(inq_data->version, SPDK_SPC_VERSION_SPC3);
CU_ASSERT_EQUAL(rc, 0);
spdk_put_task(&task);
}
static void
@ -418,9 +482,11 @@ _inquiry_overflow_test(uint8_t alloc_len)
struct spdk_scsi_lun lun;
struct spdk_scsi_dev dev;
uint8_t cdb[6];
/* expects a 4K internal data buffer */
char data[256], data_compare[256];
int rc;
/* expects a 4K internal data buffer */
char data[4096], data_compare[4096];
spdk_init_task(&task);
cdb[0] = 0x12;
cdb[1] = 0x00; // EVPD = 0
@ -436,12 +502,16 @@ _inquiry_overflow_test(uint8_t alloc_len)
memset(data, 0, sizeof(data));
memset(data_compare, 0, sizeof(data_compare));
task.iov.iov_base = data;
spdk_scsi_task_set_data(&task, data, sizeof(data));
rc = spdk_bdev_scsi_execute(&bdev, &task);
CU_ASSERT_EQUAL(rc, 0);
SPDK_CU_ASSERT_FATAL(rc == 0);
CU_ASSERT_EQUAL(memcmp(data + alloc_len, data_compare + alloc_len, sizeof(data) - alloc_len), 0);
CU_ASSERT(task.data_transferred <= alloc_len);
spdk_put_task(&task);
}
static void
@ -461,10 +531,12 @@ static void
task_complete_test(void)
{
struct spdk_event event;
struct spdk_scsi_task task = {};
struct spdk_scsi_task task;
struct spdk_bdev_io bdev_io = {};
struct spdk_scsi_lun lun;
spdk_init_task(&task);
TAILQ_INIT(&lun.tasks);
TAILQ_INSERT_TAIL(&lun.tasks, &task, scsi_link);
task.lun = &lun;
@ -494,6 +566,8 @@ task_complete_test(void)
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);
spdk_put_task(&task);
}
int