diff options
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 4f18a851e2c7..00bc7218a7f8 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -1272,16 +1272,18 @@ static void __scsi_remove_target(struct scsi_target *starget) | |||
1272 | void scsi_remove_target(struct device *dev) | 1272 | void scsi_remove_target(struct device *dev) |
1273 | { | 1273 | { |
1274 | struct Scsi_Host *shost = dev_to_shost(dev->parent); | 1274 | struct Scsi_Host *shost = dev_to_shost(dev->parent); |
1275 | struct scsi_target *starget; | 1275 | struct scsi_target *starget, *last_target = NULL; |
1276 | unsigned long flags; | 1276 | unsigned long flags; |
1277 | 1277 | ||
1278 | restart: | 1278 | restart: |
1279 | spin_lock_irqsave(shost->host_lock, flags); | 1279 | spin_lock_irqsave(shost->host_lock, flags); |
1280 | list_for_each_entry(starget, &shost->__targets, siblings) { | 1280 | list_for_each_entry(starget, &shost->__targets, siblings) { |
1281 | if (starget->state == STARGET_DEL) | 1281 | if (starget->state == STARGET_DEL || |
1282 | starget == last_target) | ||
1282 | continue; | 1283 | continue; |
1283 | if (starget->dev.parent == dev || &starget->dev == dev) { | 1284 | if (starget->dev.parent == dev || &starget->dev == dev) { |
1284 | kref_get(&starget->reap_ref); | 1285 | kref_get(&starget->reap_ref); |
1286 | last_target = starget; | ||
1285 | spin_unlock_irqrestore(shost->host_lock, flags); | 1287 | spin_unlock_irqrestore(shost->host_lock, flags); |
1286 | __scsi_remove_target(starget); | 1288 | __scsi_remove_target(starget); |
1287 | scsi_target_reap(starget); | 1289 | scsi_target_reap(starget); |