Commit 4d440529 authored by Hou Tao's avatar Hou Tao Committed by Jialin Zhang
Browse files

scsi: cancel the inflight async device probe when remove scsi_target

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: default avatarHou Tao <houtao1@huawei.com>
Signed-off-by: default avatarZhong Jinghua <zhongjinghua@huawei.com>
Reviewed-by: default avatarHou Tao <houtao1@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parent 746a0963
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -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);
}

/**