Commit 1f6a7862 authored by Ziye Yang's avatar Ziye Yang Committed by Ben Walker
Browse files

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: default avatarZiye Yang <ziye.yang@intel.com>
Reviewed-on: https://review.gerrithub.io/428801


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent ac5aa208
Loading
Loading
Loading
Loading
+43 −2
Original line number Diff line number Diff line
@@ -623,16 +623,56 @@ spdk_iscsi_conn_close_luns(struct spdk_iscsi_conn *conn)
}

static void
spdk_iscsi_conn_remove_lun(struct spdk_scsi_lun *lun, void *remove_ctx)
_iscsi_conn_remove_lun(void *arg1, void *arg2)
{
	struct spdk_iscsi_conn *conn = remove_ctx;
	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;
	struct spdk_event *event;

	event = spdk_event_allocate(conn->lcore, _iscsi_conn_remove_lun,
				    conn, lun);
	spdk_event_call(event);
}

static void
spdk_iscsi_conn_open_luns(struct spdk_iscsi_conn *conn)
{
@@ -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);