Commit 8fb2ef89 authored by Mike Christie's avatar Mike Christie Committed by James Bottomley
Browse files

[SCSI] fc class: fix scanning when devs are offline



When a rport is added back or the role is changed the fc class
will queue a scan and then call scsi_target_unblock. The problem
with this is if the devices are in the SDEV_OFFLINE state and
the scan is run before the scsi_target_unblock, then the scan
will see LUN0 as offline and the scan will fail. This patch moves
the unblock call to before the scan, so we know the device state
will be set correctly when the scan is run.

Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 7c018a90
Loading
Loading
Loading
Loading
+14 −10
Original line number Diff line number Diff line
@@ -2808,17 +2808,20 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
						  FC_RPORT_DEVLOSS_PENDING |
						  FC_RPORT_DEVLOSS_CALLBK_DONE);

				spin_unlock_irqrestore(shost->host_lock, flags);

				/* if target, initiate a scan */
				if (rport->scsi_target_id != -1) {
					scsi_target_unblock(&rport->dev);

					spin_lock_irqsave(shost->host_lock,
							  flags);
					rport->flags |= FC_RPORT_SCAN_PENDING;
					scsi_queue_work(shost,
							&rport->scan_work);
					spin_unlock_irqrestore(shost->host_lock,
							flags);
					scsi_target_unblock(&rport->dev);
				} else
					spin_unlock_irqrestore(shost->host_lock,
							flags);
				}

				fc_bsg_goose_queue(rport);

@@ -2876,16 +2879,17 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
			if (fci->f->dd_fcrport_size)
				memset(rport->dd_data, 0,
						fci->f->dd_fcrport_size);
			spin_unlock_irqrestore(shost->host_lock, flags);

			if (ids->roles & FC_PORT_ROLE_FCP_TARGET) {
				scsi_target_unblock(&rport->dev);

			if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
				/* initiate a scan of the target */
				spin_lock_irqsave(shost->host_lock, flags);
				rport->flags |= FC_RPORT_SCAN_PENDING;
				scsi_queue_work(shost, &rport->scan_work);
				spin_unlock_irqrestore(shost->host_lock, flags);
				scsi_target_unblock(&rport->dev);
			} else
				spin_unlock_irqrestore(shost->host_lock, flags);

			}
			return rport;
		}
	}
@@ -3083,12 +3087,12 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
		/* ensure any stgt delete functions are done */
		fc_flush_work(shost);

		scsi_target_unblock(&rport->dev);
		/* initiate a scan of the target */
		spin_lock_irqsave(shost->host_lock, flags);
		rport->flags |= FC_RPORT_SCAN_PENDING;
		scsi_queue_work(shost, &rport->scan_work);
		spin_unlock_irqrestore(shost->host_lock, flags);
		scsi_target_unblock(&rport->dev);
	}
}
EXPORT_SYMBOL(fc_remote_port_rolechg);