From a2ffc4c7ef7d5bc8b3e8358e09cdd6d403bbc760 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 28 Aug 2012 22:12:10 -0700 Subject: [PATCH] --- yaml --- r: 328925 b: refs/heads/master c: bc3f02a795d3b4faa99d37390174be2a75d091bd h: refs/heads/master i: 328923: ad9d0566b6aeb08378840e7a6f8477c0ab8958a3 v: v3 --- [refs] | 2 +- trunk/drivers/scsi/scsi_sysfs.c | 30 ++++++++++++++---------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/[refs] b/[refs] index ea1c0bf863a9..6cb6e9d3e541 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 225c56960fcafeccc2b6304f96cd3f0dbf42a16a +refs/heads/master: bc3f02a795d3b4faa99d37390174be2a75d091bd diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c index 093d4f6a54d2..ce5224c92eda 100644 --- a/trunk/drivers/scsi/scsi_sysfs.c +++ b/trunk/drivers/scsi/scsi_sysfs.c @@ -1031,33 +1031,31 @@ static void __scsi_remove_target(struct scsi_target *starget) void scsi_remove_target(struct device *dev) { struct Scsi_Host *shost = dev_to_shost(dev->parent); - struct scsi_target *starget, *found; + struct scsi_target *starget, *last = NULL; unsigned long flags; - restart: - found = NULL; + /* remove targets being careful to lookup next entry before + * deleting the last + */ spin_lock_irqsave(shost->host_lock, flags); list_for_each_entry(starget, &shost->__targets, siblings) { if (starget->state == STARGET_DEL) continue; if (starget->dev.parent == dev || &starget->dev == dev) { - found = starget; - found->reap_ref++; - break; + /* assuming new targets arrive at the end */ + starget->reap_ref++; + spin_unlock_irqrestore(shost->host_lock, flags); + if (last) + scsi_target_reap(last); + last = starget; + __scsi_remove_target(starget); + spin_lock_irqsave(shost->host_lock, flags); } } spin_unlock_irqrestore(shost->host_lock, flags); - if (found) { - __scsi_remove_target(found); - scsi_target_reap(found); - /* in the case where @dev has multiple starget children, - * continue removing. - * - * FIXME: does such a case exist? - */ - goto restart; - } + if (last) + scsi_target_reap(last); } EXPORT_SYMBOL(scsi_remove_target);