On Sunday 15 August 2010 20:08:33 realrichardsharpe@xxxxxxxxx wrote: > From: Richard Sharpe <realrichardsharpe@xxxxxxxxx> > > If the target returns logical_unit_not_supported when we send REPORT LUNS > it means that it supports REPORT LUNS but there really are no LUNs there. > Delete LUN 0 in that case. > > Also, when parsing the LUNs reported, remove any LUNs that used to exist > in the gaps, and remove LUNs beyond the end of those reported. They no > longer exist. > > Also don't scan a target where the ID is too large or the channel is > too large. > > Tested by adding four LUNs with scst_local and then deleting them in > various combinations, including deleting from LUN 0, deleting from last > LUN and deleting in the middle out. What happens if you stack the device? Say you got multipath on top of this or device-mapper? Does this work properly ? For multipath I would expect it to work OK, and multipath device would queue the I/O until a LUN with the same SCSI_ID would reappear. > > Signed-off-by: Richard Sharpe <realrichardsharpe@xxxxxxxxx> > --- > drivers/scsi/scsi_scan.c | 65 > +++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 62 > insertions(+), 3 deletions(-) > > diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c > index 1c027a9..d0f5d30 100644 > --- a/drivers/scsi/scsi_scan.c > +++ b/drivers/scsi/scsi_scan.c > @@ -1309,7 +1309,7 @@ static int scsi_report_lun_scan(struct scsi_target > *starget, int bflags, char devname[64]; > unsigned char scsi_cmd[MAX_COMMAND_SIZE]; > unsigned int length; > - unsigned int lun; > + unsigned int lun, old_lun = 0; > unsigned int num_luns; > unsigned int retries; > int result; > @@ -1410,6 +1410,22 @@ static int scsi_report_lun_scan(struct scsi_target > *starget, int bflags, if (result == 0) > break; > else if (scsi_sense_valid(&sshdr)) { > + /* > + * This is awful. We should use a named constant! > + * If the target returns logical_unit_not_supported > + * then there really are zero LUNs there, so delete > + * LUN 0 if it exists. > + */ > + if (sshdr.asc == 0x25) { > + struct scsi_device *sdev = NULL; > + sdev = scsi_device_lookup_by_target(starget, 0); > + if (sdev) { > + scsi_device_put(sdev); > + __scsi_remove_device(sdev); > + SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO > + "Removing LUN 0\n")); > + } > + } > if (sshdr.sense_key != UNIT_ATTENTION) > break; > } > @@ -1473,6 +1489,27 @@ static int scsi_report_lun_scan(struct scsi_target > *starget, int bflags, } else { > int res; > > + /* > + * First, check for and remove any missing LUNs, as > + * they have been removed on the target. > + */ > + if (lun > old_lun + 1) { > + unsigned int i; > + for (i = old_lun + 1; i < lun; i++) { > + struct scsi_device *sdev; > + sdev = scsi_device_lookup_by_target( > + starget, i); > + if (sdev) { > + scsi_device_put(sdev); > + __scsi_remove_device(sdev); > + SCSI_LOG_SCAN_BUS(3, > + printk(KERN_INFO > + "Removing LUN %d\n", > + i)); > + } > + } > + } > + > res = scsi_probe_and_add_lun(starget, > lun, NULL, NULL, rescan, NULL); > if (res == SCSI_SCAN_NO_RESPONSE) { > @@ -1485,6 +1522,26 @@ static int scsi_report_lun_scan(struct scsi_target > *starget, int bflags, " aborted\n", lun); > break; > } > + > + old_lun = lun; > + } > + } > + > + /* > + * Remove any device that no longer exist. Does not work for LUN 0. > + * See above. > + */ > + if (lun < shost->max_lun) { > + int i = 0; > + for (i = lun + 1; i < shost->max_lun; i++) { > + struct scsi_device *sdev; > + sdev = scsi_device_lookup_by_target(starget, i); > + if (sdev) { > + scsi_device_put(sdev); > + __scsi_remove_device(sdev); > + SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO > + "Removed LUN %d\n", i)); > + } > } > } > > @@ -1565,9 +1622,11 @@ static void __scsi_scan_target(struct device > *parent, unsigned int channel, int res; > struct scsi_target *starget; > > - if (shost->this_id == id) > + if (shost->this_id == id || > + id > shost->max_id || > + channel > shost->max_channel) > /* > - * Don't scan the host adapter > + * Don't scan the host adapter or dis-allowed ones. > */ > return; -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html