]> git.baikalelectronics.ru Git - kernel.git/commitdiff
[SCSI] host state model update: mediate host add/remove race
authorMike Anderson <andmike@us.ibm.com>
Thu, 16 Jun 2005 18:14:33 +0000 (11:14 -0700)
committerJames Bottomley <jejb@mulgrave.(none)>
Sat, 30 Jul 2005 16:13:01 +0000 (11:13 -0500)
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>
drivers/scsi/hosts.c
drivers/scsi/scsi_scan.c
include/scsi/scsi_host.h

index 67c4c0c3aa5e6738e36d612e5804f94c6e502dc1..8640ad1c17e286e32a267c938717f5ae716bccbf 100644 (file)
@@ -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);
 
index 2d3c4ac475f233d5cd723331dc117883fb28021d..076cbe3b5a05c994d3e196163b6e39a1a0091bba 100644 (file)
@@ -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;
index 0b1e275b269984f86f5cb15e7357655ea61b9ae0..1ea5b51d17493ace9cd5cdf828cfd7e7e554a442 100644 (file)
@@ -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 *);