[PATCH] [SCSI] Automatic LUN removal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Ewan D. Milne" <emilne@xxxxxxxxxx>

This patch adds the capability to configure the kernel to
automatically remove LUNs when a rescan of a SCSI target
finds that LUNs that were previously reported are no longer
being reported.  This is only done when a target is scanned
using REPORT LUNS, to avoid removing LUNs due to transport
errors (in other words, the target must be accessible).

Signed-off-by: Ewan D. Milne <emilne@xxxxxxxxxx>
---
 drivers/scsi/Kconfig     |  8 +++++++
 drivers/scsi/scsi_scan.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 5d1e614..9642c87 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -292,6 +292,14 @@ config SCSI_ENHANCED_UA
 	 primarily useful when storage arrays that can be reconfigured
 	 are attached to the system, otherwise you can say N here.
 
+config SCSI_AUTOMATIC_LUN_REMOVAL
+	bool "Automatic LUN removal"
+	depends on SCSI
+	help
+	 If you want LUNs to be automatically removed when a SCSI target
+	 is rescanned and the REPORT LUNS result indicates that LUNs are
+	 no longer present, say Y.  Otherwise, say N.
+
 menu "SCSI Transports"
 	depends on SCSI
 
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 1bbbc43..a0d0d97 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1318,6 +1318,11 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
 	struct scsi_device *sdev;
 	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
 	int ret = 0;
+#ifdef CONFIG_SCSI_AUTOMATIC_LUN_REMOVAL
+	unsigned long flags;
+	struct scsi_device *sdev_i;
+	bool found;
+#endif
 
 	/*
 	 * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set.
@@ -1490,6 +1495,55 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
 		}
 	}
 
+#ifdef CONFIG_SCSI_AUTOMATIC_LUN_REMOVAL
+	/*
+	 * See if all of the LUNs that we know about on the target are
+	 * still being reported in the REPORT LUNS data.  If any are not,
+	 * they have been removed from the target.  Remove those LUNs.
+	 *
+	 * We only do this for REPORT LUNS scanning, because we do not
+	 * want to remove LUNs if they are inaccessible due to a transport
+	 * error.  Here, the target has responded to a command.
+	 */
+restart:
+	spin_lock_irqsave(shost->host_lock, flags);
+	list_for_each_entry(sdev_i, &starget->devices, same_target_siblings) {
+		/*
+		 * Don't remove the sdev used for the REPORT LUNS command here.
+		 * It will be removed at the end of the function if necessary.
+		 */
+		if (sdev_i == sdev)
+			continue;
+		if (sdev_i->sdev_state == SDEV_DEL)
+			continue;
+		found = 0;
+		for (lunp = &lun_data[1]; lunp <= &lun_data[num_luns]; lunp++) {
+			lun = scsilun_to_int(lunp);
+			if (memcmp(&lunp->scsi_lun[sizeof(lun)], "\0\0\0\0", 4))
+				continue;
+			else if (lun > sdev->host->max_lun)
+				continue;
+			else if (lun == sdev_i->lun) {
+				found = 1;
+				break;
+			}
+		}
+		if (!found) {
+			spin_unlock_irqrestore(shost->host_lock, flags);
+			sdev_printk(KERN_INFO, sdev_i,
+				    "LUN %d is no longer present, removing\n",
+				    sdev_i->lun);
+			__scsi_remove_device(sdev_i);
+			/*
+			 * Once the device has been removed, the iterator
+			 * is no longer valid and we have to start again.
+			 */
+			goto restart;
+		}
+	}
+	spin_unlock_irqrestore(shost->host_lock, flags);
+#endif
+
  out_err:
 	kfree(lun_data);
  out:
-- 
1.7.11.7

--
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


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux