diff options
| author | Mike Anderson <andmike@us.ibm.com> | 2005-06-16 14:14:33 -0400 |
|---|---|---|
| committer | James Bottomley <jejb@mulgrave.(none)> | 2005-07-30 12:13:01 -0400 |
| commit | 82f29467a025f6a2192d281e97fca0be46e905cc (patch) | |
| tree | 5cf356ece53caf2936ca85803676b326094f7c38 | |
| parent | d2c9d9eafa03dbd08a8a439e6c5addb8b1f03b9b (diff) | |
[SCSI] host state model update: mediate host add/remove race
Add support to not allow additions to a host when it is being removed.
Signed-off-by: Mike Anderson <andmike@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
| -rw-r--r-- | drivers/scsi/hosts.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/scsi_scan.c | 21 | ||||
| -rw-r--r-- | include/scsi/scsi_host.h | 9 |
3 files changed, 25 insertions, 7 deletions
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 67c4c0c3aa5e..8640ad1c17e2 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
| @@ -133,7 +133,9 @@ EXPORT_SYMBOL(scsi_host_set_state); | |||
| 133 | **/ | 133 | **/ |
| 134 | void scsi_remove_host(struct Scsi_Host *shost) | 134 | void scsi_remove_host(struct Scsi_Host *shost) |
| 135 | { | 135 | { |
| 136 | down(&shost->scan_mutex); | ||
| 136 | scsi_host_set_state(shost, SHOST_CANCEL); | 137 | scsi_host_set_state(shost, SHOST_CANCEL); |
| 138 | up(&shost->scan_mutex); | ||
| 137 | scsi_forget_host(shost); | 139 | scsi_forget_host(shost); |
| 138 | scsi_proc_host_rm(shost); | 140 | scsi_proc_host_rm(shost); |
| 139 | 141 | ||
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 2d3c4ac475f2..076cbe3b5a05 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
| @@ -1251,9 +1251,12 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, | |||
| 1251 | 1251 | ||
| 1252 | get_device(&starget->dev); | 1252 | get_device(&starget->dev); |
| 1253 | down(&shost->scan_mutex); | 1253 | down(&shost->scan_mutex); |
| 1254 | res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); | 1254 | if (scsi_host_scan_allowed(shost)) { |
| 1255 | if (res != SCSI_SCAN_LUN_PRESENT) | 1255 | res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, |
| 1256 | sdev = ERR_PTR(-ENODEV); | 1256 | hostdata); |
| 1257 | if (res != SCSI_SCAN_LUN_PRESENT) | ||
| 1258 | sdev = ERR_PTR(-ENODEV); | ||
| 1259 | } | ||
| 1257 | up(&shost->scan_mutex); | 1260 | up(&shost->scan_mutex); |
| 1258 | scsi_target_reap(starget); | 1261 | scsi_target_reap(starget); |
| 1259 | put_device(&starget->dev); | 1262 | put_device(&starget->dev); |
| @@ -1403,11 +1406,15 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, | |||
| 1403 | return -EINVAL; | 1406 | return -EINVAL; |
| 1404 | 1407 | ||
| 1405 | down(&shost->scan_mutex); | 1408 | down(&shost->scan_mutex); |
| 1406 | if (channel == SCAN_WILD_CARD) | 1409 | if (scsi_host_scan_allowed(shost)) { |
| 1407 | for (channel = 0; channel <= shost->max_channel; channel++) | 1410 | if (channel == SCAN_WILD_CARD) |
| 1411 | for (channel = 0; channel <= shost->max_channel; | ||
| 1412 | channel++) | ||
| 1413 | scsi_scan_channel(shost, channel, id, lun, | ||
| 1414 | rescan); | ||
| 1415 | else | ||
| 1408 | scsi_scan_channel(shost, channel, id, lun, rescan); | 1416 | scsi_scan_channel(shost, channel, id, lun, rescan); |
| 1409 | else | 1417 | } |
| 1410 | scsi_scan_channel(shost, channel, id, lun, rescan); | ||
| 1411 | up(&shost->scan_mutex); | 1418 | up(&shost->scan_mutex); |
| 1412 | 1419 | ||
| 1413 | return 0; | 1420 | return 0; |
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 0b1e275b2699..1ea5b51d1749 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
| @@ -650,6 +650,15 @@ static inline struct device *scsi_get_device(struct Scsi_Host *shost) | |||
| 650 | return shost->shost_gendev.parent; | 650 | return shost->shost_gendev.parent; |
| 651 | } | 651 | } |
| 652 | 652 | ||
| 653 | /** | ||
| 654 | * scsi_host_scan_allowed - Is scanning of this host allowed | ||
| 655 | * @shost: Pointer to Scsi_Host. | ||
| 656 | **/ | ||
| 657 | static inline int scsi_host_scan_allowed(struct Scsi_Host *shost) | ||
| 658 | { | ||
| 659 | return shost->shost_state == SHOST_RUNNING; | ||
| 660 | } | ||
| 661 | |||
| 653 | extern void scsi_unblock_requests(struct Scsi_Host *); | 662 | extern void scsi_unblock_requests(struct Scsi_Host *); |
| 654 | extern void scsi_block_requests(struct Scsi_Host *); | 663 | extern void scsi_block_requests(struct Scsi_Host *); |
| 655 | 664 | ||
