From 1f6a78620d1f4b7470ccf5ff378fd2eb6cf49c5f Mon Sep 17 00:00:00 2001 From: Ziye Yang Date: Thu, 11 Oct 2018 19:22:32 +0800 Subject: [PATCH] iscsi: fix the iSCSI connection issue for lun hotplug Only calling spdk_clear_all_transfer_task cannot solve all the hotplug issue. The iSCSI task may successfully return and own the bdev buffer inside the iSCSI task, so we need to call this flush pdu function. Change-Id: I255173d0880334e8acccc980a4ce04c380f64435 Signed-off-by: Ziye Yang Reviewed-on: https://review.gerrithub.io/428801 Tested-by: SPDK CI Jenkins Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/iscsi/conn.c | 49 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/lib/iscsi/conn.c b/lib/iscsi/conn.c index 5cbc8dc73..5ab3c41dd 100644 --- a/lib/iscsi/conn.c +++ b/lib/iscsi/conn.c @@ -622,15 +622,55 @@ spdk_iscsi_conn_close_luns(struct spdk_iscsi_conn *conn) } } +static void +_iscsi_conn_remove_lun(void *arg1, void *arg2) +{ + struct spdk_iscsi_conn *conn = arg1; + struct spdk_scsi_lun *lun = arg2; + int lun_id = spdk_scsi_lun_get_id(lun); + struct spdk_iscsi_pdu *pdu, *tmp_pdu; + struct spdk_iscsi_task *iscsi_task, *tmp_iscsi_task; + + /* If a connection is already in stating status, just return */ + if (conn->state >= ISCSI_CONN_STATE_EXITING) { + return; + } + + spdk_clear_all_transfer_task(conn, lun); + TAILQ_FOREACH_SAFE(pdu, &conn->write_pdu_list, tailq, tmp_pdu) { + if (pdu->task && (lun == pdu->task->scsi.lun)) { + TAILQ_REMOVE(&conn->write_pdu_list, pdu, tailq); + spdk_iscsi_conn_free_pdu(conn, pdu); + } + } + + TAILQ_FOREACH_SAFE(pdu, &conn->snack_pdu_list, tailq, tmp_pdu) { + if (pdu->task && (lun == pdu->task->scsi.lun)) { + TAILQ_REMOVE(&conn->snack_pdu_list, pdu, tailq); + spdk_iscsi_task_put(pdu->task); + spdk_put_pdu(pdu); + } + } + + TAILQ_FOREACH_SAFE(iscsi_task, &conn->queued_datain_tasks, link, tmp_iscsi_task) { + if ((!iscsi_task->is_queued) && (lun == iscsi_task->scsi.lun)) { + TAILQ_REMOVE(&conn->queued_datain_tasks, iscsi_task, link); + spdk_iscsi_task_put(iscsi_task); + } + } + + spdk_iscsi_conn_close_lun(conn, lun_id); +} + static void spdk_iscsi_conn_remove_lun(struct spdk_scsi_lun *lun, void *remove_ctx) { struct spdk_iscsi_conn *conn = remove_ctx; - int lun_id = spdk_scsi_lun_get_id(lun); + struct spdk_event *event; - spdk_clear_all_transfer_task(conn, lun); - - spdk_iscsi_conn_close_lun(conn, lun_id); + event = spdk_event_allocate(conn->lcore, _iscsi_conn_remove_lun, + conn, lun); + spdk_event_call(event); } static void @@ -1308,6 +1348,7 @@ spdk_iscsi_conn_migration(struct spdk_iscsi_conn *conn) } spdk_iscsi_poll_group_remove_conn_sock(conn); + spdk_poller_unregister(&conn->flush_poller); spdk_iscsi_conn_stop(conn); __sync_fetch_and_add(&g_num_connections[lcore], 1);