Commit 20d32d9d authored by Christoph Hellwig's avatar Christoph Hellwig

[PATCH] serialize bus scanning

Synchronize all scanning activity, this fixes long-standing races
vs /proc/scsi/scsi and sysfs addition and deletion of devices.

Note that this does not serialize removing, the lists will get
their own locking soon.
parent f0a47ab7
......@@ -30,6 +30,7 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <asm/semaphore.h>
#include "scsi.h"
#include "hosts.h"
......@@ -94,6 +95,13 @@ MODULE_PARM_DESC(max_report_luns,
" between 1 and 16384)");
#endif
/*
* This mutex serializes all scsi scanning activity from kernel- and
* userspace. It could easily be made per-host but I'd like to avoid
* the overhead for now.
*/
static DECLARE_MUTEX(scsi_scan_mutex);
/**
* scsi_unlock_floptical - unlock device via a special MODE SENSE command
* @sreq: used to send the command
......@@ -1067,9 +1075,12 @@ struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
struct scsi_device *sdev;
int res;
down(&scsi_scan_mutex);
res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev, 1);
if (res != SCSI_SCAN_LUN_PRESENT)
sdev = ERR_PTR(-ENODEV);
up(&scsi_scan_mutex);
return sdev;
}
......@@ -1191,11 +1202,14 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
return -EINVAL;
down(&scsi_scan_mutex);
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);
up(&scsi_scan_mutex);
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment