[PATCH] make fc transport removal of target configurable

Michael Reed
2006-06-12T23:16:46Z

[-- Attachment #1: Type: text/plain, Size: 377 bytes --]

If the fc transport removes the scsi infrastructure for a
disconnected target and that target subsequently returns,
those subsystems layered upon scsi which don't understand
the implications of this disconnection / reconnection may
be unable to access the reconnected scsi target. This patch
makes the target removal configurable.

Signed-off-by: Michael Reed <mdr@sgi.com>

[-- Attachment #2: fc_transport_optional_remove.patch --]
[-- Type: text/x-patch, Size: 2209 bytes --]

--- rc6u/drivers/scsi/scsi_transport_fc.c 2006-06-07 12:21:31.000000000 -0500
+++ rc6/drivers/scsi/scsi_transport_fc.c 2006-06-12 17:23:34.135974222 -0500
@@ -374,9 +374,29 @@
MODULE_PARM_DESC(dev_loss_tmo,
"Maximum number of seconds that the FC transport should"
" insulate the loss of a remote port. Once this value is"
- " exceeded, the scsi target is removed. Value should be"
+ " exceeded, the scsi target may be removed. Reference the
+ " remove_on_dev_loss module parameter. Value should be"
" between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT.");

+/*
+ * remove_on_dev_loss: controls whether the transport will
+ * remove a scsi target after the device loss timer expires.
+ * Removal on disconnect is modeled after the USB subsystem
+ * and expects subsystems layered on SCSI to be aware of
+ * potential device loss and handle it appropriately. However,
+ * many subsystems do not support device removal, leaving situations
+ * where structure references may remain, causing new device
+ * name assignments, etc., if the target returns.
+ */
+static unsigned int fc_remove_on_dev_loss = 0;
+module_param_named(remove_on_dev_loss, fc_remove_on_dev_loss,
+ int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(remove_on_dev_loss,
+ "Boolean. When the device loss timer fires, this variable"
+ " controls whether the scsi infrastructure for the target"
+ " device is removed. Values: zero means do not remove,"
+ " non-zero means remove. Default is zero.");
+

static __init int fc_transport_init(void)
{
@@ -1446,7 +1466,8 @@
}
spin_unlock_irqrestore(shost->host_lock, flags);

- scsi_remove_target(&rport->dev);
+ if (fc_remove_on_dev_loss)
+ scsi_remove_target(&rport->dev);
}

@@ -1992,9 +2013,13 @@
return;
}

- dev_printk(KERN_ERR, &rport->dev,
- "blocked FC remote port time out: removing target and "
- "saving binding\n");
+ if (fc_remove_on_dev_loss)
+ dev_printk(KERN_ERR, &rport->dev,
+ "blocked FC remote port time out: removing target and "
+ "saving binding\n");
+ else
+ dev_printk(KERN_ERR, &rport->dev,
+ "blocked FC remote port time out: saving binding\n");

list_move_tail(&rport->peers, &fc_host->rport_bindings);