diff --git a/lib/iscsi/conn.c b/lib/iscsi/conn.c index 7c727ddbb..f88ce79e1 100644 --- a/lib/iscsi/conn.c +++ b/lib/iscsi/conn.c @@ -302,11 +302,22 @@ error_return: void spdk_iscsi_conn_free_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) { + iscsi_conn_xfer_complete_cb cb_fn; + void *cb_arg; + + cb_fn = pdu->cb_fn; + cb_arg = pdu->cb_arg; + + assert(cb_fn != NULL); + pdu->cb_fn = NULL; + if (pdu->task) { spdk_iscsi_task_put(pdu->task); spdk_iscsi_conn_handle_queued_datain_tasks(conn); } spdk_put_pdu(pdu); + + cb_fn(cb_arg); } static int @@ -791,7 +802,7 @@ iscsi_send_logout_request(struct spdk_iscsi_conn *conn) to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN); to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN); - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); } static int @@ -1254,7 +1265,7 @@ iscsi_conn_send_nopin(struct spdk_iscsi_conn *conn) to_be32(&rsp->stat_sn, conn->StatSN); to_be32(&rsp->exp_cmd_sn, conn->sess->ExpCmdSN); to_be32(&rsp->max_cmd_sn, conn->sess->MaxCmdSN); - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); conn->last_nopin = spdk_get_ticks(); conn->nop_outstanding = true; } @@ -1448,7 +1459,9 @@ _iscsi_conn_pdu_write_done(void *cb_arg, int err) } void -spdk_iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) +spdk_iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu, + iscsi_conn_xfer_complete_cb cb_fn, + void *cb_arg) { uint32_t crc32c; ssize_t rc; @@ -1476,6 +1489,8 @@ spdk_iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *p } } + pdu->cb_fn = cb_fn; + pdu->cb_arg = cb_arg; TAILQ_INSERT_TAIL(&conn->write_pdu_list, pdu, tailq); if (spdk_unlikely(conn->state >= ISCSI_CONN_STATE_EXITING)) { diff --git a/lib/iscsi/conn.h b/lib/iscsi/conn.h index dd7a10add..857568e2d 100644 --- a/lib/iscsi/conn.h +++ b/lib/iscsi/conn.h @@ -225,9 +225,12 @@ int spdk_iscsi_conn_abort_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, struct iovec *iov, int iovcnt); -void spdk_iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu); +void spdk_iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu, + iscsi_conn_xfer_complete_cb cb_fn, + void *cb_arg); void spdk_iscsi_conn_free_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu); void spdk_iscsi_conn_info_json(struct spdk_json_write_ctx *w, struct spdk_iscsi_conn *conn); +void spdk_iscsi_conn_pdu_generic_complete(void *cb_arg); #endif /* SPDK_ISCSI_CONN_H */ diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 76646f7c2..d0a677b34 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -208,6 +208,11 @@ hex2bin(uint8_t *data, size_t data_len, const char *str) return total; } +void +spdk_iscsi_conn_pdu_generic_complete(void *cb_arg) +{ +} + static int iscsi_reject(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu, int reason) @@ -287,7 +292,7 @@ iscsi_reject(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu, SPDK_LOGDUMP(SPDK_LOG_ISCSI, "PDU", (void *)&rsp_pdu->bhs, ISCSI_BHS_LEN); - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); return 0; } @@ -1129,7 +1134,7 @@ iscsi_op_login_response(struct spdk_iscsi_conn *conn, rsph->flags &= ~ISCSI_LOGIN_CURRENT_STAGE_MASK; rsph->flags &= ~ISCSI_LOGIN_NEXT_STAGE_MASK; } - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); /* after send PDU digest on/off */ if (conn->full_feature) { @@ -2411,7 +2416,7 @@ iscsi_pdu_payload_op_text(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *p to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN); to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN); - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); /* update internal variables */ rc = spdk_iscsi_copy_param2var(conn); @@ -2523,7 +2528,7 @@ iscsi_pdu_hdr_op_logout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu rsph->time_2_wait = 0; rsph->time_2_retain = 0; - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); if (conn->sess == NULL) { /* @@ -2604,7 +2609,7 @@ iscsi_send_r2t(struct spdk_iscsi_conn *conn, rsp_pdu->task = task; task->scsi.ref++; - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); return 0; } @@ -2657,7 +2662,7 @@ iscsi_send_r2t_recovery(struct spdk_iscsi_conn *conn, */ if (!send_new_r2tsn) { to_be32(&pdu->bhs.stat_sn, conn->StatSN); - spdk_iscsi_conn_write_pdu(conn, pdu); + spdk_iscsi_conn_write_pdu(conn, pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); } else { rsph = (struct iscsi_bhs_r2t *)&pdu->bhs; transfer_len = from_be32(&rsph->desired_xfer_len); @@ -2978,7 +2983,7 @@ iscsi_send_datain(struct spdk_iscsi_conn *conn, } } - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); return DataSN; } @@ -3174,7 +3179,7 @@ void spdk_iscsi_task_response(struct spdk_iscsi_conn *conn, to_be32(&rsph->bi_read_res_cnt, 0); to_be32(&rsph->res_cnt, residual_len); - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); } /* @@ -3509,7 +3514,7 @@ spdk_iscsi_task_mgmt_response(struct spdk_iscsi_conn *conn, to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN); to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN); - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); } static void @@ -3826,7 +3831,7 @@ iscsi_pdu_payload_op_nopout(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu to_be32(&rsph->exp_cmd_sn, conn->sess->ExpCmdSN); to_be32(&rsph->max_cmd_sn, conn->sess->MaxCmdSN); - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); conn->last_nopin = spdk_get_ticks(); return 0; @@ -3963,7 +3968,7 @@ iscsi_handle_recovery_datain(struct spdk_iscsi_conn *conn, if (from_be32(&datain_header->itt) == task_tag && from_be32(&datain_header->data_sn) == i) { TAILQ_REMOVE(&conn->snack_pdu_list, old_pdu, tailq); - spdk_iscsi_conn_write_pdu(conn, old_pdu); + spdk_iscsi_conn_write_pdu(conn, old_pdu, old_pdu->cb_fn, old_pdu->cb_arg); break; } } @@ -4020,7 +4025,7 @@ iscsi_handle_status_snack(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *p beg_run); } else { TAILQ_REMOVE(&conn->snack_pdu_list, old_pdu, tailq); - spdk_iscsi_conn_write_pdu(conn, old_pdu); + spdk_iscsi_conn_write_pdu(conn, old_pdu, old_pdu->cb_fn, old_pdu->cb_arg); } } @@ -4475,7 +4480,7 @@ iscsi_pdu_hdr_handle(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) return SPDK_ISCSI_CONNECTION_FATAL; } init_login_reject_response(pdu, rsp_pdu); - spdk_iscsi_conn_write_pdu(conn, rsp_pdu); + spdk_iscsi_conn_write_pdu(conn, rsp_pdu, spdk_iscsi_conn_pdu_generic_complete, NULL); SPDK_ERRLOG("Received opcode %d in login phase\n", opcode); return SPDK_ISCSI_LOGIN_ERROR_RESPONSE; } else if (conn->state == ISCSI_CONN_STATE_INVALID) { diff --git a/lib/iscsi/iscsi.h b/lib/iscsi/iscsi.h index 101be4829..044f6043d 100644 --- a/lib/iscsi/iscsi.h +++ b/lib/iscsi/iscsi.h @@ -168,6 +168,8 @@ struct spdk_mobj { */ #define SPDK_ISCSI_MAX_SGL_DESCRIPTORS (5) +typedef void (*iscsi_conn_xfer_complete_cb)(void *cb_arg); + struct spdk_iscsi_pdu { struct iscsi_bhs bhs; struct spdk_mobj *mobj; @@ -192,6 +194,9 @@ struct spdk_iscsi_pdu { struct spdk_dif_ctx dif_ctx; struct spdk_iscsi_conn *conn; + iscsi_conn_xfer_complete_cb cb_fn; + void *cb_arg; + /* The sock request ends with a 0 length iovec. Place the actual iovec immediately * after it. There is a static assert below to check if the compiler inserted * any unwanted padding */ diff --git a/test/unit/lib/iscsi/common.c b/test/unit/lib/iscsi/common.c index 206b7ad2b..f97c9a50f 100644 --- a/test/unit/lib/iscsi/common.c +++ b/test/unit/lib/iscsi/common.c @@ -190,7 +190,8 @@ DEFINE_STUB(spdk_iscsi_conn_readv_data, int, (struct spdk_iscsi_conn *conn, struct iovec *iov, int iovcnt), 0); void -spdk_iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) +spdk_iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu, + iscsi_conn_xfer_complete_cb cb_fn, void *cb_arg) { TAILQ_INSERT_TAIL(&g_write_pdu_list, pdu, tailq); } diff --git a/test/unit/lib/iscsi/conn.c/conn_ut.c b/test/unit/lib/iscsi/conn.c/conn_ut.c index b076c084d..54ad34848 100644 --- a/test/unit/lib/iscsi/conn.c/conn_ut.c +++ b/test/unit/lib/iscsi/conn.c/conn_ut.c @@ -540,6 +540,10 @@ dequeue_task(void *_head, struct spdk_iscsi_task *task) return false; } +static void iscsi_conn_pdu_dummy_complete(void *arg) +{ +} + static void free_tasks_on_connection(void) { @@ -557,6 +561,11 @@ free_tasks_on_connection(void) pdu2.task = &task2; pdu3.task = &task3; + pdu1.cb_fn = iscsi_conn_pdu_dummy_complete; + pdu2.cb_fn = iscsi_conn_pdu_dummy_complete; + pdu3.cb_fn = iscsi_conn_pdu_dummy_complete; + pdu4.cb_fn = iscsi_conn_pdu_dummy_complete; + task1.scsi.lun = &lun1; task2.scsi.lun = &lun2; @@ -587,6 +596,9 @@ free_tasks_on_connection(void) task1.scsi.ref = 1; task2.scsi.ref = 1; task3.scsi.ref = 1; + pdu1.cb_fn = iscsi_conn_pdu_dummy_complete; + pdu2.cb_fn = iscsi_conn_pdu_dummy_complete; + pdu3.cb_fn = iscsi_conn_pdu_dummy_complete; TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu1, tailq); TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu2, tailq); TAILQ_INSERT_TAIL(&conn.snack_pdu_list, &pdu3, tailq); @@ -635,6 +647,9 @@ free_tasks_with_queued_datain(void) pdu1.task = &task1; pdu2.task = &task2; pdu3.task = &task3; + pdu1.cb_fn = iscsi_conn_pdu_dummy_complete; + pdu2.cb_fn = iscsi_conn_pdu_dummy_complete; + pdu3.cb_fn = iscsi_conn_pdu_dummy_complete; task1.scsi.ref = 1; task2.scsi.ref = 1; @@ -655,6 +670,9 @@ free_tasks_with_queued_datain(void) task4.pdu = &pdu4; task5.pdu = &pdu5; task6.pdu = &pdu6; + pdu4.cb_fn = iscsi_conn_pdu_dummy_complete; + pdu5.cb_fn = iscsi_conn_pdu_dummy_complete; + pdu6.cb_fn = iscsi_conn_pdu_dummy_complete; TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task4, link); TAILQ_INSERT_TAIL(&conn.queued_datain_tasks, &task5, link);