diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 42db9c52208e60ff1a834ffc170645da845b68cb..dc448def9e806cc1a2f9d99fb7abd4744dcc4b5e 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1556,7 +1556,16 @@ void scsi_remove_target(struct device *dev) starget->state == STARGET_CREATED_REMOVE) continue; if (starget->dev.parent == dev || &starget->dev == dev) { - kref_get(&starget->reap_ref); + /* + * If the reference count is already zero, skip + * this target. Calling kref_get_unless_zero() if + * the reference count is zero is safe because + * scsi_target_destroy() will wait until the host + * lock has been released before freeing starget. + */ + if (!kref_get_unless_zero(&starget->reap_ref)) + continue; + if (starget->state == STARGET_CREATED) starget->state = STARGET_CREATED_REMOVE; else