diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 19884370b..23f82b45e 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -3260,7 +3260,7 @@ iscsi_pdu_payload_op_scsi_read(struct spdk_iscsi_conn *conn, struct spdk_iscsi_t if (task->scsi.transfer_len <= SPDK_BDEV_LARGE_BUF_MAX_SIZE) { task->parent = NULL; task->scsi.offset = 0; - task->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, task->scsi.transfer_len); + task->scsi.length = task->scsi.transfer_len; spdk_scsi_task_set_data(&task->scsi, NULL, 0); iscsi_queue_task(conn, task); @@ -3562,31 +3562,32 @@ _iscsi_conn_abort_queued_datain_task(struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *subtask; uint32_t remaining_size; - while (conn->data_in_cnt < MAX_LARGE_DATAIN_PER_CONNECTION) { - assert(task->current_datain_offset <= task->scsi.transfer_len); - /* If any IO is submitted already, abort all subtasks by repetition. */ - 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 = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, 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 if this is the last subtask */ - if (task->current_datain_offset == task->scsi.transfer_len) { - TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); - return 0; - } + if (conn->data_in_cnt >= MAX_LARGE_DATAIN_PER_CONNECTION) { + return -1; } - 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 diff --git a/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c b/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c index 25ee8e903..58097cea1 100644 --- a/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c +++ b/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c @@ -1105,7 +1105,7 @@ static void abort_queued_datain_task_test(void) { struct spdk_iscsi_conn conn = {}; - struct spdk_iscsi_task *task, *task2, *task3; + struct spdk_iscsi_task *task; int rc; TAILQ_INIT(&conn.queued_datain_tasks); @@ -1124,18 +1124,17 @@ abort_queued_datain_task_test(void) rc = _iscsi_conn_abort_queued_datain_task(&conn, task); CU_ASSERT(rc != 0); CU_ASSERT(!TAILQ_EMPTY(&conn.queued_datain_tasks)); - assert(conn.data_in_cnt == MAX_LARGE_DATAIN_PER_CONNECTION); /* havs 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)); - assert(conn.data_in_cnt == 0); + CU_ASSERT(task->current_datain_offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3); - /* Case2: Queue one task, and this task is partially executed, - * and the slot of sub read tasks are full - */ + /* Case2: Queue one task, and this task is partially executed */ + + /* No slots for sub read tasks */ conn.data_in_cnt = MAX_LARGE_DATAIN_PER_CONNECTION; task->scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3; task->current_datain_offset = SPDK_BDEV_LARGE_BUF_MAX_SIZE; @@ -1143,55 +1142,15 @@ abort_queued_datain_task_test(void) rc = _iscsi_conn_abort_queued_datain_task(&conn, task); CU_ASSERT(rc != 0); + CU_ASSERT(!TAILQ_EMPTY(&conn.queued_datain_tasks)); - /* Case3: Queue one task, and this task is partially executed, - * and the slot of sub read tasks is not full. - */ - conn.data_in_cnt = MAX_LARGE_DATAIN_PER_CONNECTION - 2; + /* have slots for sub read tasks */ + conn.data_in_cnt = 0; rc = _iscsi_conn_abort_queued_datain_task(&conn, task); CU_ASSERT(rc == 0); - assert(conn.data_in_cnt == MAX_LARGE_DATAIN_PER_CONNECTION - 2); - CU_ASSERT(TAILQ_EMPTY(&conn.queued_datain_tasks)); - - /* Case4: Queue three tasks and abort each task sequentially */ - conn.data_in_cnt = 0; - - task->tag = 1; - task->scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3; - task->current_datain_offset = 0; - TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task, link); - - task2 = spdk_iscsi_task_get(&conn, NULL, NULL); - SPDK_CU_ASSERT_FATAL(task2 != NULL); - task2->tag = 2; - task2->scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV; - task2->scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 4; - task2->current_datain_offset = SPDK_BDEV_LARGE_BUF_MAX_SIZE; - TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task2, link); - - task3 = spdk_iscsi_task_get(&conn, NULL, NULL); - SPDK_CU_ASSERT_FATAL(task3 != NULL); - task3->tag = 3; - task3->scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV; - task3->scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 5; - task3->current_datain_offset = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 2; - TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, task3, link); - - rc = iscsi_conn_abort_queued_datain_task(&conn, 1); - CU_ASSERT(rc == 0); - - rc = iscsi_conn_abort_queued_datain_task(&conn, 2); - CU_ASSERT(rc == 0); - - rc = iscsi_conn_abort_queued_datain_task(&conn, 3); - CU_ASSERT(rc == 0); - - CU_ASSERT(TAILQ_EMPTY(&conn.queued_datain_tasks)); - assert(conn.data_in_cnt == 0); + CU_ASSERT(task->current_datain_offset == SPDK_BDEV_LARGE_BUF_MAX_SIZE * 3); spdk_iscsi_task_cpl(&task->scsi); - spdk_iscsi_task_cpl(&task2->scsi); - spdk_iscsi_task_cpl(&task3->scsi); } static bool @@ -1233,6 +1192,7 @@ abort_queued_datain_tasks_test(void) 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); @@ -1245,6 +1205,7 @@ abort_queued_datain_tasks_test(void) 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); @@ -1263,6 +1224,7 @@ abort_queued_datain_tasks_test(void) 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); @@ -1275,6 +1237,7 @@ abort_queued_datain_tasks_test(void) 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); @@ -1287,6 +1250,7 @@ abort_queued_datain_tasks_test(void) 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); @@ -1305,6 +1269,7 @@ abort_queued_datain_tasks_test(void) 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);