diff --git a/lib/iscsi/conn.c b/lib/iscsi/conn.c index 4b12e56ccb..b303771cb3 100644 --- a/lib/iscsi/conn.c +++ b/lib/iscsi/conn.c @@ -1096,8 +1096,8 @@ iscsi_task_copy_from_rsp_scsi_status(struct spdk_scsi_task *task, } static void -process_completed_read_subtask_list(struct spdk_iscsi_conn *conn, - struct spdk_iscsi_task *primary) +process_completed_read_subtask_list_in_order(struct spdk_iscsi_conn *conn, + struct spdk_iscsi_task *primary) { struct spdk_iscsi_task *subtask, *tmp; @@ -1105,7 +1105,7 @@ process_completed_read_subtask_list(struct spdk_iscsi_conn *conn, if (subtask->scsi.offset == primary->bytes_completed) { TAILQ_REMOVE(&primary->subtask_list, subtask, subtask_link); primary->bytes_completed += subtask->scsi.length; - if (primary->bytes_completed == primary->scsi.transfer_len) { + if (primary->bytes_completed == primary->scsi.transfer_len) { iscsi_task_put(primary); } iscsi_task_response(conn, subtask); @@ -1148,7 +1148,15 @@ process_read_task_completion(struct spdk_iscsi_conn *conn, assert(primary->bytes_completed == task->scsi.transfer_len); iscsi_task_response(conn, task); iscsi_task_put(task); + } else if (!conn->sess->DataSequenceInOrder) { + primary->bytes_completed += task->scsi.length; + if (primary->bytes_completed == primary->scsi.transfer_len) { + iscsi_task_put(primary); + } + iscsi_task_response(conn, task); + iscsi_task_put(task); } else { + if (task->scsi.offset != primary->bytes_completed) { TAILQ_FOREACH(tmp, &primary->subtask_list, subtask_link) { if (task->scsi.offset < tmp->scsi.offset) { @@ -1160,7 +1168,7 @@ process_read_task_completion(struct spdk_iscsi_conn *conn, TAILQ_INSERT_TAIL(&primary->subtask_list, task, subtask_link); } else { TAILQ_INSERT_HEAD(&primary->subtask_list, task, subtask_link); - process_completed_read_subtask_list(conn, primary); + process_completed_read_subtask_list_in_order(conn, primary); } } } diff --git a/test/unit/lib/iscsi/conn.c/conn_ut.c b/test/unit/lib/iscsi/conn.c/conn_ut.c index 5e92df2a81..c9979fc5fb 100644 --- a/test/unit/lib/iscsi/conn.c/conn_ut.c +++ b/test/unit/lib/iscsi/conn.c/conn_ut.c @@ -308,6 +308,11 @@ read_task_split_in_order_case(void) { struct spdk_iscsi_task primary = {}; struct spdk_iscsi_task *task, *tmp; + struct spdk_iscsi_conn conn = {}; + struct spdk_iscsi_sess sess = {}; + + conn.sess = &sess; + conn.sess->DataSequenceInOrder = true; primary.scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 8; TAILQ_INIT(&primary.subtask_list); @@ -320,7 +325,7 @@ read_task_split_in_order_case(void) TAILQ_FOREACH(task, &g_ut_read_tasks, link) { CU_ASSERT(&primary == iscsi_task_get_primary(task)); - process_read_task_completion(NULL, task, &primary); + process_read_task_completion(&conn, task, &primary); } CU_ASSERT(primary.bytes_completed == primary.scsi.transfer_len); @@ -339,6 +344,11 @@ read_task_split_reverse_order_case(void) { struct spdk_iscsi_task primary = {}; struct spdk_iscsi_task *task, *tmp; + struct spdk_iscsi_conn conn = {}; + struct spdk_iscsi_sess sess = {}; + + conn.sess = &sess; + conn.sess->DataSequenceInOrder = true; primary.scsi.transfer_len = SPDK_BDEV_LARGE_BUF_MAX_SIZE * 8; TAILQ_INIT(&primary.subtask_list); @@ -351,7 +361,7 @@ read_task_split_reverse_order_case(void) TAILQ_FOREACH_REVERSE(task, &g_ut_read_tasks, read_tasks_head, link) { CU_ASSERT(&primary == iscsi_task_get_primary(task)); - process_read_task_completion(NULL, task, &primary); + process_read_task_completion(&conn, task, &primary); } CU_ASSERT(primary.bytes_completed == primary.scsi.transfer_len); @@ -370,6 +380,12 @@ propagate_scsi_error_status_for_split_read_tasks(void) struct spdk_iscsi_task primary = {}; struct spdk_iscsi_task task1 = {}, task2 = {}, task3 = {}, task4 = {}, task5 = {}, task6 = {}; + struct spdk_iscsi_conn conn = {}; + struct spdk_iscsi_sess sess = {}; + + conn.sess = &sess; + conn.sess->DataSequenceInOrder = true; + primary.scsi.transfer_len = 512 * 6; primary.rsp_scsi_status = SPDK_SCSI_STATUS_GOOD; TAILQ_INIT(&primary.subtask_list); @@ -415,12 +431,12 @@ propagate_scsi_error_status_for_split_read_tasks(void) * status is propagated to remaining tasks correctly when these tasks complete * by the following order, task4, task3, task2, task1, primary, task5, and task6. */ - process_read_task_completion(NULL, &task4, &primary); - process_read_task_completion(NULL, &task3, &primary); - process_read_task_completion(NULL, &task2, &primary); - process_read_task_completion(NULL, &task1, &primary); - process_read_task_completion(NULL, &task5, &primary); - process_read_task_completion(NULL, &task6, &primary); + process_read_task_completion(&conn, &task4, &primary); + process_read_task_completion(&conn, &task3, &primary); + process_read_task_completion(&conn, &task2, &primary); + process_read_task_completion(&conn, &task1, &primary); + process_read_task_completion(&conn, &task5, &primary); + process_read_task_completion(&conn, &task6, &primary); CU_ASSERT(primary.rsp_scsi_status == SPDK_SCSI_STATUS_CHECK_CONDITION); CU_ASSERT(task1.scsi.status == SPDK_SCSI_STATUS_CHECK_CONDITION); @@ -725,6 +741,11 @@ abort_queued_datain_task_test(void) struct iscsi_bhs_scsi_req *scsi_req; int rc; + struct spdk_iscsi_sess sess = {}; + + conn.sess = &sess; + conn.sess->DataSequenceInOrder = true; + TAILQ_INIT(&conn.queued_datain_tasks); task.scsi.ref = 1; task.scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV; @@ -808,10 +829,14 @@ abort_queued_datain_tasks_test(void) uint32_t alloc_cmd_sn; struct iscsi_bhs_scsi_req *scsi_req; int rc; + struct spdk_iscsi_sess sess = {}; TAILQ_INIT(&conn.queued_datain_tasks); conn.data_in_cnt = 0; + conn.sess = &sess; + conn.sess->DataSequenceInOrder = true; + g_new_task = &subtask; alloc_cmd_sn = 88;