From: Hou Tao houtao1@huawei.com
hulk inclusion category: bugfix bugzilla: 188150, https://gitee.com/openeuler/kernel/issues/I643OL
----------------------------------------
Cancel the inflight async device probe when removing scsi_target, so no new disk will be added when __scsi_target_remove() returns.
Signed-off-by: Hou Tao houtao1@huawei.com Signed-off-by: Zhong Jinghua zhongjinghua@huawei.com Reviewed-by: Hou Tao houtao1@huawei.com Signed-off-by: Jialin Zhang zhangjialin11@huawei.com --- drivers/scsi/scsi_sysfs.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index dc448def9e80..8a24d144395d 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1503,6 +1503,40 @@ void scsi_remove_device(struct scsi_device *sdev) } EXPORT_SYMBOL(scsi_remove_device);
+/* Cancel the inflight async probe for scsi_device */ +static void __scsi_kill_devices(struct scsi_target *starget) +{ + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct scsi_device *sdev, *to_put = NULL; + unsigned long flags; + + spin_lock_irqsave(shost->host_lock, flags); + list_for_each_entry(sdev, &shost->__devices, siblings) { + if (sdev->channel != starget->channel || + sdev->id != starget->id) + continue; + + if ((sdev->sdev_state != SDEV_DEL && + sdev->sdev_state != SDEV_CANCEL) || !sdev->is_visible) + continue; + if (!kobject_get_unless_zero(&sdev->sdev_gendev.kobj)) + continue; + spin_unlock_irqrestore(shost->host_lock, flags); + + if (to_put) + put_device(&to_put->sdev_gendev); + device_lock(&sdev->sdev_gendev); + kill_device(&sdev->sdev_gendev); + device_unlock(&sdev->sdev_gendev); + to_put = sdev; + + spin_lock_irqsave(shost->host_lock, flags); + } + spin_unlock_irqrestore(shost->host_lock, flags); + if (to_put) + put_device(&to_put->sdev_gendev); +} + static void __scsi_remove_target(struct scsi_target *starget) { struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); @@ -1532,6 +1566,8 @@ static void __scsi_remove_target(struct scsi_target *starget) goto restart; } spin_unlock_irqrestore(shost->host_lock, flags); + + __scsi_kill_devices(starget); }
/**