spdk: add support for readv and writev in scsi layer
This patch adds support for spdk_bdev_readv in scsi layer. It also fixes write so that it uses multiple iov's instead of one. Currently we should use only task->iov (for single vector operation) or task->iovs (for multiple vector operations). Signed-off-by: Piotr Pelplinski <piotr.pelplinski@intel.com> Change-Id: Ia3b2f6d18fd212b11d7b63b11dc46ec5bbc74788
This commit is contained in:
parent
563b2caf06
commit
a2d0fa5351
@ -63,6 +63,10 @@
|
||||
|
||||
#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,
|
||||
@ -133,11 +137,11 @@ struct spdk_scsi_task {
|
||||
struct iovec iov;
|
||||
struct iovec *iovs;
|
||||
uint16_t iovcnt;
|
||||
uint8_t iov_flags;
|
||||
|
||||
uint8_t sense_data[32];
|
||||
size_t sense_data_len;
|
||||
|
||||
uint8_t *rbuf; /* read buffer */
|
||||
void *blockdev_io;
|
||||
|
||||
TAILQ_ENTRY(spdk_scsi_task) scsi_link;
|
||||
|
@ -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.rbuf + offset;
|
||||
rsp_pdu->data = task->scsi.iov.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.rbuf = NULL;
|
||||
subtask->scsi.iov.iov_base = NULL;
|
||||
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.rbuf = NULL;
|
||||
task->scsi.iov.iov_base = NULL;
|
||||
|
||||
remaining_size = task->scsi.transfer_len - task->scsi.length;
|
||||
task->current_datain_offset = 0;
|
||||
|
@ -1300,9 +1300,8 @@ 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->rbuf = bdev_io->u.read.iovs[0].iov_base;
|
||||
task->iov.iov_base = bdev_io->u.read.iovs[0].iov_base;
|
||||
}
|
||||
|
||||
spdk_scsi_lun_complete_task(task->lun, task);
|
||||
@ -1334,11 +1333,11 @@ spdk_bdev_scsi_read(struct spdk_bdev *bdev,
|
||||
SPDK_ERRLOG("end of media\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
task->blockdev_io = spdk_bdev_read(bdev, task->ch, task->rbuf, offset, nbytes,
|
||||
spdk_bdev_scsi_task_complete, task);
|
||||
task->blockdev_io = spdk_bdev_readv(bdev, task->ch, task->iovs,
|
||||
task->iovcnt, offset, nbytes,
|
||||
spdk_bdev_scsi_task_complete, task);
|
||||
if (!task->blockdev_io) {
|
||||
SPDK_ERRLOG("spdk_bdev_read() failed\n");
|
||||
SPDK_ERRLOG("spdk_bdev_readv() failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1385,8 +1384,8 @@ spdk_bdev_scsi_write(struct spdk_bdev *bdev,
|
||||
}
|
||||
|
||||
offset += task->offset;
|
||||
task->blockdev_io = spdk_bdev_writev(bdev, task->ch, &task->iov,
|
||||
1, offset, task->length,
|
||||
task->blockdev_io = spdk_bdev_writev(bdev, task->ch, task->iovs,
|
||||
task->iovcnt, offset, task->length,
|
||||
spdk_bdev_scsi_task_complete,
|
||||
task);
|
||||
|
||||
|
@ -59,12 +59,10 @@ spdk_scsi_task_put(struct spdk_scsi_task *task)
|
||||
bdev_io->status = SPDK_BDEV_IO_STATUS_FAILED;
|
||||
}
|
||||
spdk_bdev_free_io(bdev_io);
|
||||
} else {
|
||||
spdk_free(task->rbuf);
|
||||
} else if (task->iov_flags & SPDK_SCSI_TASK_ALLOC_BUFFER) {
|
||||
spdk_free(task->iov.iov_base);
|
||||
}
|
||||
|
||||
task->rbuf = NULL;
|
||||
|
||||
assert(task->owner_task_ctr != NULL);
|
||||
if (*(task->owner_task_ctr) > 0) {
|
||||
*(task->owner_task_ctr) -= 1;
|
||||
@ -122,13 +120,14 @@ 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;
|
||||
if (task->rbuf == NULL) {
|
||||
task->rbuf = spdk_zmalloc(alloc_len, 0, NULL);
|
||||
/* 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;
|
||||
}
|
||||
*data = task->rbuf;
|
||||
memset(task->rbuf, 0, task->alloc_len);
|
||||
task->alloc_len = alloc_len;
|
||||
*data = task->iov.iov_base;
|
||||
memset(task->iov.iov_base, 0, task->alloc_len);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -76,11 +76,9 @@ void
|
||||
spdk_scsi_task_put(struct spdk_scsi_task *task)
|
||||
{
|
||||
g_task_count--;
|
||||
|
||||
if (task->rbuf) {
|
||||
free(task->rbuf);
|
||||
if (task->iov_flags & SPDK_SCSI_TASK_ALLOC_BUFFER) {
|
||||
free(task->iov.iov_base);
|
||||
}
|
||||
|
||||
free(task);
|
||||
}
|
||||
|
||||
@ -98,7 +96,7 @@ spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len,
|
||||
alloc_len = 4096;
|
||||
|
||||
task->alloc_len = alloc_len;
|
||||
*data = task->rbuf;
|
||||
*data = task->iov.iov_base;
|
||||
}
|
||||
|
||||
void spdk_scsi_dev_queue_mgmt_task(struct spdk_scsi_dev *dev,
|
||||
@ -420,7 +418,8 @@ lun_append_task_null_lun_task_cdb_spc_inquiry(void)
|
||||
/* alloc_len >= 4096 */
|
||||
task->cdb[3] = 0xFF;
|
||||
task->cdb[4] = 0xFF;
|
||||
task->rbuf = malloc(65536);
|
||||
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 +445,8 @@ 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->rbuf = malloc(4096);
|
||||
|
||||
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);
|
||||
|
@ -69,7 +69,7 @@ spdk_scsi_task_alloc_data(struct spdk_scsi_task *task, uint32_t alloc_len,
|
||||
}
|
||||
|
||||
task->alloc_len = alloc_len;
|
||||
*data = task->rbuf;
|
||||
*data = task->iov.iov_base;
|
||||
}
|
||||
|
||||
void
|
||||
@ -127,6 +127,14 @@ spdk_bdev_read(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct spdk_bdev_io *
|
||||
spdk_bdev_readv(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
|
||||
struct iovec *iov, int iovcnt, uint64_t offset, uint64_t nbytes,
|
||||
spdk_bdev_io_completion_cb cb, void *cb_arg)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct spdk_bdev_io *
|
||||
spdk_bdev_writev(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
|
||||
struct iovec *iov, int iovcnt,
|
||||
@ -261,7 +269,7 @@ mode_sense_6_test(void)
|
||||
lun.dev = &dev;
|
||||
task.lun = &lun;
|
||||
|
||||
task.rbuf = data;
|
||||
task.iov.iov_base = data;
|
||||
|
||||
rc = spdk_bdev_scsi_execute(&bdev, &task);
|
||||
mode_data_len = data[0];
|
||||
@ -306,7 +314,7 @@ mode_sense_10_test(void)
|
||||
lun.dev = &dev;
|
||||
task.lun = &lun;
|
||||
|
||||
task.rbuf = data;
|
||||
task.iov.iov_base = data;
|
||||
|
||||
rc = spdk_bdev_scsi_execute(&bdev, &task);
|
||||
mode_data_len = ((data[0] << 8) + data[1]);
|
||||
@ -350,7 +358,7 @@ inquiry_evpd_test(void)
|
||||
task.lun = &lun;
|
||||
|
||||
memset(data, 0, 4096);
|
||||
task.rbuf = data;
|
||||
task.iov.iov_base = data;
|
||||
|
||||
rc = spdk_bdev_scsi_execute(&bdev, &task);
|
||||
|
||||
@ -394,7 +402,7 @@ inquiry_standard_test(void)
|
||||
task.lun = &lun;
|
||||
|
||||
memset(data, 0, 4096);
|
||||
task.rbuf = data;
|
||||
task.iov.iov_base = data;
|
||||
|
||||
rc = spdk_bdev_scsi_execute(&bdev, &task);
|
||||
|
||||
@ -433,7 +441,7 @@ _inquiry_overflow_test(uint8_t alloc_len)
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
memset(data_compare, 0, sizeof(data_compare));
|
||||
task.rbuf = data;
|
||||
task.iov.iov_base = data;
|
||||
|
||||
rc = spdk_bdev_scsi_execute(&bdev, &task);
|
||||
CU_ASSERT_EQUAL(rc, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user