diff --git a/lib/iscsi/conn.c b/lib/iscsi/conn.c index d23f7826d..215463dc7 100644 --- a/lib/iscsi/conn.c +++ b/lib/iscsi/conn.c @@ -930,6 +930,47 @@ spdk_iscsi_drop_conns(struct spdk_iscsi_conn *conn, const char *conn_match, return 0; } +int +spdk_iscsi_conn_handle_queued_datain_tasks(struct spdk_iscsi_conn *conn) +{ + struct spdk_iscsi_task *task; + + while (!TAILQ_EMPTY(&conn->queued_datain_tasks) && + conn->data_in_cnt < MAX_LARGE_DATAIN_PER_CONNECTION) { + task = TAILQ_FIRST(&conn->queued_datain_tasks); + assert(task->current_datain_offset <= task->scsi.transfer_len); + if (task->current_datain_offset < task->scsi.transfer_len) { + struct spdk_iscsi_task *subtask; + uint32_t remaining_size = 0; + + 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; + spdk_scsi_task_set_data(&subtask->scsi, NULL, 0); + + if (spdk_scsi_dev_get_lun(conn->dev, task->lun_id) == NULL) { + /* Stop submitting split read I/Os for remaining data. */ + TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); + task->current_datain_offset += remaining_size; + assert(task->current_datain_offset == task->scsi.transfer_len); + subtask->scsi.transfer_len = remaining_size; + spdk_scsi_task_process_null_lun(&subtask->scsi); + spdk_iscsi_task_cpl(&subtask->scsi); + return 0; + } + + subtask->scsi.length = spdk_min(SPDK_BDEV_LARGE_BUF_MAX_SIZE, remaining_size); + task->current_datain_offset += subtask->scsi.length; + spdk_iscsi_queue_task(conn, subtask); + } + if (task->current_datain_offset == task->scsi.transfer_len) { + TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); + } + } + return 0; +} + void spdk_iscsi_task_mgmt_cpl(struct spdk_scsi_task *scsi_task) { diff --git a/lib/iscsi/conn.h b/lib/iscsi/conn.h index d8b8f96fd..1b3a4fd67 100644 --- a/lib/iscsi/conn.h +++ b/lib/iscsi/conn.h @@ -216,6 +216,7 @@ void spdk_iscsi_conn_schedule(struct spdk_iscsi_conn *conn); 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_read_data(struct spdk_iscsi_conn *conn, int len, void *buf); int spdk_iscsi_conn_readv_data(struct spdk_iscsi_conn *conn, diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 32bc5e9dd..c1041bcad 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -3211,46 +3211,6 @@ spdk_iscsi_queue_task(struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task spdk_scsi_dev_queue_task(conn->dev, &task->scsi); } -int spdk_iscsi_conn_handle_queued_datain_tasks(struct spdk_iscsi_conn *conn) -{ - struct spdk_iscsi_task *task; - - while (!TAILQ_EMPTY(&conn->queued_datain_tasks) && - conn->data_in_cnt < MAX_LARGE_DATAIN_PER_CONNECTION) { - task = TAILQ_FIRST(&conn->queued_datain_tasks); - assert(task->current_datain_offset <= task->scsi.transfer_len); - if (task->current_datain_offset < task->scsi.transfer_len) { - struct spdk_iscsi_task *subtask; - uint32_t remaining_size = 0; - - 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; - spdk_scsi_task_set_data(&subtask->scsi, NULL, 0); - - if (spdk_scsi_dev_get_lun(conn->dev, task->lun_id) == NULL) { - /* Stop submitting split read I/Os for remaining data. */ - TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); - task->current_datain_offset += remaining_size; - assert(task->current_datain_offset == task->scsi.transfer_len); - subtask->scsi.transfer_len = remaining_size; - spdk_scsi_task_process_null_lun(&subtask->scsi); - spdk_iscsi_task_cpl(&subtask->scsi); - return 0; - } - - subtask->scsi.length = spdk_min(SPDK_BDEV_LARGE_BUF_MAX_SIZE, remaining_size); - task->current_datain_offset += subtask->scsi.length; - spdk_iscsi_queue_task(conn, subtask); - } - if (task->current_datain_offset == task->scsi.transfer_len) { - TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); - } - } - return 0; -} - static int iscsi_pdu_payload_op_scsi_read(struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task) { diff --git a/test/unit/lib/iscsi/conn.c/conn_ut.c b/test/unit/lib/iscsi/conn.c/conn_ut.c index 5142243a5..b9116994d 100644 --- a/test/unit/lib/iscsi/conn.c/conn_ut.c +++ b/test/unit/lib/iscsi/conn.c/conn_ut.c @@ -101,6 +101,10 @@ 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); + void spdk_scsi_task_put(struct spdk_scsi_task *scsi_task) { @@ -146,6 +150,10 @@ spdk_scsi_task_copy_status(struct spdk_scsi_task *dst, dst->status = src->status; } +DEFINE_STUB_V(spdk_scsi_task_set_data, (struct spdk_scsi_task *task, void *data, uint32_t len)); + +DEFINE_STUB_V(spdk_scsi_task_process_null_lun, (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)); @@ -161,6 +169,9 @@ DEFINE_STUB(spdk_iscsi_build_iovs, int, struct spdk_iscsi_pdu *pdu, uint32_t *mapped_length), 0); +DEFINE_STUB_V(spdk_iscsi_queue_task, + (struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task)); + DEFINE_STUB_V(spdk_iscsi_task_response, (struct spdk_iscsi_conn *conn, struct spdk_iscsi_task *task)); @@ -172,21 +183,6 @@ DEFINE_STUB_V(spdk_iscsi_send_nopin, (struct spdk_iscsi_conn *conn)); DEFINE_STUB(spdk_del_transfer_task, bool, (struct spdk_iscsi_conn *conn, uint32_t task_tag), true); -int -spdk_iscsi_conn_handle_queued_datain_tasks(struct spdk_iscsi_conn *conn) -{ - struct spdk_iscsi_task *task, *tmp; - - TAILQ_FOREACH_SAFE(task, &conn->queued_datain_tasks, link, tmp) { - TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); - if (task->pdu) { - TAILQ_INSERT_TAIL(&conn->write_pdu_list, task->pdu, tailq); - } - } - - return 0; -} - DEFINE_STUB(spdk_iscsi_handle_incoming_pdus, int, (struct spdk_iscsi_conn *conn), 0); DEFINE_STUB_V(spdk_free_sess, (struct spdk_iscsi_sess *sess)); @@ -571,6 +567,7 @@ free_tasks_on_connection(void) TAILQ_INIT(&conn.write_pdu_list); TAILQ_INIT(&conn.snack_pdu_list); TAILQ_INIT(&conn.queued_datain_tasks); + conn.data_in_cnt = MAX_LARGE_DATAIN_PER_CONNECTION; pdu1.task = &task1; pdu2.task = &task2; diff --git a/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c b/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c index 4844b69da..0b0b93557 100644 --- a/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c +++ b/test/unit/lib/iscsi/iscsi.c/iscsi_ut.c @@ -94,6 +94,9 @@ DEFINE_STUB_V(spdk_iscsi_conn_schedule, (struct spdk_iscsi_conn *conn)); DEFINE_STUB_V(spdk_iscsi_conn_free_pdu, (struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)); +DEFINE_STUB(spdk_iscsi_conn_handle_queued_datain_tasks, int, + (struct spdk_iscsi_conn *conn), 0); + DEFINE_STUB(spdk_iscsi_chap_get_authinfo, int, (struct iscsi_chap_auth *auth, const char *authuser, int ag_tag), 0);