Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 316802
b: refs/heads/master
c: 3b661a9
h: refs/heads/master
v: v3
  • Loading branch information
Dan Williams authored and James Bottomley committed Jul 20, 2012
1 parent cdf4ea8 commit 4cab07f
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b5f1758f221e446c5a2956cf7ffdf62b005f6458
refs/heads/master: 3b661a92e869ebe2358de8f4b3230ad84f7fce51
3 changes: 3 additions & 0 deletions trunk/drivers/scsi/scsi_scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1717,6 +1717,9 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
{
struct scsi_device *sdev;
shost_for_each_device(sdev, shost) {
/* target removed before the device could be added */
if (sdev->sdev_state == SDEV_DEL)
continue;
if (!scsi_host_scan_allowed(shost) ||
scsi_sysfs_add_sdev(sdev) != 0)
__scsi_remove_device(sdev);
Expand Down
41 changes: 26 additions & 15 deletions trunk/drivers/scsi/scsi_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,6 @@ static void __scsi_remove_target(struct scsi_target *starget)
struct scsi_device *sdev;

spin_lock_irqsave(shost->host_lock, flags);
starget->reap_ref++;
restart:
list_for_each_entry(sdev, &shost->__devices, siblings) {
if (sdev->channel != starget->channel ||
Expand All @@ -1019,14 +1018,6 @@ static void __scsi_remove_target(struct scsi_target *starget)
goto restart;
}
spin_unlock_irqrestore(shost->host_lock, flags);
scsi_target_reap(starget);
}

static int __remove_child (struct device * dev, void * data)
{
if (scsi_is_target_device(dev))
__scsi_remove_target(to_scsi_target(dev));
return 0;
}

/**
Expand All @@ -1039,14 +1030,34 @@ static int __remove_child (struct device * dev, void * data)
*/
void scsi_remove_target(struct device *dev)
{
if (scsi_is_target_device(dev)) {
__scsi_remove_target(to_scsi_target(dev));
return;
struct Scsi_Host *shost = dev_to_shost(dev->parent);
struct scsi_target *starget, *found;
unsigned long flags;

restart:
found = NULL;
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;
}
}
spin_unlock_irqrestore(shost->host_lock, flags);

get_device(dev);
device_for_each_child(dev, NULL, __remove_child);
put_device(dev);
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;
}
}
EXPORT_SYMBOL(scsi_remove_target);

Expand Down

0 comments on commit 4cab07f

Please sign in to comment.