From db91cfe04518750dd0dc998eb1d850b8c16fa67f Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Fri, 8 Nov 2019 08:17:35 +0900 Subject: [PATCH] lib/scsi: Stop submitting new task and abort pending tasks for LUN hotplug Previously iSCSI LUN hotplug had critical bugs and we had no choice but accept submitting new tasks as late as possible. We fixed the bug now and we can stop submitting new task immediately after starting LUN removal process. By this change, no task is submitted to the LUN and previously queued tasks have no chance to be kicked. Hence we execute them instead after stopping new task submission. This change simplifies LUN hotplug process and reproduce LUN hotplug issues solidly if we don't have the fix. Signed-off-by: Shuhei Matsumoto Change-Id: I9a33e6a217978b0863d15aaff3d35880dbdccfd4 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/473596 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/scsi/dev.c | 10 +++++++++- lib/scsi/lun.c | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/scsi/dev.c b/lib/scsi/dev.c index 8857d7d1a..8ab5f4ad3 100644 --- a/lib/scsi/dev.c +++ b/lib/scsi/dev.c @@ -411,11 +411,19 @@ spdk_scsi_dev_get_id(const struct spdk_scsi_dev *dev) struct spdk_scsi_lun * spdk_scsi_dev_get_lun(struct spdk_scsi_dev *dev, int lun_id) { + struct spdk_scsi_lun *lun; + if (lun_id < 0 || lun_id >= SPDK_SCSI_DEV_MAX_LUN) { return NULL; } - return dev->lun[lun_id]; + lun = dev->lun[lun_id]; + + if (lun != NULL && !spdk_scsi_lun_is_removing(lun)) { + return lun; + } else { + return NULL; + } } bool diff --git a/lib/scsi/lun.c b/lib/scsi/lun.c index c4d0f6b38..feb502882 100644 --- a/lib/scsi/lun.c +++ b/lib/scsi/lun.c @@ -326,6 +326,14 @@ _scsi_lun_hot_remove(void *arg1) { struct spdk_scsi_lun *lun = arg1; + /* If lun->removed is set, no new task can be submitted to the LUN. + * Execute previously queued tasks, which will be immediately aborted. + */ + scsi_lun_execute_tasks(lun); + + /* Then we only need to wait for all outstanding tasks to be completed + * before notifying the upper layer about the removal. + */ if (scsi_lun_has_pending_tasks(lun) || scsi_lun_has_pending_mgmt_tasks(lun)) { lun->hotremove_poller = spdk_poller_register(scsi_lun_check_pending_tasks,