Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82f29467 authored by Mike Anderson's avatar Mike Anderson Committed by James Bottomley
Browse files

[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: default avatarMike Anderson <andmike@us.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent d2c9d9ea
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);

+14 −7
Original line number Diff line number Diff line
@@ -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 (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 (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);
			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(&shost->scan_mutex);

	return 0;
+9 −0
Original line number Diff line number Diff line
@@ -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 *);