lib/iscsi: Move iscsi_conn_abort_queued_datain_task() from iscsi.c to conn.c

Followin the last patch, move iscsi_conn_abort_queued_datain_task()
and iscsi_conn_abort_queued_datain_tasks() from iscsi.c to conn.c.

Refine unit tests to check more accurately. Adding more test cases
will be done later.

Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I30530e6871a78a58d9fb472f62168862298884a0
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/477417
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Shuhei Matsumoto 2019-12-11 01:07:53 -05:00 committed by Tomasz Zawadzki
parent ff001eb93f
commit f29c728980
5 changed files with 322 additions and 289 deletions

View File

@ -930,6 +930,79 @@ spdk_iscsi_drop_conns(struct spdk_iscsi_conn *conn, const char *conn_match,
return 0;
}
static int
_iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn,
struct spdk_iscsi_task *task)
{
struct spdk_iscsi_task *subtask;
uint32_t remaining_size;
if (conn->data_in_cnt >= MAX_LARGE_DATAIN_PER_CONNECTION) {
return -1;
}
assert(task->current_datain_offset <= task->scsi.transfer_len);
/* Stop split and abort read I/O for remaining data. */
if (task->current_datain_offset < task->scsi.transfer_len) {
remaining_size = task->scsi.transfer_len - task->current_datain_offset;
subtask = spdk_iscsi_task_get(conn, task, spdk_iscsi_task_cpl);
assert(subtask != NULL);
subtask->scsi.offset = task->current_datain_offset;
subtask->scsi.length = remaining_size;
spdk_scsi_task_set_data(&subtask->scsi, NULL, 0);
task->current_datain_offset += subtask->scsi.length;
subtask->scsi.transfer_len = subtask->scsi.length;
spdk_scsi_task_process_abort(&subtask->scsi);
spdk_iscsi_task_cpl(&subtask->scsi);
}
/* Remove the primary task from the list because all subtasks are submitted
* or aborted.
*/
assert(task->current_datain_offset == task->scsi.transfer_len);
TAILQ_REMOVE(&conn->queued_datain_tasks, task, link);
return 0;
}
int
spdk_iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn,
uint32_t ref_task_tag)
{
struct spdk_iscsi_task *task;
TAILQ_FOREACH(task, &conn->queued_datain_tasks, link) {
if (task->tag == ref_task_tag) {
return _iscsi_conn_abort_queued_datain_task(conn, task);
}
}
return 0;
}
int
spdk_iscsi_conn_abort_queued_datain_tasks(struct spdk_iscsi_conn *conn,
struct spdk_scsi_lun *lun,
struct spdk_iscsi_pdu *pdu)
{
struct spdk_iscsi_task *task, *task_tmp;
struct spdk_iscsi_pdu *pdu_tmp;
int rc;
TAILQ_FOREACH_SAFE(task, &conn->queued_datain_tasks, link, task_tmp) {
pdu_tmp = spdk_iscsi_task_get_pdu(task);
if ((lun == NULL || lun == task->scsi.lun) &&
(pdu == NULL || (SN32_LT(pdu_tmp->cmd_sn, pdu->cmd_sn)))) {
rc = _iscsi_conn_abort_queued_datain_task(conn, task);
if (rc != 0) {
return rc;
}
}
}
return 0;
}
int
spdk_iscsi_conn_handle_queued_datain_tasks(struct spdk_iscsi_conn *conn)
{

View File

@ -217,6 +217,11 @@ void spdk_iscsi_conn_logout(struct spdk_iscsi_conn *conn);
int spdk_iscsi_drop_conns(struct spdk_iscsi_conn *conn,
const char *conn_match, int drop_all);
int spdk_iscsi_conn_handle_queued_datain_tasks(struct spdk_iscsi_conn *conn);
int spdk_iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn,
uint32_t ref_task_tag);
int spdk_iscsi_conn_abort_queued_datain_tasks(struct spdk_iscsi_conn *conn,
struct spdk_scsi_lun *lun,
struct spdk_iscsi_pdu *pdu);
int spdk_iscsi_conn_read_data(struct spdk_iscsi_conn *conn, int len, void *buf);
int spdk_iscsi_conn_readv_data(struct spdk_iscsi_conn *conn,

View File

@ -3512,79 +3512,6 @@ spdk_iscsi_task_mgmt_response(struct spdk_iscsi_conn *conn,
spdk_iscsi_conn_write_pdu(conn, rsp_pdu);
}
static int
_iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn,
struct spdk_iscsi_task *task)
{
struct spdk_iscsi_task *subtask;
uint32_t remaining_size;
if (conn->data_in_cnt >= MAX_LARGE_DATAIN_PER_CONNECTION) {
return -1;
}
assert(task->current_datain_offset <= task->scsi.transfer_len);
/* Stop split and abort read I/O for remaining data. */
if (task->current_datain_offset < task->scsi.transfer_len) {
remaining_size = task->scsi.transfer_len - task->current_datain_offset;
subtask = spdk_iscsi_task_get(conn, task, spdk_iscsi_task_cpl);
assert(subtask != NULL);
subtask->scsi.offset = task->current_datain_offset;
subtask->scsi.length = remaining_size;
spdk_scsi_task_set_data(&subtask->scsi, NULL, 0);
task->current_datain_offset += subtask->scsi.length;
subtask->scsi.transfer_len = subtask->scsi.length;
spdk_scsi_task_process_abort(&subtask->scsi);
spdk_iscsi_task_cpl(&subtask->scsi);
}
/* Remove the primary task from the list because all subtasks are submitted
* or aborted.
*/
assert(task->current_datain_offset == task->scsi.transfer_len);
TAILQ_REMOVE(&conn->queued_datain_tasks, task, link);
return 0;
}
static int
iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn,
uint32_t ref_task_tag)
{
struct spdk_iscsi_task *task;
TAILQ_FOREACH(task, &conn->queued_datain_tasks, link) {
if (task->tag == ref_task_tag) {
return _iscsi_conn_abort_queued_datain_task(conn, task);
}
}
return 0;
}
static int
iscsi_conn_abort_queued_datain_tasks(struct spdk_iscsi_conn *conn,
struct spdk_scsi_lun *lun,
struct spdk_iscsi_pdu *pdu)
{
struct spdk_iscsi_task *task, *task_tmp;
struct spdk_iscsi_pdu *pdu_tmp;
int rc;
TAILQ_FOREACH_SAFE(task, &conn->queued_datain_tasks, link, task_tmp) {
pdu_tmp = spdk_iscsi_task_get_pdu(task);
if ((lun == NULL || lun == task->scsi.lun) &&
(pdu == NULL || (SN32_LT(pdu_tmp->cmd_sn, pdu->cmd_sn)))) {
rc = _iscsi_conn_abort_queued_datain_task(conn, task);
if (rc != 0) {
return rc;
}
}
}
return 0;
}
static void
iscsi_queue_mgmt_task(struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task)
{
@ -3607,7 +3534,7 @@ _iscsi_op_abort_task(void *arg)
struct spdk_iscsi_task *task = arg;
int rc;
rc = iscsi_conn_abort_queued_datain_task(task->conn, task->scsi.abort_id);
rc = spdk_iscsi_conn_abort_queued_datain_task(task->conn, task->scsi.abort_id);
if (rc != 0) {
return 1;
}
@ -3631,7 +3558,7 @@ _iscsi_op_abort_task_set(void *arg)
struct spdk_iscsi_task *task = arg;
int rc;
rc = iscsi_conn_abort_queued_datain_tasks(task->conn, task->scsi.lun,
rc = spdk_iscsi_conn_abort_queued_datain_tasks(task->conn, task->scsi.lun,
task->pdu);
if (rc != 0) {
return 1;

View File

@ -59,6 +59,7 @@ struct spdk_scsi_lun {
struct spdk_iscsi_globals g_spdk_iscsi;
static TAILQ_HEAD(read_tasks_head, spdk_iscsi_task) g_ut_read_tasks =
TAILQ_HEAD_INITIALIZER(g_ut_read_tasks);
static struct spdk_iscsi_task *g_new_task = NULL;
static ssize_t g_sock_writev_bytes = 0;
DEFINE_STUB(spdk_app_get_shm_id, int, (void), 0);
@ -101,9 +102,35 @@ DEFINE_STUB(spdk_sock_group_add_sock, int,
DEFINE_STUB(spdk_sock_group_remove_sock, int,
(struct spdk_sock_group *group, struct spdk_sock *sock), 0);
DEFINE_STUB(spdk_iscsi_task_get, struct spdk_iscsi_task *,
(struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *parent,
spdk_scsi_task_cpl cpl_fn), NULL);
struct spdk_iscsi_task *
spdk_iscsi_task_get(struct spdk_iscsi_conn *conn,
struct spdk_iscsi_task *parent,
spdk_scsi_task_cpl cpl_fn)
{
struct spdk_iscsi_task *task;
task = g_new_task;
if (task == NULL) {
return NULL;
}
memset(task, 0, sizeof(*task));
task->scsi.ref = 1;
task->conn = conn;
task->scsi.cpl_fn = cpl_fn;
if (parent) {
parent->scsi.ref++;
task->parent = parent;
task->scsi.dxfer_dir = parent->scsi.dxfer_dir;
task->scsi.transfer_len = parent->scsi.transfer_len;
task->scsi.lun = parent->scsi.lun;
if (conn && (task->scsi.dxfer_dir == SPDK_SCSI_DIR_FROM_DEV)) {
conn->data_in_cnt++;
}
}
return task;
}
void
spdk_scsi_task_put(struct spdk_scsi_task *scsi_task)
@ -154,6 +181,8 @@ DEFINE_STUB_V(spdk_scsi_task_set_data, (struct spdk_scsi_task *task, void *data,
DEFINE_STUB_V(spdk_scsi_task_process_null_lun, (struct spdk_scsi_task *task));
DEFINE_STUB_V(spdk_scsi_task_process_abort, (struct spdk_scsi_task *task));
DEFINE_STUB_V(spdk_put_pdu, (struct spdk_iscsi_pdu *pdu));
DEFINE_STUB_V(spdk_iscsi_param_free, (struct iscsi_param *params));
@ -682,6 +711,206 @@ free_tasks_with_queued_datain(void)
CU_ASSERT(TAILQ_EMPTY(&conn.queued_datain_tasks));
}
static void
abort_queued_datain_task_test(void)
{
struct spdk_iscsi_conn conn = {};
struct spdk_iscsi_task task = {}, subtask = {};
struct spdk_iscsi_pdu pdu = {};
struct iscsi_bhs_scsi_req *scsi_req;
int rc;
TAILQ_INIT(&conn.queued_datain_tasks);
task.scsi.ref = 1;
task.scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV;
task.pdu = &pdu;
TAILQ_INIT(&task.subtask_list);
scsi_req = (struct iscsi_bhs_scsi_req *)&pdu.bhs;
scsi_req->read_bit = 1;
g_new_task = &subtask;
/* Case1: Queue one task, and this task is not executed */
task.scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3;
task.scsi.offset = 0;
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task, link);
/* No slots for sub read tasks */
conn.data_in_cnt = MAX_LARGE_DATAIN_PER_CONNECTION;
rc = _iscsi_conn_abort_queued_datain_task(&conn, &task);
CU_ASSERT(rc != 0);
CU_ASSERT(!TAILQ_EMPTY(&conn.queued_datain_tasks));
/* Have slots for sub read tasks */
conn.data_in_cnt = 0;
rc = _iscsi_conn_abort_queued_datain_task(&conn, &task);
CU_ASSERT(rc == 0);
CU_ASSERT(TAILQ_EMPTY(&conn.queued_datain_tasks));
CU_ASSERT(task.current_datain_offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3);
CU_ASSERT(task.scsi.ref == 0);
CU_ASSERT(subtask.scsi.offset == 0);
CU_ASSERT(subtask.scsi.length == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3);
CU_ASSERT(subtask.scsi.ref == 0);
/* Case2: Queue one task, and this task is partially executed */
task.scsi.ref = 1;
task.scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3;
task.current_datain_offset = SPDK_BDEV_LARGE_BUF_MAX_SIZE;
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task, link);
/* No slots for sub read tasks */
conn.data_in_cnt = MAX_LARGE_DATAIN_PER_CONNECTION;
rc = _iscsi_conn_abort_queued_datain_task(&conn, &task);
CU_ASSERT(rc != 0);
CU_ASSERT(!TAILQ_EMPTY(&conn.queued_datain_tasks));
/* have slots for sub read tasks */
conn.data_in_cnt = 0;
rc = _iscsi_conn_abort_queued_datain_task(&conn, &task);
CU_ASSERT(rc == 0);
CU_ASSERT(task.current_datain_offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3);
CU_ASSERT(task.scsi.ref == 2);
CU_ASSERT(TAILQ_FIRST(&task.subtask_list) == &subtask);
CU_ASSERT(subtask.scsi.offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE);
CU_ASSERT(subtask.scsi.length == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 2);
CU_ASSERT(subtask.scsi.ref == 1);
g_new_task = NULL;
}
static bool
datain_task_is_queued(struct spdk_iscsi_conn *conn,
struct spdk_iscsi_task *task)
{
struct spdk_iscsi_task *tmp;
TAILQ_FOREACH(tmp, &conn->queued_datain_tasks, link) {
if (tmp == task) {
return true;
}
}
return false;
}
static void
abort_queued_datain_tasks_test(void)
{
struct spdk_iscsi_conn conn = {};
struct spdk_iscsi_task task1 = {}, task2 = {}, task3 = {}, task4 = {}, task5 = {}, task6 = {};
struct spdk_iscsi_task subtask = {};
struct spdk_iscsi_pdu pdu1 = {}, pdu2 = {}, pdu3 = {}, pdu4 = {}, pdu5 = {}, pdu6 = {};
struct spdk_iscsi_pdu mgmt_pdu1 = {}, mgmt_pdu2 = {};
struct spdk_scsi_lun lun1 = {}, lun2 = {};
uint32_t alloc_cmd_sn;
struct iscsi_bhs_scsi_req *scsi_req;
int rc;
TAILQ_INIT(&conn.queued_datain_tasks);
conn.data_in_cnt = 0;
g_new_task = &subtask;
alloc_cmd_sn = 88;
pdu1.cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
scsi_req = (struct iscsi_bhs_scsi_req *)&pdu1.bhs;
scsi_req->read_bit = 1;
task1.scsi.ref = 1;
task1.current_datain_offset = 0;
task1.scsi.transfer_len = 512;
task1.scsi.lun = &lun1;
spdk_iscsi_task_set_pdu(&task1, &pdu1);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task1, link);
pdu2.cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
scsi_req = (struct iscsi_bhs_scsi_req *)&pdu2.bhs;
scsi_req->read_bit = 1;
task2.scsi.ref = 1;
task2.current_datain_offset = 0;
task2.scsi.transfer_len = 512;
task2.scsi.lun = &lun2;
spdk_iscsi_task_set_pdu(&task2, &pdu2);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task2, link);
mgmt_pdu1.cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
pdu3.cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
scsi_req = (struct iscsi_bhs_scsi_req *)&pdu3.bhs;
scsi_req->read_bit = 1;
task3.scsi.ref = 1;
task3.current_datain_offset = 0;
task3.scsi.transfer_len = 512;
task3.scsi.lun = &lun1;
spdk_iscsi_task_set_pdu(&task3, &pdu3);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task3, link);
pdu4.cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
scsi_req = (struct iscsi_bhs_scsi_req *)&pdu4.bhs;
scsi_req->read_bit = 1;
task4.scsi.ref = 1;
task4.current_datain_offset = 0;
task4.scsi.transfer_len = 512;
task4.scsi.lun = &lun2;
spdk_iscsi_task_set_pdu(&task4, &pdu4);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task4, link);
pdu5.cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
scsi_req = (struct iscsi_bhs_scsi_req *)&pdu5.bhs;
scsi_req->read_bit = 1;
task5.scsi.ref = 1;
task5.current_datain_offset = 0;
task5.scsi.transfer_len = 512;
task5.scsi.lun = &lun1;
spdk_iscsi_task_set_pdu(&task5, &pdu5);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task5, link);
mgmt_pdu2.cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
pdu6.cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
scsi_req = (struct iscsi_bhs_scsi_req *)&pdu6.bhs;
scsi_req->read_bit = 1;
task6.scsi.ref = 1;
task6.current_datain_offset = 0;
task6.scsi.transfer_len = 512;
task6.scsi.lun = &lun2;
spdk_iscsi_task_set_pdu(&task6, &pdu6);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task6, link);
rc = spdk_iscsi_conn_abort_queued_datain_tasks(&conn, &lun1, &mgmt_pdu1);
CU_ASSERT(rc == 0);
CU_ASSERT(!datain_task_is_queued(&conn, &task1));
CU_ASSERT(datain_task_is_queued(&conn, &task2));
CU_ASSERT(datain_task_is_queued(&conn, &task3));
CU_ASSERT(datain_task_is_queued(&conn, &task4));
CU_ASSERT(datain_task_is_queued(&conn, &task5));
CU_ASSERT(datain_task_is_queued(&conn, &task6));
rc = spdk_iscsi_conn_abort_queued_datain_tasks(&conn, &lun2, &mgmt_pdu2);
CU_ASSERT(rc == 0);
CU_ASSERT(!datain_task_is_queued(&conn, &task2));
CU_ASSERT(datain_task_is_queued(&conn, &task3));
CU_ASSERT(!datain_task_is_queued(&conn, &task4));
CU_ASSERT(datain_task_is_queued(&conn, &task5));
CU_ASSERT(datain_task_is_queued(&conn, &task6));
CU_ASSERT(task1.scsi.ref == 0);
CU_ASSERT(task2.scsi.ref == 0);
CU_ASSERT(task3.scsi.ref == 1);
CU_ASSERT(task4.scsi.ref == 0);
CU_ASSERT(task5.scsi.ref == 1);
CU_ASSERT(task6.scsi.ref == 1);
CU_ASSERT(subtask.scsi.ref == 0);
g_new_task = NULL;
}
int
main(int argc, char **argv)
{
@ -708,7 +937,9 @@ main(int argc, char **argv)
process_non_read_task_completion_test) == NULL ||
CU_add_test(suite, "recursive_flush_pdus_calls", recursive_flush_pdus_calls) == NULL ||
CU_add_test(suite, "free_tasks_on_connection", free_tasks_on_connection) == NULL ||
CU_add_test(suite, "free_tasks_with_queued_datain", free_tasks_with_queued_datain) == NULL
CU_add_test(suite, "free_tasks_with_queued_datain", free_tasks_with_queued_datain) == NULL ||
CU_add_test(suite, "abort_queued_datain_task_test", abort_queued_datain_task_test) == NULL ||
CU_add_test(suite, "abort_queued_datain_tasks_test", abort_queued_datain_tasks_test) == NULL
) {
CU_cleanup_registry();
return CU_get_error();

View File

@ -97,6 +97,13 @@ DEFINE_STUB_V(spdk_iscsi_conn_free_pdu,
DEFINE_STUB(spdk_iscsi_conn_handle_queued_datain_tasks, int,
(struct spdk_iscsi_conn *conn), 0);
DEFINE_STUB(spdk_iscsi_conn_abort_queued_datain_task, int,
(struct spdk_iscsi_conn *conn, uint32_t ref_task_tag), 0);
DEFINE_STUB(spdk_iscsi_conn_abort_queued_datain_tasks, int,
(struct spdk_iscsi_conn *conn, struct spdk_scsi_lun *lun,
struct spdk_iscsi_pdu *pdu), 0);
DEFINE_STUB(spdk_iscsi_chap_get_authinfo, int,
(struct iscsi_chap_auth *auth, const char *authuser, int ag_tag),
0);
@ -1052,212 +1059,6 @@ clear_all_transfer_tasks_test(void)
spdk_put_pdu(pdu1);
}
static void
abort_queued_datain_task_test(void)
{
struct spdk_iscsi_conn conn = {};
struct spdk_iscsi_task *task;
int rc;
TAILQ_INIT(&conn.queued_datain_tasks);
task = spdk_iscsi_task_get(&conn, NULL, NULL);
SPDK_CU_ASSERT_FATAL(task != NULL);
task->scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV;
/* Case1: Queue one task, and this task is not executed */
task->scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3;
task->scsi.offset = 0;
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task, link);
/* No slots for sub read tasks */
conn.data_in_cnt = MAX_LARGE_DATAIN_PER_CONNECTION;
rc = _iscsi_conn_abort_queued_datain_task(&conn, task);
CU_ASSERT(rc != 0);
CU_ASSERT(!TAILQ_EMPTY(&conn.queued_datain_tasks));
/* Have slots for sub read tasks */
conn.data_in_cnt = 0;
rc = _iscsi_conn_abort_queued_datain_task(&conn, task);
CU_ASSERT(rc == 0);
CU_ASSERT(TAILQ_EMPTY(&conn.queued_datain_tasks));
CU_ASSERT(task->current_datain_offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3);
/* Case2: Queue one task, and this task is partially executed */
task->scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3;
task->current_datain_offset = SPDK_BDEV_LARGE_BUF_MAX_SIZE;
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task, link);
/* No slots for sub read tasks */
conn.data_in_cnt = MAX_LARGE_DATAIN_PER_CONNECTION;
rc = _iscsi_conn_abort_queued_datain_task(&conn, task);
CU_ASSERT(rc != 0);
CU_ASSERT(!TAILQ_EMPTY(&conn.queued_datain_tasks));
/* have slots for sub read tasks */
conn.data_in_cnt = 0;
rc = _iscsi_conn_abort_queued_datain_task(&conn, task);
CU_ASSERT(rc == 0);
CU_ASSERT(task->current_datain_offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3);
spdk_iscsi_task_cpl(&task->scsi);
}
static bool
datain_task_is_queued(struct spdk_iscsi_conn *conn,
struct spdk_iscsi_task *task)
{
struct spdk_iscsi_task *tmp;
TAILQ_FOREACH(tmp, &conn->queued_datain_tasks, link) {
if (tmp == task) {
return true;
}
}
return false;
}
static void
abort_queued_datain_tasks_test(void)
{
struct spdk_iscsi_conn conn = {};
struct spdk_iscsi_task *task1, *task2, *task3, *task4, *task5, *task6;
struct spdk_iscsi_task *task, *tmp;
struct spdk_iscsi_pdu *pdu1, *pdu2, *pdu3, *pdu4, *pdu5, *pdu6;
struct spdk_iscsi_pdu *mgmt_pdu1, *mgmt_pdu2;
struct spdk_scsi_lun lun1 = {}, lun2 = {};
uint32_t alloc_cmd_sn;
int rc;
TAILQ_INIT(&conn.queued_datain_tasks);
conn.data_in_cnt = 0;
alloc_cmd_sn = 88;
task1 = spdk_iscsi_task_get(&conn, NULL, NULL);
SPDK_CU_ASSERT_FATAL(task1 != NULL);
pdu1 = spdk_get_pdu();
SPDK_CU_ASSERT_FATAL(pdu1 != NULL);
pdu1->cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
task1->current_datain_offset = 0;
task1->scsi.transfer_len = 512;
task1->scsi.lun = &lun1;
spdk_iscsi_task_set_pdu(task1, pdu1);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task1, link);
task2 = spdk_iscsi_task_get(&conn, NULL, NULL);
SPDK_CU_ASSERT_FATAL(task2 != NULL);
pdu2 = spdk_get_pdu();
SPDK_CU_ASSERT_FATAL(pdu2 != NULL);
pdu2->cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
task2->current_datain_offset = 0;
task2->scsi.transfer_len = 512;
task2->scsi.lun = &lun2;
spdk_iscsi_task_set_pdu(task2, pdu2);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task2, link);
mgmt_pdu1 = spdk_get_pdu();
SPDK_CU_ASSERT_FATAL(mgmt_pdu1 != NULL);
mgmt_pdu1->cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
task3 = spdk_iscsi_task_get(&conn, NULL, NULL);
SPDK_CU_ASSERT_FATAL(task3 != NULL);
pdu3 = spdk_get_pdu();
SPDK_CU_ASSERT_FATAL(pdu3 != NULL);
pdu3->cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
task3->current_datain_offset = 0;
task3->scsi.transfer_len = 512;
task3->scsi.lun = &lun1;
spdk_iscsi_task_set_pdu(task3, pdu3);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task3, link);
task4 = spdk_iscsi_task_get(&conn, NULL, NULL);
SPDK_CU_ASSERT_FATAL(task4 != NULL);
pdu4 = spdk_get_pdu();
SPDK_CU_ASSERT_FATAL(pdu4 != NULL);
pdu4->cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
task4->current_datain_offset = 0;
task4->scsi.transfer_len = 512;
task4->scsi.lun = &lun2;
spdk_iscsi_task_set_pdu(task4, pdu4);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task4, link);
task5 = spdk_iscsi_task_get(&conn, NULL, NULL);
SPDK_CU_ASSERT_FATAL(task5 != NULL);
pdu5 = spdk_get_pdu();
SPDK_CU_ASSERT_FATAL(pdu5 != NULL);
pdu5->cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
task5->current_datain_offset = 0;
task5->scsi.transfer_len = 512;
task5->scsi.lun = &lun1;
spdk_iscsi_task_set_pdu(task5, pdu5);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task5, link);
mgmt_pdu2 = spdk_get_pdu();
SPDK_CU_ASSERT_FATAL(mgmt_pdu2 != NULL);
mgmt_pdu2->cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
task6 = spdk_iscsi_task_get(&conn, NULL, NULL);
SPDK_CU_ASSERT_FATAL(task6 != NULL);
pdu6 = spdk_get_pdu();
SPDK_CU_ASSERT_FATAL(pdu6 != NULL);
pdu6->cmd_sn = alloc_cmd_sn;
alloc_cmd_sn++;
task6->current_datain_offset = 0;
task6->scsi.transfer_len = 512;
task6->scsi.lun = &lun2;
spdk_iscsi_task_set_pdu(task6, pdu6);
TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task6, link);
rc = iscsi_conn_abort_queued_datain_tasks(&conn, &lun1, mgmt_pdu1);
CU_ASSERT(rc == 0);
CU_ASSERT(!datain_task_is_queued(&conn, task1));
CU_ASSERT(datain_task_is_queued(&conn, task2));
CU_ASSERT(datain_task_is_queued(&conn, task3));
CU_ASSERT(datain_task_is_queued(&conn, task4));
CU_ASSERT(datain_task_is_queued(&conn, task5));
CU_ASSERT(datain_task_is_queued(&conn, task6));
spdk_iscsi_task_cpl(&task1->scsi);
rc = iscsi_conn_abort_queued_datain_tasks(&conn, &lun2, mgmt_pdu2);
CU_ASSERT(rc == 0);
CU_ASSERT(!datain_task_is_queued(&conn, task2));
CU_ASSERT(datain_task_is_queued(&conn, task3));
CU_ASSERT(!datain_task_is_queued(&conn, task4));
CU_ASSERT(datain_task_is_queued(&conn, task5));
CU_ASSERT(datain_task_is_queued(&conn, task6));
spdk_iscsi_task_cpl(&task2->scsi);
spdk_iscsi_task_cpl(&task4->scsi);
TAILQ_FOREACH_SAFE(task, &conn.queued_datain_tasks, link, tmp) {
TAILQ_REMOVE(&conn.queued_datain_tasks, task, link);
spdk_iscsi_task_cpl(&task->scsi);
}
spdk_put_pdu(mgmt_pdu2);
spdk_put_pdu(mgmt_pdu1);
spdk_put_pdu(pdu6);
spdk_put_pdu(pdu5);
spdk_put_pdu(pdu4);
spdk_put_pdu(pdu3);
spdk_put_pdu(pdu2);
spdk_put_pdu(pdu1);
}
static void
build_iovs_test(void)
{
@ -2195,10 +1996,6 @@ main(int argc, char **argv)
|| CU_add_test(suite, "del transfer task test", del_transfer_task_test) == NULL
|| CU_add_test(suite, "clear all transfer tasks test",
clear_all_transfer_tasks_test) == NULL
|| CU_add_test(suite, "abort_queued_datain_task_test",
abort_queued_datain_task_test) == NULL
|| CU_add_test(suite, "abort_queued_datain_tasks_test",
abort_queued_datain_tasks_test) == NULL
|| CU_add_test(suite, "build_iovs_test", build_iovs_test) == NULL
|| CU_add_test(suite, "build_iovs_with_md_test", build_iovs_with_md_test) == NULL
|| CU_add_test(suite, "pdu_hdr_op_login_test", pdu_hdr_op_login_test) == NULL