From 82f29467a025f6a2192d281e97fca0be46e905cc Mon Sep 17 00:00:00 2001 From: Mike Anderson Date: Thu, 16 Jun 2005 11:14:33 -0700 Subject: [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 Signed-off-by: James Bottomley --- drivers/scsi/hosts.c | 2 ++ drivers/scsi/scsi_scan.c | 21 ++++++++++++++------- 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); **/ void scsi_remove_host(struct Scsi_Host *shost) { + down(&shost->scan_mutex); scsi_host_set_state(shost, SHOST_CANCEL); + up(&shost->scan_mutex); scsi_forget_host(shost); scsi_proc_host_rm(shost); 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, get_device(&starget->dev); down(&shost->scan_mutex); - res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); - if (res != SCSI_SCAN_LUN_PRESENT) - sdev = ERR_PTR(-ENODEV); + if (scsi_host_scan_allowed(shost)) { + res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, + hostdata); + if (res != SCSI_SCAN_LUN_PRESENT) + sdev = ERR_PTR(-ENODEV); + } up(&shost->scan_mutex); scsi_target_reap(starget); put_device(&starget->dev); @@ -1403,11 +1406,15 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, return -EINVAL; down(&shost->scan_mutex); - if (channel == SCAN_WILD_CARD) - for (channel = 0; channel <= shost->max_channel; channel++) + if (scsi_host_scan_allowed(shost)) { + if (channel == SCAN_WILD_CARD) + for (channel = 0; channel <= shost->max_channel; + channel++) + scsi_scan_channel(shost, channel, id, lun, + rescan); + else scsi_scan_channel(shost, channel, id, lun, rescan); - else - scsi_scan_channel(shost, channel, id, lun, rescan); + } up(&shost->scan_mutex); 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) return shost->shost_gendev.parent; } +/** + * scsi_host_scan_allowed - Is scanning of this host allowed + * @shost: Pointer to Scsi_Host. + **/ +static inline int scsi_host_scan_allowed(struct Scsi_Host *shost) +{ + return shost->shost_state == SHOST_RUNNING; +} + extern void scsi_unblock_requests(struct Scsi_Host *); extern void scsi_block_requests(struct Scsi_Host *); -- cgit v1.2.3