From 8eba104b732e8a02dc357a34c07fcf6d37b1cea2 Mon Sep 17 00:00:00 2001 From: Cunyin Chang Date: Sun, 30 Jul 2017 20:21:38 +0800 Subject: [PATCH] iscsi: Fix the bug for hotplug when read IO is running. after move the spdk_iscsi_conn_handle_queued_tasks() into spdk_iscsi_conn_execute(), we should handle the situation when the lun has been removed and then try to access spdk_iscsi_conn_handle_queued_tasks(). Change-Id: I9ac7a5203b49274347c9ee9fbf19558ca87557ed Signed-off-by: Cunyin Chang Reviewed-on: https://review.gerrithub.io/371813 Reviewed-by: Ben Walker Tested-by: SPDK Automated Test System Reviewed-by: Jim Harris --- include/spdk/scsi.h | 5 +++++ lib/iscsi/iscsi.c | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/include/spdk/scsi.h b/include/spdk/scsi.h index 477f48e1a..1a3d50db9 100644 --- a/include/spdk/scsi.h +++ b/include/spdk/scsi.h @@ -94,6 +94,11 @@ struct spdk_scsi_task { uint8_t status; uint8_t function; /* task mgmt function */ uint8_t response; /* task mgmt response */ + /** + * Record the lun id just in case the lun is invalid, + * which will happen when hot remove the lun. + */ + int lun_id; struct spdk_scsi_lun *lun; struct spdk_bdev_desc *desc; struct spdk_io_channel *ch; diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 42b388a80..46dfeeb21 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -2862,6 +2862,13 @@ int spdk_iscsi_conn_handle_queued_tasks(struct spdk_iscsi_conn *conn) assert(task->current_datain_offset <= task->scsi.transfer_len); if (task->current_datain_offset == 0) { + task->scsi.lun = spdk_scsi_dev_get_lun(conn->dev, task->scsi.lun_id); + if (task->scsi.lun == NULL) { + TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); + spdk_scsi_task_process_null_lun(&task->scsi); + spdk_iscsi_task_cpl(&task->scsi); + return 0; + } task->current_datain_offset = task->scsi.length; conn->data_in_cnt++; spdk_iscsi_queue_task(conn, task); @@ -2877,9 +2884,18 @@ int spdk_iscsi_conn_handle_queued_tasks(struct spdk_iscsi_conn *conn) subtask->scsi.offset = task->current_datain_offset; subtask->scsi.length = DMIN32(SPDK_BDEV_LARGE_BUF_MAX_SIZE, remaining_size); spdk_scsi_task_set_data(&subtask->scsi, NULL, 0); - spdk_iscsi_queue_task(conn, subtask); task->current_datain_offset += subtask->scsi.length; conn->data_in_cnt++; + + task->scsi.lun = spdk_scsi_dev_get_lun(conn->dev, task->scsi.lun_id); + if (task->scsi.lun == NULL) { + subtask->scsi.transfer_len = subtask->scsi.length; + spdk_scsi_task_process_null_lun(&subtask->scsi); + spdk_iscsi_task_cpl(&subtask->scsi); + return 0; + } + + spdk_iscsi_queue_task(conn, subtask); } if (task->current_datain_offset == task->scsi.transfer_len) { TAILQ_REMOVE(&conn->queued_datain_tasks, task, link); @@ -2951,6 +2967,7 @@ spdk_iscsi_op_scsi(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) spdk_iscsi_task_associate_pdu(task, pdu); lun_i = spdk_islun2lun(lun); + task->scsi.lun_id = lun_i; dev = conn->dev; task->scsi.lun = spdk_scsi_dev_get_lun(dev, lun_i);