All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
@ 2002-10-24  0:48 Steven Dake
  2002-10-24 14:25 ` James Bottomley
                   ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: Steven Dake @ 2002-10-24  0:48 UTC (permalink / raw)
  To: linux-scsi

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

linux-scsi,


Attached is an update of the Advanced TCA disk hotswap driver to provide 
disk hotswap
support for the Linux Kernel 2.5.43.  Hotswap targets include both SCSI 
and FibreChannel.
Note this support is generic in that it will work in a typical PC system 
with SCSI or
FibreChannel disks.

I've not yet ported or made suggested changes to the ga mapping driver 
yet.  I'll work on
that next.

As always, the latest Advanced TCA hotswap patches are available for 
Linux 2.4 and Linux 2.5
at the sourceforge site: (please note ga mapper hasn't yet been ported 
to 2.5)
http://sourceforge.net/project/showfiles.php?group_id=64580

Changes from kernel 2.4.19 to 2.5.44 release:
* Complete port to linux kernel 2.5.44
* Locking of scsi_host->host_queue structure when traversing scsi device 
list (suggested by Alan Cox)
  - This keeps multiple hotswap commands from corrupting the SCSI device 
list and
    causing system failure
* ioctls deleted and replaced by ramfs scsi_hotswap_fs (suggested by 
Greg KH)
  - removes need for character device node
  - usage information available by read() call to files
  - available over nfs exported directories
* local file-scope functions declared as static instead of global 
(suggested by Greg KH)
* code reformatted to fit on 80 character wide screen and to follow 
linux general kernel
  instead of scsi subsystem format
* KERNEL_SYSCALLS define removed from header (suggested by Greg KH)
* list of include files optimized to only include files as needed
* Removed direct call from scsi.c into scsi_hotswap_init and used 
module_init instead
* Made modular so can be compiled as a module or in the kernel directly
* Fixed bug where scsi_hotswap_insert_by_scsi_id didn't properly add a 
device in some cases


[-- Attachment #2: linux-2.5.44-scsi-hotswap-0.9.patch --]
[-- Type: text/plain, Size: 53249 bytes --]

diff -uNr linux-2.5.44-qla/MAINTAINERS linux-2.5.44-scsi-hotswap/MAINTAINERS
--- linux-2.5.44-qla/MAINTAINERS	Fri Oct 18 21:01:59 2002
+++ linux-2.5.44-scsi-hotswap/MAINTAINERS	Wed Oct 23 11:44:05 2002
@@ -1418,6 +1418,12 @@
 W:	http://www.kernel.dk
 S:	Maintained
 
+SCSI HOTSWAP DRIVER
+P:	Steven Dake
+M:	sdake@mvista.com
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 SCSI SG DRIVER
 P:	Doug Gilbert
 M:	dgilbert@interlog.com
diff -uNr linux-2.5.44-qla/drivers/scsi/Config.help linux-2.5.44-scsi-hotswap/drivers/scsi/Config.help
--- linux-2.5.44-qla/drivers/scsi/Config.help	Wed Oct 23 10:26:12 2002
+++ linux-2.5.44-scsi-hotswap/drivers/scsi/Config.help	Wed Oct 23 11:44:06 2002
@@ -34,6 +34,17 @@
   is located on a SCSI disk. In this case, do not compile the driver
   for your SCSI host adapter (below) as a module either.
 
+CONFIG_SCSIFCHOTSWAP
+ If you want to support the ability to include the hotswap FibreChannel
+ and SCSI driver, please say yes here.  Hotswap can then be executed
+ through a ramfs interface which provides better error reporting.
+
+ Further, this interface supports insertion and removal by WWN for
+ FibreChannel drivers which support this feature.
+
+ The only FibreChannel driver that supports this feature is Qlogic V6
+ with a specific support patch.
+
 CONFIG_SD_EXTRA_DEVS
   This controls the amount of additional space allocated in tables for
   drivers that are loaded as modules after the kernel is booted.  In
diff -uNr linux-2.5.44-qla/drivers/scsi/Config.in linux-2.5.44-scsi-hotswap/drivers/scsi/Config.in
--- linux-2.5.44-qla/drivers/scsi/Config.in	Wed Oct 23 10:26:12 2002
+++ linux-2.5.44-scsi-hotswap/drivers/scsi/Config.in	Wed Oct 23 11:44:06 2002
@@ -1,5 +1,6 @@
 comment 'SCSI support type (disk, tape, CD-ROM)'
 
+dep_tristate '  SCSI hotswap support' CONFIG_SCSIFCHOTSWAP $CONFIG_SCSI
 dep_tristate '  SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
 
 if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then
diff -uNr linux-2.5.44-qla/drivers/scsi/Makefile linux-2.5.44-scsi-hotswap/drivers/scsi/Makefile
--- linux-2.5.44-qla/drivers/scsi/Makefile	Wed Oct 23 10:26:12 2002
+++ linux-2.5.44-scsi-hotswap/drivers/scsi/Makefile	Wed Oct 23 11:44:06 2002
@@ -117,6 +117,7 @@
 
 obj-$(CONFIG_ARCH_ACORN)	+= ../acorn/scsi/
 
+obj-$(CONFIG_SCSIFCHOTSWAP)	+= hotswap.o
 obj-$(CONFIG_CHR_DEV_ST)	+= st.o
 obj-$(CONFIG_CHR_DEV_OSST)	+= osst.o
 obj-$(CONFIG_BLK_DEV_SD)	+= sd_mod.o
diff -uNr linux-2.5.44-qla/drivers/scsi/hosts.c linux-2.5.44-scsi-hotswap/drivers/scsi/hosts.c
--- linux-2.5.44-qla/drivers/scsi/hosts.c	Fri Oct 18 21:01:09 2002
+++ linux-2.5.44-scsi-hotswap/drivers/scsi/hosts.c	Wed Oct 23 15:35:30 2002
@@ -371,6 +371,7 @@
 	scsi_hosts_registered++;
 
 	spin_lock_init(&shost->default_lock);
+	spin_lock_init(&shost->host_queue_lock);
 	scsi_assign_lock(shost, &shost->default_lock);
 	atomic_set(&shost->host_active,0);
 
diff -uNr linux-2.5.44-qla/drivers/scsi/hosts.h linux-2.5.44-scsi-hotswap/drivers/scsi/hosts.h
--- linux-2.5.44-qla/drivers/scsi/hosts.h	Fri Oct 18 21:01:21 2002
+++ linux-2.5.44-scsi-hotswap/drivers/scsi/hosts.h	Wed Oct 23 15:24:39 2002
@@ -264,6 +264,14 @@
      */
     int (* bios_param)(Disk *, struct block_device *, int []);
 
+#ifdef CONFIG_SCSIFCHOTSWAP
+	/*
+	 * Used to determine the id to send the inquiry command to during
+	 * hot additions of FibreChannel targets
+	 */
+	int (*get_scsi_info_from_wwn)(int mode, unsigned long long wwn, int *host, int *channel, int *lun, int *id);
+#endif
+
     /*
      * This determines if we will use a non-interrupt driven
      * or an interrupt driven scheme,  It is set to the maximum number
@@ -374,6 +382,7 @@
      */
     struct list_head      sh_list;
     Scsi_Device           * host_queue;
+    spinlock_t		  host_queue_lock;
     struct list_head	  all_scsi_hosts;
     struct list_head	  my_devices;
 
diff -uNr linux-2.5.44-qla/drivers/scsi/hotswap.c linux-2.5.44-scsi-hotswap/drivers/scsi/hotswap.c
--- linux-2.5.44-qla/drivers/scsi/hotswap.c	Wed Dec 31 17:00:00 1969
+++ linux-2.5.44-scsi-hotswap/drivers/scsi/hotswap.c	Wed Oct 23 15:28:15 2002
@@ -0,0 +1,1334 @@
+/*
+ * hotswap.c
+ *
+ * SCSI/FibreChannel Hotswap kernel implementaton
+ * 
+ * Author: MontaVista Software, Inc.
+ *         Steven Dake (sdake@mvista.com)
+ *         source@mvista.com
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ *
+ * Derived from linux/scsi/scsi.c hotswap code
+ *
+ * 	added FibreChannel hotswap by both WWN/host/channel/lun and WWN wildcard
+ * 	added ramfs interface
+ * 	added locking to scsi host queue structure (list of scsi devices on host)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this program; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/types.h>
+#include <linux/dcache.h>
+#include <linux/namei.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/blk.h>
+#include <linux/spinlock.h>
+
+#include <asm/uaccess.h>
+
+#include "scsi.h"
+#include "hosts.h"
+#include <linux/scsi_hotswap.h>
+
+#define SCSI_HOTSWAP_MAGIC 0x02834431
+
+#define DRIVER_VERSION "0.9"
+#define DRIVER_AUTHOR "MontaVista Software Inc, Steven Dake <sdake@mvista.com>"
+#define DRIVER_DESCRIPTION "SCSI and FibreChannel Hotswap Core"
+
+static struct cmd_fs {
+	struct dentry *insert_by_scsi_id;
+	struct dentry *remove_by_scsi_id;
+	struct dentry *insert_by_fc_wwn;
+	struct dentry *remove_by_fc_wwn;
+	struct dentry *insert_by_fc_wwn_wildcard;
+	struct dentry *remove_by_fc_wwn_wildcard;
+} scsi_hotswap_cmd_fs;
+
+static struct super_operations scsi_hotswap_super_operations;
+static struct file_operations default_file_operations;
+static struct inode_operations scsi_hotswap_dir_inode_operations;
+
+static struct vfsmount *scsi_hotswap_mountpoint;
+
+/*
+ * Default file operations
+ */
+static int scsi_hotswap_statfs (struct super_block *sb, struct statfs *buf)
+{
+	buf->f_type = SCSI_HOTSWAP_MAGIC;
+	buf->f_bsize = PAGE_CACHE_SIZE;
+	buf->f_namelen = 255;
+	return (0);
+}
+
+static struct dentry *scsi_hotswap_lookup (struct inode *dir,
+	struct dentry *dentry)
+{
+	d_add (dentry, NULL);
+	return (NULL);
+}
+
+static struct inode *scsi_hotswap_get_inode (struct super_block *sb, int mode,
+	int dev)
+{
+	struct inode *inode = new_inode(sb);
+
+	if (inode) {
+		inode->i_mode = mode;
+		inode->i_uid = current->fsuid;
+		inode->i_gid = current->fsgid;
+		inode->i_blksize = PAGE_CACHE_SIZE;
+		inode->i_blocks = 0;
+		inode->i_rdev = NODEV;
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		switch (mode & S_IFMT) {
+		default:
+			init_special_inode (inode, mode, dev);
+			break;
+
+		case S_IFREG:
+			inode->i_fop = &default_file_operations;
+			break;
+		case S_IFDIR:
+			inode->i_op = &scsi_hotswap_dir_inode_operations;
+			inode->i_fop = &simple_dir_operations;
+			inode->i_nlink++;
+			break;
+		}
+	}
+	return (inode);
+}
+
+static int scsi_hotswap_mknod (struct inode *dir, struct dentry *dentry,
+	int mode, int dev)
+{
+	struct inode *inode = scsi_hotswap_get_inode (dir->i_sb, mode, dev);
+	int error = -ENOSPC;
+
+	if (inode) {
+		d_instantiate (dentry, inode);
+		dget (dentry);
+		error = 0;
+	}
+	return (error);
+}
+
+static int scsi_hotswap_mkdir (struct inode *dir, struct dentry *dentry,
+	int mode)
+{
+	return (scsi_hotswap_mknod (dir, dentry, mode | S_IFDIR, 0));
+}
+
+static int scsi_hotswap_create (struct inode *dir, struct dentry *dentry,
+	int mode)
+{
+	return (scsi_hotswap_mknod (dir, dentry, mode | S_IFREG, 0));
+}
+
+static int scsi_hotswap_link (struct dentry *old_dentry, struct inode *dir,
+	struct dentry *dentry)
+{
+	struct inode *inode = old_dentry->d_inode;
+
+	if (S_ISDIR(inode->i_mode)) {
+		return (-EPERM);
+	}
+
+	inode->i_nlink++;
+	atomic_inc (&inode->i_count);
+	dget (dentry);
+	d_instantiate (dentry, inode);
+
+	return (0);
+}
+
+static inline int scsi_hotswap_positive (struct dentry *dentry)
+{
+	return (dentry->d_inode && !d_unhashed (dentry));
+}
+
+static int scsi_hotswap_empty (struct dentry *dentry)
+{
+	struct list_head *list;
+
+	spin_lock(&dcache_lock);
+
+	list_for_each (list, &dentry->d_subdirs) {
+		struct dentry *de = list_entry(list, struct dentry, d_child);
+		if (scsi_hotswap_positive (de)) {
+			spin_unlock (&dcache_lock);
+			return 0;
+		}
+        }
+
+	spin_unlock(&dcache_lock);
+	return (1);
+}
+
+static int scsi_hotswap_unlink (struct inode *dir, struct dentry *dentry)
+{
+	int error = -ENOTEMPTY;
+
+	if (scsi_hotswap_empty (dentry)) {
+		struct inode *inode = dentry->d_inode;
+
+		inode->i_nlink--;
+		dput (dentry);
+		error = 0;
+	}
+	return (error);
+}
+
+static int scsi_hotswap_rename (struct inode *old_dir,
+	struct dentry *old_dentry, struct inode *new_dir,
+	struct dentry *new_dentry)
+{
+	int error = -ENOTEMPTY;
+
+	if (scsi_hotswap_empty (new_dentry)) {
+		struct inode *inode = new_dentry->d_inode;
+		if (inode) {
+			inode->i_nlink--;
+			dput (new_dentry);
+		}
+		error = 0;
+	}
+
+	return (error);
+}
+
+#define scsi_hotswap_rmdir scsi_hotswap_unlink
+
+static ssize_t default_read_file (struct file *file, char *buf, size_t count,
+	loff_t *ppos)
+{
+	return (0);
+}
+
+static ssize_t default_write_file (struct file *file, const char *buf,
+	size_t count, loff_t *ppos)
+{
+	return (count);
+}
+
+static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
+{
+	loff_t retval = -EINVAL;
+
+	switch(orig) {
+	case 0:
+		if (offset > 0) {
+			file->f_pos = offset;
+			retval = file->f_pos;
+		}
+		break;
+	case 1:
+		if ((offset + file->f_pos) > 0) {
+			file->f_pos += offset;
+			retval = file->f_pos;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return (retval);
+}
+
+static int default_open (struct inode *inode, struct file *filp)
+{
+	if (inode->u.generic_ip) {
+		filp->private_data = inode->u.generic_ip;
+	}
+	return (0);
+}
+
+static int default_sync_file (struct file *file, struct dentry *dentry,
+	int datasync)
+{
+	return (0);
+}
+
+static struct file_operations default_file_operations = {
+	read:		default_read_file,
+	write: 		default_write_file,
+	open:		default_open,
+	llseek:		default_file_lseek,
+	fsync: 		default_sync_file,
+	mmap: 		generic_file_mmap,
+};
+
+static struct inode_operations scsi_hotswap_dir_inode_operations = {
+	create:		scsi_hotswap_create,
+	lookup:		scsi_hotswap_lookup,
+	link:		scsi_hotswap_link,
+	unlink:		scsi_hotswap_unlink,
+	mkdir:		scsi_hotswap_mkdir,
+	rmdir:		scsi_hotswap_rmdir,
+	mknod:		scsi_hotswap_mknod,
+	rename:		scsi_hotswap_rename,
+};
+
+static struct super_operations scsi_hotswap_super_operations = {
+	statfs:		scsi_hotswap_statfs,
+	drop_inode:	generic_delete_inode,
+/* IFDEF LINUX-2.4 
+	put_inode:	force_delete,
+*/
+};
+
+/*
+ * scsi_hotswap_insert_by_scsi_id file operations structure
+ */
+static ssize_t scsi_hotswap_insert_by_scsi_id_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset);
+static ssize_t scsi_hotswap_insert_by_scsi_id_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos);
+
+static struct file_operations scsi_hotswap_insert_by_scsi_id_file_operations = {
+	read:	scsi_hotswap_insert_by_scsi_id_read_file,
+	write:	scsi_hotswap_insert_by_scsi_id_write_file,
+	open:	default_open,
+	llseek:	default_file_lseek,
+	fsync:	default_sync_file,
+	mmap:	generic_file_mmap
+};
+
+/*
+ * scsi_hotswap_remove_by_scsi_id file operations structure
+ */
+static ssize_t scsi_hotswap_remove_by_scsi_id_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset);
+static ssize_t scsi_hotswap_remove_by_scsi_id_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos);
+
+static struct file_operations scsi_hotswap_remove_by_scsi_id_file_operations = {
+	read:	scsi_hotswap_remove_by_scsi_id_read_file,
+	write:	scsi_hotswap_remove_by_scsi_id_write_file,
+	open:	default_open,
+	llseek:	default_file_lseek,
+	fsync:	default_sync_file,
+	mmap:	generic_file_mmap
+};
+
+/*
+ * scsi_hotswap_insert_by_fc_wwn file operations structure
+ */
+static ssize_t scsi_hotswap_insert_by_fc_wwn_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset);
+static ssize_t scsi_hotswap_insert_by_fc_wwn_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos);
+
+static struct file_operations scsi_hotswap_insert_by_fc_wwn_file_operations = {
+	read:	scsi_hotswap_insert_by_fc_wwn_read_file,
+	write:	scsi_hotswap_insert_by_fc_wwn_write_file,
+	open:	default_open,
+	llseek:	default_file_lseek,
+	fsync:	default_sync_file,
+	mmap:	generic_file_mmap
+};
+
+/*
+ * scsi_hotswap_remove_by_fc_wwn file operations structure
+ */
+static ssize_t scsi_hotswap_remove_by_fc_wwn_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset);
+static ssize_t scsi_hotswap_remove_by_fc_wwn_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos);
+
+static struct file_operations scsi_hotswap_remove_by_fc_wwn_file_operations = {
+	read:	scsi_hotswap_remove_by_fc_wwn_read_file,
+	write:	scsi_hotswap_remove_by_fc_wwn_write_file,
+	open:	default_open,
+	llseek:	default_file_lseek,
+	fsync:	default_sync_file,
+	mmap:	generic_file_mmap
+};
+/*
+ * scsi_hotswap_insert_by_fc_wwn_wildcard file operations structure
+ */
+static ssize_t scsi_hotswap_insert_by_fc_wwn_wildcard_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset);
+static ssize_t scsi_hotswap_insert_by_fc_wwn_wildcard_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos);
+
+static struct file_operations scsi_hotswap_insert_by_fc_wwn_wildcard_file_operations = {
+	read:	scsi_hotswap_insert_by_fc_wwn_wildcard_read_file,
+	write:	scsi_hotswap_insert_by_fc_wwn_wildcard_write_file,
+	open:	default_open,
+	llseek:	default_file_lseek,
+	fsync:	default_sync_file,
+	mmap:	generic_file_mmap
+};
+
+/*
+ * scsi_hotswap_remove_by_fc_wwn_wildcard file operations structure
+ */
+static ssize_t scsi_hotswap_remove_by_fc_wwn_wildcard_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset);
+static ssize_t scsi_hotswap_remove_by_fc_wwn_wildcard_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos);
+
+static struct file_operations scsi_hotswap_remove_by_fc_wwn_wildcard_file_operations = {
+	read:	scsi_hotswap_remove_by_fc_wwn_wildcard_read_file,
+	write:	scsi_hotswap_remove_by_fc_wwn_wildcard_write_file,
+	open:	default_open,
+	llseek:	default_file_lseek,
+	fsync:	default_sync_file,
+	mmap:	generic_file_mmap
+};
+
+//static struct super_block *scsi_hotswap_read_super (struct super_block *sb, void *data, int silet) {
+static int scsi_hotswap_fill_super (struct super_block *sb, void *data,
+	int silet)
+{
+	struct inode *inode;
+	struct dentry *root;
+
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = SCSI_HOTSWAP_MAGIC;
+	sb->s_op = &scsi_hotswap_super_operations;
+	inode = scsi_hotswap_get_inode (sb, S_IFDIR | 0755, 0);
+
+	if (inode == 0) {
+		return (-ENOMEM);
+	}
+
+	root = d_alloc_root (inode);
+	if (root == 0) {
+		iput(inode);
+		return (-ENOMEM);
+	}
+	sb->s_root = root;
+
+	return (0);
+}
+
+static struct super_block *scsi_hotswap_get_sb (struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return (get_sb_single (fs_type, flags, data, scsi_hotswap_fill_super));
+}	
+
+static struct file_system_type scsi_hotswap_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"scsi_hotswap_fs",
+	get_sb:		scsi_hotswap_get_sb,
+	kill_sb:	kill_litter_super,
+};
+
+static int scsi_hotswap_fs_create_by_name (const char *name, mode_t mode,
+	struct dentry *parent, struct dentry **dentry)
+{
+	struct dentry *d = NULL;
+	struct qstr qstr;
+	int error;
+
+	if (parent == 0) {
+		parent = scsi_hotswap_mountpoint->mnt_sb->s_root;
+	}
+
+	if (parent == 0) {
+		return (-EINVAL);
+	}
+
+	*dentry = NULL;
+	qstr.name = name;
+	qstr.len = strlen (name);
+	qstr.hash = full_name_hash (name, qstr.len);
+
+	parent = dget (parent);
+
+	down (&parent->d_inode->i_sem);
+
+	d = lookup_hash (&qstr, parent);
+
+	error = PTR_ERR (d);
+	if (IS_ERR(d) == 0) {
+		switch (mode & S_IFMT) {
+			case 0:
+			case S_IFREG:
+				error = vfs_create (parent->d_inode, d, mode);
+				break;
+			case S_IFDIR:
+				error = vfs_mkdir (parent->d_inode, d, mode);
+				break;
+			default:
+				error = -EINVAL;
+		}
+		*dentry = d;
+	}
+	up (&parent->d_inode->i_sem);
+
+	dput (parent);
+
+	return (error);
+}
+
+static struct dentry *scsi_hotswap_fs_create_file (const char *name,
+	mode_t mode, struct dentry *parent,
+	struct file_operations *file_operations)
+{
+	struct dentry *dentry;
+	int error;
+
+	error = scsi_hotswap_fs_create_by_name (name, mode, parent, &dentry);
+	if (error) {
+		dentry = 0;
+	} else {
+		if (dentry->d_inode) {
+			if (file_operations) {
+				dentry->d_inode->i_fop = file_operations;
+			}
+		}
+	}
+
+	return (dentry);
+}
+
+static void fs_remove_file (struct dentry *dentry) {
+	struct dentry *parent = dentry->d_parent;
+
+	if (!parent || !parent->d_inode) {
+		return;
+	}
+
+	down (&parent->d_inode->i_sem);
+
+	if (scsi_hotswap_positive (dentry)) {
+		if (dentry->d_inode) {
+			if (S_ISDIR (dentry->d_inode->i_mode)) {
+				vfs_rmdir (parent->d_inode,dentry);
+			} else {
+				vfs_unlink (parent->d_inode,dentry);
+			}
+		}
+		dput (dentry);
+	}
+	up (&parent->d_inode->i_sem);
+}
+
+/*
+ * Core file read/write operations interfaces
+ */
+static char scsi_hotswap_insert_by_scsi_id_usage[] = {
+	"Usage: echo \"[host] [channel] [lun] [id]\" > insert_by_scsi_id\n"
+};
+
+static char scsi_hotswap_remove_by_scsi_id_usage[] = {
+	"Usage: echo \"[host] [channel] [lun] [id]\" > remove_by_scsi_id\n"
+};
+
+static char scsi_hotswap_insert_by_fc_wwn_usage[]  = {
+	"Usage: echo \"[host] [channel] [lun] [wwn]\" > insert_by_fc_wwn\n"
+};
+
+static char scsi_hotswap_remove_by_fc_wwn_usage[]  = {
+	"Usage: echo \"[host] [channel] [lun] [wwn]\" > remove_by_fc_wwn\n"
+};
+
+static char scsi_hotswap_insert_by_fc_wwn_wildcard_usage[]  = {
+	"Usage: echo \"[wwn]\" > insert_by_fc_wwn_wildcard\n"
+};
+
+static char scsi_hotswap_remove_by_fc_wwn_wildcard_usage[]  = {
+	"Usage: echo \"[wwn]\" > remove_by_fc_wwn_wildcard\n"
+};
+
+static ssize_t scsi_hotswap_insert_by_scsi_id_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset)
+{
+	int len;
+
+	if (*offset) {
+		return (0);
+	}
+	len = strlen (scsi_hotswap_insert_by_scsi_id_usage);
+	if (copy_to_user (buf, scsi_hotswap_insert_by_scsi_id_usage, len)) {
+		return (-EFAULT);
+	}
+
+	*offset += len;
+	return (len);
+}
+
+static ssize_t scsi_hotswap_insert_by_scsi_id_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos)
+{
+	int host, channel, lun, id;
+	char parameters[1024];
+	char *p;
+	int result;
+
+	if (count == 0 || count > 1024) {
+		return (0);
+	}
+
+	if (copy_from_user ((void *)parameters, (void *)buf, count)) {
+		return (-EFAULT);
+	}
+
+	p = parameters;
+	host = simple_strtoul (p, &p, 0);
+	channel = simple_strtoul (p + 1, &p, 0);
+	lun = simple_strtoul (p + 1, &p, 0);
+	id = simple_strtoul (p + 1, &p, 0);
+
+	result = scsi_hotswap_insert_by_scsi_id (host, channel, lun, id);
+
+	if (result) {
+		return (result);
+	}
+	return (count);
+}
+
+static ssize_t scsi_hotswap_remove_by_scsi_id_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset)
+{
+	int len;
+
+	if (*offset) {
+		return (0);
+	}
+	len = strlen (scsi_hotswap_remove_by_scsi_id_usage);
+	if (copy_to_user (buf, scsi_hotswap_remove_by_scsi_id_usage, len)) {
+		return (-EFAULT);
+	}
+
+	*offset += len;
+	return (len);
+}
+
+static ssize_t scsi_hotswap_remove_by_scsi_id_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos)
+{
+	int host, channel, lun, id;
+	char parameters[1024];
+	char *p;
+	int result;
+
+	if (count == 0 || count > 1024) {
+		return (0);
+	}
+
+	if (copy_from_user ((void *)parameters, (void *)buf, count)) {
+		return (-EFAULT);
+	}
+
+	p = parameters;
+	host = simple_strtoul (p, &p, 0);
+	channel = simple_strtoul (p + 1, &p, 0);
+	lun = simple_strtoul (p + 1, &p, 0);
+	id = simple_strtoul (p + 1, &p, 0);
+
+	result = scsi_hotswap_remove_by_scsi_id (host, channel, lun, id);
+
+	if (result) {
+		return (result);
+	}
+	return (count);
+	return (-ENOMEM);
+}
+
+static ssize_t scsi_hotswap_insert_by_fc_wwn_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset)
+{
+	int len;
+
+	if (*offset) {
+		return (0);
+	}
+	len = strlen (scsi_hotswap_insert_by_fc_wwn_usage);
+	if (copy_to_user (buf, scsi_hotswap_insert_by_fc_wwn_usage, len)) {
+		return (-EFAULT);
+	}
+
+	*offset += len;
+	return (len);
+}
+
+static ssize_t scsi_hotswap_insert_by_fc_wwn_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos)
+{
+	int host, channel, lun;
+	unsigned long long wwn;
+	char parameters[1024];
+	char *p;
+	int result;
+
+	if (count == 0 || count > 1024) {
+		return (0);
+	}
+
+	if (copy_from_user ((void *)parameters, (void *)buf, count)) {
+		return (-EFAULT);
+	}
+
+	p = parameters;
+	host = simple_strtoul (p, &p, 0);
+	channel = simple_strtoul (p + 1, &p, 0);
+	lun = simple_strtoul (p + 1, &p, 0);
+	wwn = simple_strtoull (p + 1, &p, 0);
+
+	result = scsi_hotswap_insert_by_fc_wwn (host, channel, lun, wwn);
+
+	if (result) {
+		return (result);
+	}
+	return (count);
+}
+
+static ssize_t scsi_hotswap_remove_by_fc_wwn_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset)
+{
+	int len;
+
+	if (*offset) {
+		return (0);
+	}
+	len = strlen (scsi_hotswap_remove_by_fc_wwn_usage);
+
+	if (copy_to_user (buf, scsi_hotswap_remove_by_fc_wwn_usage, len)) {
+		return (-EFAULT);
+	}
+
+	*offset += len;
+	return (len);
+}
+
+static ssize_t scsi_hotswap_remove_by_fc_wwn_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos)
+{
+	int host, channel, lun;
+	unsigned long long wwn;
+	char parameters[1024];
+	char *p;
+	int result;
+
+	if (count == 0 || count > 1024) {
+		return (0);
+	}
+
+	if (copy_from_user ((void *)parameters, (void *)buf, count)) {
+		return (-EFAULT);
+	}
+
+	p = parameters;
+	host = simple_strtoul (p, &p, 0);
+	channel = simple_strtoul (p + 1, &p, 0);
+	lun = simple_strtoul (p + 1, &p, 0);
+	wwn = simple_strtoull (p + 1, &p, 0);
+
+	result = scsi_hotswap_remove_by_fc_wwn (host, channel, lun, wwn);
+
+	if (result) {
+		return (result);
+	}
+	return (count);
+}
+
+static ssize_t scsi_hotswap_insert_by_fc_wwn_wildcard_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset)
+{
+	int len;
+
+	if (*offset) {
+		return (0);
+	}
+	len = strlen (scsi_hotswap_insert_by_fc_wwn_wildcard_usage);
+	if (copy_to_user (buf, scsi_hotswap_insert_by_fc_wwn_wildcard_usage,
+		len)) {
+		return (-EFAULT);
+	}
+
+	*offset += len;
+	return (len);
+}
+
+static ssize_t scsi_hotswap_insert_by_fc_wwn_wildcard_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos)
+{
+	unsigned long long wwn;
+	char parameters[1024];
+	char *p;
+	int result;
+
+	if (count == 0 || count > 1024) {
+		return (0);
+	}
+
+	if (copy_from_user ((void *)parameters, (void *)buf, count)) {
+		return (-EFAULT);
+	}
+
+	p = parameters;
+	wwn = simple_strtoull (p, &p, 0);
+
+	result = scsi_hotswap_insert_by_fc_wwn_wildcard (wwn);
+
+	if (result) {
+		return (result);
+	}
+	return (count);
+	return (-ENOMEM);
+}
+
+static ssize_t scsi_hotswap_remove_by_fc_wwn_wildcard_read_file (struct file *file,
+	char *buf, size_t count, loff_t *offset)
+{
+	int len;
+
+	if (*offset) {
+		return (0);
+	}
+	len = strlen (scsi_hotswap_remove_by_fc_wwn_wildcard_usage);
+	if (copy_to_user (buf, scsi_hotswap_remove_by_fc_wwn_wildcard_usage,
+		len)) {
+		return (-EFAULT);
+	}
+
+	*offset += len;
+	return (len);
+}
+
+static ssize_t scsi_hotswap_remove_by_fc_wwn_wildcard_write_file (struct file *file,
+	const char *buf, size_t count, loff_t *ppos)
+{
+	unsigned long long wwn;
+	char parameters[1024];
+	char *p;
+	int result;
+
+	if (count == 0 || count > 1024) {
+		return (0);
+	}
+
+	if (copy_from_user ((void *)parameters, (void *)buf, count)) {
+		return (-EFAULT);
+	}
+
+	p = parameters;
+	wwn = simple_strtoull (p, &p, 0);
+
+	result = scsi_hotswap_remove_by_fc_wwn_wildcard (wwn);
+
+	if (result) {
+		return (result);
+	}
+	return (count);
+}
+
+/*
+ * Core Interface Implementation
+ * Note these are exported to the global symbol table for
+ * other subsystems to use such as a scsi processor or 1394
+ */
+int scsi_hotswap_insert_by_scsi_id (unsigned int host, unsigned int channel,
+	unsigned int lun, unsigned int id)
+{
+	struct Scsi_Host *scsi_host;
+	Scsi_Device *scsi_device;
+
+	for (scsi_host = scsi_host_get_next (NULL); scsi_host;
+		scsi_host = scsi_host_get_next (scsi_host)) {
+		if (scsi_host->host_no == host) {
+			break;
+		}
+	}
+	if (scsi_host == 0) {
+		return (-ENXIO);
+	}
+
+	spin_lock (&scsi_host->host_queue_lock);
+
+	/*
+	 * Determine if device already attached
+	 */
+	for (scsi_device = scsi_host->host_queue; scsi_device; scsi_device = scsi_device->next) {
+		if ((scsi_device->channel == channel
+		     && scsi_device->id == id
+		     && scsi_device->lun == lun)) {
+			break;
+		}
+	}
+	
+	spin_unlock (&scsi_host->host_queue_lock);
+
+	/*
+	 * If scsi_device found in host queue, then device already attached
+	 */
+	if (scsi_device) {
+		return (-EEXIST);
+	}
+
+	scan_scsis(scsi_host, 1, channel, id, lun);
+
+	return (0);
+}
+
+int scsi_hotswap_remove_by_scsi_id (unsigned int host, unsigned int channel,
+	unsigned int lun, unsigned int id)
+{
+	struct Scsi_Device_Template *scsi_template;
+	struct Scsi_Host *scsi_host;
+	Scsi_Device *scsi_device;
+
+	for (scsi_host = scsi_host_get_next (NULL); scsi_host;
+		scsi_host = scsi_host_get_next (scsi_host)) {
+		if (scsi_host->host_no == host) {
+			break;
+		}
+	}
+	if (scsi_host == 0) {
+		return (-ENODEV);
+	}
+
+	spin_lock (&scsi_host->host_queue_lock);
+
+	for (scsi_device = scsi_host->host_queue; scsi_device;
+		scsi_device = scsi_device->next) {
+		if ((scsi_device->channel == channel
+		     && scsi_device->id == id
+		     && scsi_device->lun == lun)) {
+			break;
+		}
+	}
+
+	spin_unlock (&scsi_host->host_queue_lock);
+
+	if (scsi_device == NULL) {
+		return (-ENOENT);
+	}
+
+	if (scsi_device->access_count) {
+		return (-EBUSY);
+	}
+
+	for (scsi_template = scsi_devicelist; scsi_template; scsi_template = scsi_template->next) {
+		if (scsi_template->detach) {
+			(*scsi_template->detach) (scsi_device);
+		}
+	}
+
+	if (scsi_device->attached == 0) {
+		/*
+		 * Nobody is using this device any more.
+		 * Free all of the command structures.
+		 */
+		if (scsi_host->hostt->revoke)
+			scsi_host->hostt->revoke(scsi_device);
+		devfs_unregister (scsi_device->de);
+		scsi_release_commandblocks(scsi_device);
+
+		/* Now we can remove the device structure */
+		if (scsi_device->next != NULL)
+			scsi_device->next->prev = scsi_device->prev;
+
+		if (scsi_device->prev != NULL)
+			scsi_device->prev->next = scsi_device->next;
+
+		if (scsi_host->host_queue == scsi_device) {
+			scsi_host->host_queue = scsi_device->next;
+		}
+		blk_cleanup_queue(&scsi_device->request_queue);
+		kfree((char *) scsi_device);
+	}
+
+	return (0);
+}
+
+int scsi_hotswap_insert_by_fc_wwn (unsigned int host, unsigned int channel,
+	unsigned int lun, unsigned long long wwn)
+{
+	struct Scsi_Host *scsi_host;
+	Scsi_Device *scsi_device;
+	int id;
+	int result;
+
+	for (scsi_host = scsi_host_get_next (NULL); scsi_host;
+		scsi_host = scsi_host_get_next (scsi_host)) {
+		if (scsi_host->host_no == host) {
+			break;
+		}
+	}
+
+	if (scsi_host == 0) {
+		return (-ENXIO);
+	}
+
+	result = scsi_host->hostt->get_scsi_info_from_wwn (0, wwn, &host,
+		&channel, &lun, &id);
+	/*
+	 * Nonzero result indicates error
+	 */
+	if (result) {
+		return (result);
+	}
+
+	/*
+	 * Determine if device already attached
+	 */
+	spin_lock (&scsi_host->host_queue_lock);
+
+	for (scsi_device = scsi_host->host_queue; scsi_device;
+		scsi_device = scsi_device->next) {
+		if ((scsi_device->channel == channel
+		     && scsi_device->id == id
+		     && scsi_device->lun == lun)) {
+			break;
+		}
+	}
+
+	spin_unlock (&scsi_host->host_queue_lock);
+
+	/*
+	 * If scsi_device found in host queue, then device already attached
+	 */
+	if (scsi_device) {
+		return (-EEXIST);
+	}
+
+	scan_scsis (scsi_host, 1, channel, id, lun);
+	return (0);
+}
+
+int scsi_hotswap_remove_by_fc_wwn (unsigned int host, unsigned int channel,
+	unsigned int lun, unsigned long long wwn)
+{
+
+	struct Scsi_Device_Template *scsi_template;
+	Scsi_Device *scsi_device;
+	struct Scsi_Host *scsi_host;
+	int id;
+	int result;
+
+	for (scsi_host = scsi_host_get_next (NULL); scsi_host;
+		scsi_host = scsi_host_get_next (scsi_host)) {
+		if (scsi_host->host_no == host) {
+			break;
+		}
+	}
+	if (scsi_host == 0) {
+		return (-ENODEV);
+	}
+
+	result = scsi_host->hostt->get_scsi_info_from_wwn (1, wwn, &host,
+		&channel, &lun, &id);
+
+	/*
+	 * Nonzero indicates error
+	 */
+	if (result) {
+		return (result);
+	}
+
+	spin_lock (&scsi_host->host_queue_lock);
+
+	for (scsi_device = scsi_host->host_queue; scsi_device;
+		scsi_device = scsi_device->next) {
+		if ((scsi_device->channel == channel
+		     && scsi_device->id == id
+		     && scsi_device->lun == lun)) {
+			break;
+		}
+	}
+
+	spin_unlock (&scsi_host->host_queue_lock);
+
+	if (scsi_device == NULL) {
+		return (-ENOENT);
+	}
+
+	if (scsi_device->access_count) {
+		return (-EBUSY);
+	}
+
+	for (scsi_template = scsi_devicelist; scsi_template; scsi_template = scsi_template->next) {
+		if (scsi_template->detach) {
+			(*scsi_template->detach) (scsi_device);
+		}
+	}
+
+	if (scsi_device->attached == 0) {
+		/*
+		 * Nobody is using this device any more.
+		 * Free all of the command structures.
+		 */
+		if (scsi_host->hostt->revoke)
+			scsi_host->hostt->revoke(scsi_device);
+		devfs_unregister (scsi_device->de);
+		scsi_release_commandblocks(scsi_device);
+
+		/* Now we can remove the device structure */
+		if (scsi_device->next != NULL)
+			scsi_device->next->prev = scsi_device->prev;
+
+		if (scsi_device->prev != NULL)
+			scsi_device->prev->next = scsi_device->next;
+
+		if (scsi_host->host_queue == scsi_device) {
+			scsi_host->host_queue = scsi_device->next;
+		}
+		blk_cleanup_queue(&scsi_device->request_queue);
+		kfree((char *) scsi_device);
+	}
+	return (0);
+}
+
+int scsi_hotswap_insert_by_fc_wwn_wildcard (unsigned long long wwn)
+{
+	struct Scsi_Host *scsi_host;
+	Scsi_Device *scsi_device;
+	int host, lun, channel, id;
+	int result;
+
+	/*
+	 * Search scsi hostlist 
+	 */
+	for (scsi_host = scsi_host_get_next (NULL); scsi_host;
+		scsi_host = scsi_host_get_next (scsi_host)) {
+		/*
+		 * Skip unsupported drivers.  This is known because
+		 * get_scsi_info_from_wwn would be defined as 0
+		 */
+		if (scsi_host->hostt->get_scsi_info_from_wwn == 0) {
+			continue;
+		}
+		
+		result = scsi_host->hostt->get_scsi_info_from_wwn (0, wwn,
+			&host, &channel, &lun, &id);
+		/*
+		 * WWN not found, try next adaptor
+		 */
+		if (result == -ENOENT) {
+			continue;
+		}
+
+
+		/*
+		 * If the currently scanned host doesn't match the WWN's host ID
+		 * try again searching with new host id
+		 */
+		if (scsi_host->host_no != host) {
+			continue;
+		}
+
+			
+		/*
+		 * Verify we are not inserting an existing device
+		 */
+		spin_lock (&scsi_host->host_queue_lock);
+
+		for (scsi_device = scsi_host->host_queue; scsi_device;
+			scsi_device = scsi_device->next) {
+			if ((scsi_device->channel == channel
+			     && scsi_device->id == id
+			     && scsi_device->lun == lun)) {
+				break;
+			}
+		}
+
+		spin_unlock (&scsi_host->host_queue_lock);
+
+		/*
+		 * Insertion if no device found
+		 */
+		if (scsi_device == 0) {
+			scan_scsis(scsi_host, 1, 0, id, lun);
+			scan_scsis(scsi_host, 1, 1, id, lun);
+			break; /* exit scsi_host scan */
+		}
+	} /* scsi_host scan */
+
+	if (scsi_host == 0) {
+		return (-ENOENT);
+	}
+	return (0);
+}
+
+int scsi_hotswap_remove_by_fc_wwn_wildcard (unsigned long long wwn)
+{
+	struct Scsi_Device_Template *scsi_template;
+	Scsi_Device *scsi_device;
+	struct Scsi_Host *scsi_host;
+	int host, lun, channel, id;
+	int result;
+
+	for (scsi_host = scsi_host_get_next (NULL); scsi_host;
+		scsi_host = scsi_host_get_next (scsi_host)) {
+		/*
+		 * Skip unsupported drivers
+		 */
+		if (scsi_host->hostt->get_scsi_info_from_wwn == 0) {
+			continue;
+		}
+
+		result = scsi_host->hostt->get_scsi_info_from_wwn (1, wwn,
+			&host, &channel, &lun, &id);
+
+		/*
+		 * Adaptor not found, try next adaptor 
+		 */
+		if (result) {
+			continue;
+		}
+
+		spin_lock (&scsi_host->host_queue_lock);
+
+		for (scsi_device = scsi_host->host_queue; scsi_device;
+			scsi_device = scsi_device->next) {
+			if ((scsi_device->channel == channel
+				 && scsi_device->id == id
+				 && scsi_device->lun == lun)) {
+				break;
+			}
+		}
+
+		spin_unlock (&scsi_host->host_queue_lock);
+
+		if (scsi_device->access_count) {
+			return (-EBUSY);
+		}
+
+		for (scsi_template = scsi_devicelist; scsi_template;
+			scsi_template = scsi_template->next) {
+			if (scsi_template->detach) {
+				(*scsi_template->detach) (scsi_device);
+			}
+		}
+
+		if (scsi_device->attached == 0) {
+			/*
+			 * Nobody is using this device any more.
+			 * Free all of the command structures.
+			 */
+			if (scsi_host->hostt->revoke)
+				scsi_host->hostt->revoke(scsi_device);
+			devfs_unregister (scsi_device->de);
+			scsi_release_commandblocks(scsi_device);
+
+			/* Now we can remove the device structure */
+			if (scsi_device->next != NULL)
+				scsi_device->next->prev = scsi_device->prev;
+	
+			if (scsi_device->prev != NULL)
+				scsi_device->prev->next = scsi_device->next;
+	
+			if (scsi_host->host_queue == scsi_device) {
+				scsi_host->host_queue = scsi_device->next;
+			}
+			blk_cleanup_queue(&scsi_device->request_queue);
+			kfree((char *) scsi_device);
+		}
+		break; /* Break from scan all hosts since we found match */
+	} /* scan all hosts */
+
+	if (scsi_host == 0) {
+		return (-ENOENT);
+	}
+	return (0);
+}
+
+static int __init scsi_hotswap_init (void) {
+	int result = 0;
+	printk (KERN_INFO "Copyright (C) 2002 MontaVista Software - SCSI/FibreChannel hotswap driver\n");
+
+	/*
+	 * Register the filesystem
+	 */
+	result = register_filesystem (&scsi_hotswap_fs_type);
+
+	/*
+	 * Mount the filesystem
+	 */
+	scsi_hotswap_mountpoint = kern_mount (&scsi_hotswap_fs_type);
+	if (IS_ERR (scsi_hotswap_mountpoint)) {
+		return (-ENODEV);
+	}
+	mntget (scsi_hotswap_mountpoint);
+
+	/*
+	 * Create file command entries in filesystem
+	 */
+	scsi_hotswap_cmd_fs.insert_by_scsi_id = scsi_hotswap_fs_create_file ("insert_by_scsi_id",
+		S_IFREG | S_IRUGO | S_IWUSR,
+		NULL, &scsi_hotswap_insert_by_scsi_id_file_operations);
+
+	scsi_hotswap_cmd_fs.remove_by_scsi_id = scsi_hotswap_fs_create_file ("remove_by_scsi_id",
+		S_IFREG | S_IRUGO | S_IWUSR,
+		NULL, &scsi_hotswap_remove_by_scsi_id_file_operations);
+
+	scsi_hotswap_cmd_fs.insert_by_fc_wwn = scsi_hotswap_fs_create_file ("insert_by_fc_wwn",
+		S_IFREG | S_IRUGO | S_IWUSR,
+		NULL, &scsi_hotswap_insert_by_fc_wwn_file_operations);
+
+	scsi_hotswap_cmd_fs.remove_by_fc_wwn = scsi_hotswap_fs_create_file ("remove_by_fc_wwn",
+		S_IFREG | S_IRUGO | S_IWUSR,
+		NULL, &scsi_hotswap_remove_by_fc_wwn_file_operations);
+
+	scsi_hotswap_cmd_fs.insert_by_fc_wwn_wildcard = scsi_hotswap_fs_create_file ("insert_by_fc_wwn_wildcard",
+		S_IFREG | S_IRUGO | S_IWUSR,
+		NULL, &scsi_hotswap_insert_by_fc_wwn_wildcard_file_operations);
+
+	scsi_hotswap_cmd_fs.remove_by_fc_wwn_wildcard = scsi_hotswap_fs_create_file ("remove_by_fc_wwn_wildcard",
+		S_IFREG | S_IRUGO | S_IWUSR,
+		NULL, &scsi_hotswap_remove_by_fc_wwn_wildcard_file_operations);
+
+	return (result);
+}
+
+static void __exit scsi_hotswap_exit (void) {
+	/*
+	 * Delete all files in filesystem
+	 */
+	fs_remove_file (scsi_hotswap_cmd_fs.insert_by_scsi_id);
+	fs_remove_file (scsi_hotswap_cmd_fs.remove_by_scsi_id);
+	fs_remove_file (scsi_hotswap_cmd_fs.insert_by_fc_wwn);
+	fs_remove_file (scsi_hotswap_cmd_fs.remove_by_fc_wwn);
+	fs_remove_file (scsi_hotswap_cmd_fs.insert_by_fc_wwn_wildcard);
+	fs_remove_file (scsi_hotswap_cmd_fs.remove_by_fc_wwn_wildcard);
+
+	/*
+	 * Remove mount
+	 */
+	mntput (scsi_hotswap_mountpoint);
+
+	/*
+	 * Remove filesystem registration
+	 */
+	unregister_filesystem (&scsi_hotswap_fs_type);
+}
+
+module_init(scsi_hotswap_init);
+module_exit(scsi_hotswap_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_LICENSE("GPL");
diff -uNr linux-2.5.44-qla/drivers/scsi/qla2xxx/qla2x00.c linux-2.5.44-scsi-hotswap/drivers/scsi/qla2xxx/qla2x00.c
--- linux-2.5.44-qla/drivers/scsi/qla2xxx/qla2x00.c	Wed Oct 23 15:47:43 2002
+++ linux-2.5.44-scsi-hotswap/drivers/scsi/qla2xxx/qla2x00.c	Wed Oct 23 15:47:03 2002
@@ -244,6 +244,7 @@
 STATIC uint8_t  qla2x00_register_with_Linux(scsi_qla_host_t *ha, uint8_t maxchannels);
 STATIC int   qla2x00_done(scsi_qla_host_t *);
 //STATIC void qla2x00_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
+int qla2x00_get_scsi_info_from_wwn (int mode, unsigned long long wwn, int *host, int *channel, int *lun, int *id);
 
 STATIC void
 qla2x00_timer(scsi_qla_host_t *);
@@ -2037,6 +2038,7 @@
 	host->can_queue = max_srbs;  /* default value:-MAX_SRBS(4096)  */
 	host->cmd_per_lun = 1;
 //	host->select_queue_depths = qla2x00_select_queue_depth;
+	host->hostt->get_scsi_info_from_wwn = qla2x00_get_scsi_info_from_wwn;
 
 	host->n_io_port = 0xFF;
 
@@ -3989,6 +3991,80 @@
 }
 #endif
 
+union wwnmap {
+	unsigned long long wwn;
+	unsigned char wwn_u8[8];
+};
+
+int qla2x00_get_scsi_info_from_wwn (int mode,
+	unsigned long long wwn,
+	int *host,
+	int *channel,
+	int *lun,
+	int *id) {
+
+scsi_qla_host_t *list;
+Scsi_Device *scsi_device;
+union wwnmap wwncompare;
+union wwnmap wwncompare2;
+int i, j, k;
+
+	/*
+	 * Retrieve big endian version of world wide name
+	 */
+	wwncompare2.wwn = wwn;
+	for (j = 0, k=7; j < 8; j++, k--) {
+		wwncompare.wwn_u8[j] = wwncompare2.wwn_u8[k];
+	}
+
+	/*
+	 * query all hosts searching for WWN
+	 */
+	for (list = qla2x00_hostlist; list; list = list->next) {
+		for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+			/*
+			 * Scan all devices in FibreChannel database
+			 * if WWN match found, return SCSI device information
+			 */
+			if (memcmp (wwncompare.wwn_u8, list->fc_db[i].wwn, 8) == 0) {
+				/*
+				 * If inserting, avoid scan for channel and lun information
+				 */
+				if (mode == 0) {
+					*channel = 0;
+					*lun = 0;
+					*host = list->host->host_no;
+					*id = i;
+					return (0);
+				}
+			
+
+				/*
+				 * WWN matches, find channel and lun information from scsi
+				 * device
+				 */
+				for (scsi_device = list->host->host_queue; scsi_device; scsi_device = scsi_device->next) {
+					if (scsi_device->id == i) {
+						*channel = scsi_device->channel;
+						*lun = scsi_device->lun;
+						break;
+					}
+				}
+				if (scsi_device == 0) {
+					return (-ENOENT);
+				}
+				/*
+				 * Device found, return all data
+				 */
+				*host = list->host->host_no;
+				*id = i;
+				return (0);
+			} /* memcmp */
+		} /* i < MAXFIBREDEVICES */
+	}
+	return (-ENOENT);
+}
+
 /**************************************************************************
 *   qla2x00_select_queue_depth
 *
diff -uNr linux-2.5.44-qla/drivers/scsi/scsi.c linux-2.5.44-scsi-hotswap/drivers/scsi/scsi.c
--- linux-2.5.44-qla/drivers/scsi/scsi.c	Fri Oct 18 21:01:54 2002
+++ linux-2.5.44-scsi-hotswap/drivers/scsi/scsi.c	Wed Oct 23 15:15:07 2002
@@ -413,6 +413,9 @@
 				 * allow us to more easily figure out whether we should
 				 * do anything here or not.
 				 */
+
+				spin_lock (&host->host_queue_lock);
+
 				for (SDpnt = host->host_queue;
 				     SDpnt;
 				     SDpnt = SDpnt->next) {
@@ -430,6 +433,9 @@
                                                 break;
                                         }
 				}
+
+				spin_unlock (&host->host_queue_lock);
+
 				if (SDpnt) {
 					/*
 					 * Some other device in this cluster is busy.
@@ -1694,6 +1700,8 @@
 		len += size;
 		pos = begin + len;
 #endif
+		spin_lock (&HBA_ptr->host_queue_lock);
+
 		for (scd = HBA_ptr->host_queue; scd; scd = scd->next) {
 			proc_print_scsidevice(scd, buffer, &size, len);
 			len += size;
@@ -1706,6 +1714,8 @@
 			if (pos > offset + length)
 				goto stop_output;
 		}
+
+		spin_unlock (&HBA_ptr->host_queue_lock);
 	}
 
 stop_output:
@@ -1864,6 +1874,8 @@
 		if (!HBA_ptr)
 			goto out;
 
+		spin_lock (&HBA_ptr->host_queue_lock);
+
 		for (scd = HBA_ptr->host_queue; scd; scd = scd->next) {
 			if ((scd->channel == channel
 			     && scd->id == id
@@ -1872,6 +1884,8 @@
 			}
 		}
 
+		spin_unlock (&HBA_ptr->host_queue_lock);
+
 		err = -ENOSYS;
 		if (scd)
 			goto out;	/* We do not yet support unplugging */
@@ -1910,6 +1924,8 @@
 		if (!HBA_ptr)
 			goto out;
 
+		spin_lock (&HBA_ptr->host_queue_lock);
+
 		for (scd = HBA_ptr->host_queue; scd; scd = scd->next) {
 			if ((scd->channel == channel
 			     && scd->id == id
@@ -1918,6 +1934,8 @@
 			}
 		}
 
+		spin_unlock (&HBA_ptr->host_queue_lock);
+
 		if (scd == NULL)
 			goto out;	/* there is no such device attached */
 
@@ -1951,9 +1969,14 @@
 			if (scd->prev != NULL)
 				scd->prev->next = scd->next;
 
+			spin_lock (&HBA_ptr->host_queue_lock);
+
 			if (HBA_ptr->host_queue == scd) {
 				HBA_ptr->host_queue = scd->next;
 			}
+
+			spin_unlock (&HBA_ptr->host_queue_lock);
+
 			blk_cleanup_queue(&scd->request_queue);
 			if (scd->inquiry)
 				kfree(scd->inquiry);
@@ -1997,11 +2020,15 @@
 
 	for (shpnt = scsi_host_get_next(NULL); shpnt;
 	     shpnt = scsi_host_get_next(shpnt)) {
+		spin_lock (&shpnt->host_queue_lock);
+
 		for (SDpnt = shpnt->host_queue; SDpnt;
 		     SDpnt = SDpnt->next) {
 			if (tpnt->detect)
 				SDpnt->attached += (*tpnt->detect) (SDpnt);
 		}
+
+		spin_unlock (&shpnt->host_queue_lock);
 	}
 
 	/*
@@ -2017,6 +2044,8 @@
 	 */
 	for (shpnt = scsi_host_get_next(NULL); shpnt;
 	     shpnt = scsi_host_get_next(shpnt)) {
+		spin_lock (&shpnt->host_queue_lock);
+
 		for (SDpnt = shpnt->host_queue; SDpnt;
 		     SDpnt = SDpnt->next) {
 			if (tpnt->attach)
@@ -2032,6 +2061,8 @@
 					out_of_space = 1;
 			}
 		}
+
+		spin_unlock (&shpnt->host_queue_lock);
 	}
 
 	/*
@@ -2068,6 +2099,8 @@
 
 	for (shpnt = scsi_host_get_next(NULL); shpnt;
 	     shpnt = scsi_host_get_next(shpnt)) {
+		spin_lock (&shpnt->host_queue_lock);
+
 		for (SDpnt = shpnt->host_queue; SDpnt;
 		     SDpnt = SDpnt->next) {
 			if (tpnt->detach)
@@ -2084,6 +2117,8 @@
 				scsi_release_commandblocks(SDpnt);
 			}
 		}
+
+		spin_unlock (&shpnt->host_queue_lock);
 	}
 	/*
 	 * Extract the template from the linked list.
@@ -2154,6 +2189,8 @@
 	for (shpnt = scsi_host_get_next(NULL); shpnt;
 	     shpnt = scsi_host_get_next(shpnt)) {
 		printk(KERN_INFO "h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) (to/cmd to ito) cmd snse result\n");
+		spin_lock (&shpnt->host_queue_lock);
+
 		for (SDpnt = shpnt->host_queue; SDpnt; SDpnt = SDpnt->next) {
 			for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
 				/*  (0) h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) (to/cmd to ito) cmd snse result %d %x      */
@@ -2185,6 +2222,8 @@
 				       SCpnt->result);
 			}
 		}
+
+		spin_unlock (&shpnt->host_queue_lock);
 	}
 #endif	/* CONFIG_SCSI_LOGGING */ /* } */
 }
diff -uNr linux-2.5.44-qla/drivers/scsi/scsi_error.c linux-2.5.44-scsi-hotswap/drivers/scsi/scsi_error.c
--- linux-2.5.44-qla/drivers/scsi/scsi_error.c	Fri Oct 18 21:01:07 2002
+++ linux-2.5.44-scsi-hotswap/drivers/scsi/scsi_error.c	Wed Oct 23 11:48:20 2002
@@ -202,6 +202,8 @@
 	int devices_failed = 0;
 
 
+	spin_lock (&shost->host_queue_lock);
+
 	for (sdev = shost->host_queue; sdev; sdev = sdev->next) {
 		for (scmd = sc_list; scmd; scmd = scmd->bh_next) {
 			if (scmd->device == sdev) {
@@ -227,6 +229,8 @@
 		}
 	}
 
+	spin_unlock (&shost->host_queue_lock);
+
 	SCSI_LOG_ERROR_RECOVERY(2, printk("Total of %d commands on %d"
 					  " devices require eh work\n",
 				  total_failures, devices_failed));
@@ -247,6 +251,8 @@
 	Scsi_Device *sdev;
 	Scsi_Cmnd *scmd;
 
+	spin_lock (&shost->host_queue_lock);
+
 	for (found = 0, sdev = shost->host_queue; sdev; sdev = sdev->next) {
 		for (scmd = sdev->device_queue; scmd; scmd = scmd->next) {
 			if (scsi_eh_eflags_chk(scmd, SCSI_EH_CMD_ERR)) {
@@ -283,6 +289,8 @@
 		}
 	}
 
+	spin_unlock (&shost->host_queue_lock);
+
 	SCSI_LOG_ERROR_RECOVERY(1, scsi_eh_prt_fail_stats(*sc_list, shost));
 
 	if (shost->host_failed != found)
@@ -962,6 +970,8 @@
 
 	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Trying BDR\n", __FUNCTION__));
 
+	spin_lock (&shost->host_queue_lock);
+
 	for (sdev = shost->host_queue; sdev; sdev = sdev->next) {
 		for (scmd = sc_todo; scmd; scmd = scmd->bh_next)
 			if ((scmd->device == sdev) &&
@@ -985,6 +995,7 @@
 							scsi_eh_finish_cmd(scmd, shost);
 					}
 	}
+	spin_unlock (&shost->host_queue_lock);
 
 	return shost->host_failed;
 }
@@ -1016,11 +1027,15 @@
 		/*
 		 * Mark all affected devices to expect a unit attention.
 		 */
+		spin_lock (&scmd->host->host_queue_lock);
+
 		for (sdev = scmd->host->host_queue; sdev; sdev = sdev->next)
 			if (scmd->channel == sdev->channel) {
 				sdev->was_reset = 1;
 				sdev->expecting_cc_ua = 1;
 			}
+
+		spin_unlock (&scmd->host->host_queue_lock);
 	}
 	return rtn;
 }
@@ -1052,11 +1067,13 @@
 		/*
 		 * Mark all affected devices to expect a unit attention.
 		 */
+		spin_lock (&scmd->host->host_queue_lock);
 		for (sdev = scmd->host->host_queue; sdev; sdev = sdev->next)
 			if (scmd->channel == sdev->channel) {
 				sdev->was_reset = 1;
 				sdev->expecting_cc_ua = 1;
 			}
+		spin_unlock (&scmd->host->host_queue_lock);
 	}
 	return rtn;
 }
@@ -1475,6 +1492,8 @@
 	 * requests are started.
 	 */
 	spin_lock_irqsave(shost->host_lock, flags);
+	spin_lock (&shost->host_queue_lock);
+
 	for (sdev = shost->host_queue; sdev; sdev = sdev->next) {
 		request_queue_t *q = &sdev->request_queue;
 
@@ -1487,6 +1506,8 @@
 
 		q->request_fn(q);
 	}
+
+	spin_unlock (&shost->host_queue_lock);
 	spin_unlock_irqrestore(shost->host_lock, flags);
 }
 
diff -uNr linux-2.5.44-qla/drivers/scsi/scsi_lib.c linux-2.5.44-scsi-hotswap/drivers/scsi/scsi_lib.c
--- linux-2.5.44-qla/drivers/scsi/scsi_lib.c	Fri Oct 18 21:01:53 2002
+++ linux-2.5.44-scsi-hotswap/drivers/scsi/scsi_lib.c	Wed Oct 23 11:44:06 2002
@@ -261,6 +261,8 @@
 	if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0) {
 		request_queue_t *q;
 
+		spin_lock (&SHpnt->host_queue_lock);
+
 		for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) {
 			if (((SHpnt->can_queue > 0)
 			     && (SHpnt->host_busy >= SHpnt->can_queue))
@@ -273,6 +275,8 @@
 			q = &SDpnt->request_queue;
 			q->request_fn(q);
 		}
+
+		spin_unlock (&SHpnt->host_queue_lock);
 	}
 
 	/*
@@ -285,6 +289,7 @@
 	 */
 	all_clear = 1;
 	if (SHpnt->some_device_starved) {
+		spin_lock (&SHpnt->host_queue_lock);
 		for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) {
 			request_queue_t *q;
 			if ((SHpnt->can_queue > 0 && (SHpnt->host_busy >= SHpnt->can_queue))
@@ -299,6 +304,7 @@
 			q->request_fn(q);
 			all_clear = 0;
 		}
+		spin_unlock (&SHpnt->host_queue_lock);
 		if (SDpnt == NULL && all_clear) {
 			SHpnt->some_device_starved = 0;
 		}
@@ -1038,8 +1044,13 @@
 
 	SHpnt->host_self_blocked = FALSE;
 	/* Now that we are unblocked, try to start the queues. */
+
+	spin_lock (&SHpnt->host_queue_lock);
+
 	for (SDloop = SHpnt->host_queue; SDloop; SDloop = SDloop->next)
 		scsi_queue_next_request(&SDloop->request_queue, NULL);
+
+	spin_unlock (&SHpnt->host_queue_lock);
 }
 
 /*
@@ -1066,12 +1077,17 @@
 void scsi_report_bus_reset(struct Scsi_Host * SHpnt, int channel)
 {
 	Scsi_Device *SDloop;
+
+	spin_lock (&SHpnt->host_queue_lock);
+
 	for (SDloop = SHpnt->host_queue; SDloop; SDloop = SDloop->next) {
 		if (channel == SDloop->channel) {
 			SDloop->was_reset = 1;
 			SDloop->expecting_cc_ua = 1;
 		}
 	}
+
+	spin_unlock (&SHpnt->host_queue_lock);
 }
 
 /*
diff -uNr linux-2.5.44-qla/drivers/scsi/scsi_scan.c linux-2.5.44-scsi-hotswap/drivers/scsi/scsi_scan.c
--- linux-2.5.44-qla/drivers/scsi/scsi_scan.c	Fri Oct 18 21:02:28 2002
+++ linux-2.5.44-scsi-hotswap/drivers/scsi/scsi_scan.c	Wed Oct 23 11:44:06 2002
@@ -530,6 +530,8 @@
 		/*
 		 * Add it to the end of the shost->host_queue list.
 		 */
+		spin_lock (&shost->host_queue_lock);
+
 		if (shost->host_queue != NULL) {
 			sdev->prev = shost->host_queue;
 			while (sdev->prev->next != NULL)
@@ -538,6 +540,8 @@
 		} else
 			shost->host_queue = sdev;
 
+		spin_unlock (&shost->host_queue_lock);
+
 	}
 	return (sdev);
 }
@@ -554,8 +558,12 @@
 {
 	if (sdev->prev != NULL)
 		sdev->prev->next = sdev->next;
-	else
+	else {
+		spin_lock (&sdev->host->host_queue_lock);
 		sdev->host->host_queue = sdev->next;
+		spin_unlock (&sdev->host->host_queue_lock);
+	}
+
 	if (sdev->next != NULL)
 		sdev->next->prev = sdev->prev;
 
diff -uNr linux-2.5.44-qla/include/linux/scsi_hotswap.h linux-2.5.44-scsi-hotswap/include/linux/scsi_hotswap.h
--- linux-2.5.44-qla/include/linux/scsi_hotswap.h	Wed Dec 31 17:00:00 1969
+++ linux-2.5.44-scsi-hotswap/include/linux/scsi_hotswap.h	Wed Oct 23 11:44:06 2002
@@ -0,0 +1,84 @@
+/*
+ * scsi_hotswap.h
+ *
+ * SCSI/FibreChannel Hotswap userland interface to kernel features
+ * 
+ * Author: MontaVista Software, Inc.
+ *         Steven Dake (sdake@mvista.com)
+ *         source@mvista.com
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this program; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __SCSI_HOTSWAP_H
+#define __SCSI_HOTSWAP_H
+
+/*
+ * Software Interface
+ */
+
+/*
+ * Find a device by host, channel, lun and scsi id and insert it into the system
+ */
+extern int scsi_hotswap_insert_by_scsi_id (unsigned int host,
+	unsigned int channel,
+	unsigned int lun,
+	unsigned int id);
+
+/*
+ * Find a device by host, channel, lun and scsi id and remove it from the system
+ */
+extern int scsi_hotswap_remove_by_scsi_id (unsigned int host,
+	unsigned int channel,
+	unsigned int lun,
+	unsigned int id);
+
+/*
+ * Find a device by host, channel, lun and wwn and insert it into the system
+ */
+extern int scsi_hotswap_insert_by_fc_wwn (unsigned int host,
+	unsigned int channel,
+	unsigned int lun,
+	unsigned long long wwn);
+
+/*
+ * Find a device by host, channel, lun and wwn and remove it from the system
+ */
+extern int scsi_hotswap_remove_by_fc_wwn (unsigned int host,
+	unsigned int channel,
+	unsigned int lun,
+	unsigned long long wwn);
+
+/*
+ * Find a device by WWN, searching all adaptor hosts and channels.
+ * If found, insert it into the system
+ */
+extern int scsi_hotswap_insert_by_fc_wwn_wildcard (unsigned long long wwn);
+
+/*
+ * Find a device by WWN, searching all adaptor hosts and channels.
+ * If found, remove it from the system
+ */
+extern int scsi_hotswap_remove_by_fc_wwn_wildcard (unsigned long long wwn);
+
+#endif /* __SCSI_HOTSWAP_H */

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24  0:48 [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap Steven Dake
@ 2002-10-24 14:25 ` James Bottomley
  2002-10-24 19:40   ` Steven Dake
  2002-10-24 22:32 ` Patrick Mansfield
  2002-10-24 22:36 ` Mike Anderson
  2 siblings, 1 reply; 25+ messages in thread
From: James Bottomley @ 2002-10-24 14:25 UTC (permalink / raw)
  To: Steven Dake; +Cc: linux-scsi

I looked at this briefly last night.  The patch seems to come in three pieces:

1) Add list locking to manipulations of the host device list
2) Add a new filesystem type for exposing SCSI information
3) add a lot more methods for adding and removing SCSI devices.

1) seems to be something we should have

I'm dubious about 2).  Could you explain why you need a new fs interface as 
opposed to using driverfs?

3) duplicates existing functionality and the new bits it does add could be 
done using a hotplug framework.

For all the removes, if you exposed the information you're looking for (FC 
wwn) in driverfs, you could use the existing remove interface.

For the adds, all of this would be finessed by having the FC event that 
detected a new device on the fibre trigger a hotplug event.  You could then 
have the hotplug trigger the existing add device interface to make the 
component configure automatically (hotplug on fibre events like this has been 
a hot item for a while, so having a general interface would be most welcome).

If you must delay configuration and do it by wwn later, you could capture the 
wwns to host,channel,id,lun mappings in a table on the hotplug event (and not 
configure the device) and use the information for later configuration using 
the existing interfaces.

James



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 14:25 ` James Bottomley
@ 2002-10-24 19:40   ` Steven Dake
  2002-10-24 20:02     ` James Bottomley
  0 siblings, 1 reply; 25+ messages in thread
From: Steven Dake @ 2002-10-24 19:40 UTC (permalink / raw)
  To: James Bottomley; +Cc: linux-scsi

James,
Responses below:

James Bottomley wrote:

>I looked at this briefly last night.  The patch seems to come in three pieces:
>
>1) Add list locking to manipulations of the host device list
>2) Add a new filesystem type for exposing SCSI information
>3) add a lot more methods for adding and removing SCSI devices.
>
>1) seems to be something we should have
>
>I'm dubious about 2).  Could you explain why you need a new fs interface as 
>opposed to using driverfs?
>  
>
The main reason I use a new fs interface is this was a port of a 2.4 
driver (and as you know
2.4 doesn't have driverfs:)  Since my customers that are using this 
software are currently
on 2.4, that is my main concern.  I had wanted to see this code reach 
the 2.5 mainline so I
could maintain it in the main kernel instead of as seperate patches for 
each kernel rev.

I plan to produce a now patch that dumps the filesystem interface and 
replaces it with driverfs
files in /sys/bus/scsi.  These things take time, but I hope to be 
finished by October 25th.

>3) duplicates existing functionality and the new bits it does add could be 
>done using a hotplug framework.
>  
>
>For all the removes, if you exposed the information you're looking for (FC 
>wwn) in driverfs, you could use the existing remove interface.
>  
>
The current remove interface is unmaintained, doesn't contain locking, 
and requires
laborious string processing resulting in slow results.  Further there is 
no usage
information (which means the usage must come by looking at 
drivers/scsi/scsi.c
which is beyond most typical users).

Another problem is performance:

Imagine scanning each disk in driverfs looking at its WWN attribute (if 
it has one)
until a match is found.  Assume there are 16 FC devices.  That is 
several hundred syscalls
just to complete one hotswap operation.

The method in the patch takes only two syscalls (open and write) to 
complete a hotswap
operation, independent of the number of FibreChannel devices.  Of 
course, the scanning
still occurs, but through a very fast function call interface (1 call 
per adaptor) as opposed to a slower
syscall interface.

This requires the adaptor to maintain a mapping of WWNs to SCSI IDs, 
however, this is already
required by most FibreChannel firmware I've seen (and hence is available 
in the driver database
already).

>For the adds, all of this would be finessed by having the FC event that 
>detected a new device on the fibre trigger a hotplug event.  You could then 
>have the hotplug trigger the existing add device interface to make the 
>component configure automatically (hotplug on fibre events like this has been 
>a hot item for a while, so having a general interface would be most welcome).
>  
>
Hotplugs on FibreChannel don't trigger "events".  What they can do is 
LIP (loop initialization
procedure) if the device has been configured in it's SCSI code pages to 
do such a thing.  Since this
is device specific I'd hate to rely on it for hotswap.

I do like your idea, though, and if I have a chance this year, I'll 
implement automatic hotplug on new
devices found during a LIP.

>If you must delay configuration and do it by wwn later, you could capture the 
>wwns to host,channel,id,lun mappings in a table on the hotplug event (and not 
>configure the device) and use the information for later configuration using 
>the existing interfaces.
>  
>
I think this would be too slow.  10 msec for my entire hotswap is 
available.  If you calculate 2msec for the actual hotswap disk 
operation, that leaves 8 msec for the rest of the mess.  Scanning 
through tables or scanning tens or hundreds of files through hundreds of 
syscalls may betoo slow.

>James
>
>  
>
Thanks
-steve

>
>
>  
>


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 19:40   ` Steven Dake
@ 2002-10-24 20:02     ` James Bottomley
  2002-10-24 20:45       ` Steven Dake
  2002-10-24 22:58       ` Mike Anderson
  0 siblings, 2 replies; 25+ messages in thread
From: James Bottomley @ 2002-10-24 20:02 UTC (permalink / raw)
  To: Steven Dake; +Cc: linux-scsi

sdake@mvista.com said:
> I plan to produce a now patch that dumps the filesystem interface and
> replaces it with driverfs files in /sys/bus/scsi.  These things take
> time, but I hope to be  finished by October 25th. 

OK, that's good, thanks.

> The current remove interface is unmaintained, doesn't contain locking,
>  and requires laborious string processing resulting in slow results.

It is maintained (well, I was planning on looking after it).  The locking can 
be added (the 1st part of your patch).  It does two in kernel strncmps.  
That's not really slow by most definitions.

> Further there is  no usage information (which means the usage must
> come by looking at  drivers/scsi/scsi.c which is beyond most typical
> users).

I don't really think it's the job of the kernel to conatin usage information.  
That's the job of the user level documentation.

> Imagine scanning each disk in driverfs looking at its WWN attribute
> (if  it has one) until a match is found.  Assume there are 16 FC
> devices.  That is  several hundred syscalls just to complete one
> hotswap operation. 

Why is speed so important?

> This requires the adaptor to maintain a mapping of WWNs to SCSI IDs,
> however, this is already required by most FibreChannel firmware I've
> seen (and hence is available  in the driver database already). 

There will be a point where for a large number of drivers, a linear scan even 
in the kernel will be slower than a good DB lookup in userspace.

> Hotplugs on FibreChannel don't trigger "events".  What they can do is
> LIP (loop initialization procedure) if the device has been configured
> in it's SCSI code pages to  do such a thing.  Since this is device
> specific I'd hate to rely on it for hotswap. 

They don't now, but they should.  The LIP protocol makes the FC driver aware 
of the gain or loss of devices.  This should be communicated to the mid-layer 
and then trigger a hotplug event.  Someone needs to write this, I was just 
wondering if you might.

> I think this would be too slow.  10 msec for my entire hotswap is
> available.  If you calculate 2msec for the actual hotswap disk
> operation, that leaves 8 msec for the rest of the mess.  Scanning
> through tables or scanning tens or hundreds of files through hundreds
> of  syscalls may betoo slow. 

Where does the 10ms figure come from?

James



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 20:02     ` James Bottomley
@ 2002-10-24 20:45       ` Steven Dake
  2002-10-24 21:05           ` Randy.Dunlap
  2002-10-24 23:42         ` James Bottomley
  2002-10-24 22:58       ` Mike Anderson
  1 sibling, 2 replies; 25+ messages in thread
From: Steven Dake @ 2002-10-24 20:45 UTC (permalink / raw)
  To: James Bottomley; +Cc: linux-scsi, linux-kernel

James
Some responses below:

James Bottomley wrote:

>sdake@mvista.com said:
>  
>
>>I plan to produce a now patch that dumps the filesystem interface and
>>replaces it with driverfs files in /sys/bus/scsi.  These things take
>>time, but I hope to be  finished by October 25th. 
>>    
>>
>
>OK, that's good, thanks.
>
>  
>
>>The current remove interface is unmaintained, doesn't contain locking,
>> and requires laborious string processing resulting in slow results.
>>    
>>
>
>It is maintained (well, I was planning on looking after it).  The locking can 
>be added (the 1st part of your patch).  It does two in kernel strncmps.  
>That's not really slow by most definitions.
>  
>
The locking most definately needs to be added to the kernel.  I'm 
surprised the original
patch didn't contain any locking, but then again, my first patch didn't 
either :)

>  
>
>>Further there is  no usage information (which means the usage must
>>come by looking at  drivers/scsi/scsi.c which is beyond most typical
>>users).
>>    
>>
>
>I don't really think it's the job of the kernel to conatin usage information.  
>That's the job of the user level documentation.
>  
>
I've gotten mixed feedback on this.  I'll add you to the list that 
doesn't like this.

perhaps it should be removed (even though it takes up minimal memory).

>  
>
>>Imagine scanning each disk in driverfs looking at its WWN attribute
>>(if  it has one) until a match is found.  Assume there are 16 FC
>>devices.  That is  several hundred syscalls just to complete one
>>hotswap operation. 
>>    
>>
>
>Why is speed so important?
>  
>
Telecoms and Datacoms have told me in numerous conversations that a hotswap
operation should occur in 20msec.  I've arbitrarily set 10msec as my 
target to
ensure that I meet the worse-case bus-is-loaded responses during scans, etc.

I can't mention the names of the telecoms, but several with 10000+ employees
have mentioned it.

>  
>
>>This requires the adaptor to maintain a mapping of WWNs to SCSI IDs,
>>however, this is already required by most FibreChannel firmware I've
>>seen (and hence is available  in the driver database already). 
>>    
>>
>
>There will be a point where for a large number of drivers, a linear scan even 
>in the kernel will be slower than a good DB lookup in userspace.
>  
>
This may be true, but most systems will only have at most 4-5 devices. 
 Theres only
so much room on PCI for FC devices :)

>  
>
>>Hotplugs on FibreChannel don't trigger "events".  What they can do is
>>LIP (loop initialization procedure) if the device has been configured
>>in it's SCSI code pages to  do such a thing.  Since this is device
>>specific I'd hate to rely on it for hotswap. 
>>    
>>
>
>They don't now, but they should.  The LIP protocol makes the FC driver aware 
>of the gain or loss of devices.  This should be communicated to the mid-layer 
>and then trigger a hotplug event.  Someone needs to write this, I was just 
>wondering if you might.
>  
>
I like the idea and it was something I was considering for early next 
year.  Its driver
dependent and until a FC driver is in the kernel, theres not much point 
yet :)

Keep in mind also that a LIP is not always generated on an insertion and 
isn't generated
on a removal at all.  This makes insertion easy but removal still 
requires user intervention.

In Advanced TCA (what spawned this work) a button is pressed to indicate 
hotswap removal
which makes for easy detection of hotswap events.  This is why there are 
kernel interfaces
for removal and insertion (so a kernel driver can be written to detect 
the button press
and remove the devices from the os data structures and then light a blue 
led indicating
safe for removal).

>  
>
>>I think this would be too slow.  10 msec for my entire hotswap is
>>available.  If you calculate 2msec for the actual hotswap disk
>>operation, that leaves 8 msec for the rest of the mess.  Scanning
>>through tables or scanning tens or hundreds of files through hundreds
>>of  syscalls may betoo slow. 
>>    
>>
>
>Where does the 10ms figure come from?
>  
>
See above

Thanks James for reading the code and giving comments!

>James
>
>
>
>
>  
>


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 20:45       ` Steven Dake
@ 2002-10-24 21:05           ` Randy.Dunlap
  2002-10-24 23:42         ` James Bottomley
  1 sibling, 0 replies; 25+ messages in thread
From: Randy.Dunlap @ 2002-10-24 21:05 UTC (permalink / raw)
  To: Steven Dake; +Cc: James Bottomley, linux-scsi, linux-kernel

On Thu, 24 Oct 2002, Steven Dake wrote:

| James
| Some responses below:
|
| James Bottomley wrote:
|
| >sdake@mvista.com said:

| >I don't really think it's the job of the kernel to conatin usage information.
| >That's the job of the user level documentation.
| >
| >
| I've gotten mixed feedback on this.  I'll add you to the list that
| doesn't like this.

add me to that list also.

| perhaps it should be removed (even though it takes up minimal memory).
yes, i agree.

| >>Imagine scanning each disk in driverfs looking at its WWN attribute
| >>(if  it has one) until a match is found.  Assume there are 16 FC
| >>devices.  That is  several hundred syscalls just to complete one
| >>hotswap operation.
| >>
| >>
| >
| >Why is speed so important?
| >
| >
| Telecoms and Datacoms have told me in numerous conversations that a hotswap
| operation should occur in 20msec.  I've arbitrarily set 10msec as my
| target to
| ensure that I meet the worse-case bus-is-loaded responses during scans, etc.
|
| I can't mention the names of the telecoms, but several with 10000+ employees
| have mentioned it.

| >>I think this would be too slow.  10 msec for my entire hotswap is
| >>available.  If you calculate 2msec for the actual hotswap disk
| >>operation, that leaves 8 msec for the rest of the mess.  Scanning
| >>through tables or scanning tens or hundreds of files through hundreds
| >>of  syscalls may betoo slow.
| >>
| >
| >Where does the 10ms figure come from?
| >
| See above

I've already ask Steve about this and received his answers.
Can't say that I agree with them though, so I asked someone from
a Telecom Equipment Mfr. about this.  He said that it's just for
equipment testing, where technicians verify that hotswap works,
and they are impatient to wait, so they practice surprise removal
instead of coordinated removal.  He doesn't think that's how it's
actually done out in the field, just in test labs.

Preface question:  does cPCI support surprise removal (in the
PICMG specs, not in some implementation)?  I know that PCI hotplug
doesn't support surprise removal, only "coordinated" removal.

So the question that has to be answered IMO is:  do we want to
support surprise removal for something like manufacturing test,
which doesn't abide by the coordinated removal protocol?

or:  Do we have to support surprise removal, only because it can't
be prevented?  I expect that this is the case, but I still don't
see or understand the 20 ms time requirement.

-- 
~Randy


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
@ 2002-10-24 21:05           ` Randy.Dunlap
  0 siblings, 0 replies; 25+ messages in thread
From: Randy.Dunlap @ 2002-10-24 21:05 UTC (permalink / raw)
  To: Steven Dake; +Cc: James Bottomley, linux-scsi, linux-kernel

On Thu, 24 Oct 2002, Steven Dake wrote:

| James
| Some responses below:
|
| James Bottomley wrote:
|
| >sdake@mvista.com said:

| >I don't really think it's the job of the kernel to conatin usage information.
| >That's the job of the user level documentation.
| >
| >
| I've gotten mixed feedback on this.  I'll add you to the list that
| doesn't like this.

add me to that list also.

| perhaps it should be removed (even though it takes up minimal memory).
yes, i agree.

| >>Imagine scanning each disk in driverfs looking at its WWN attribute
| >>(if  it has one) until a match is found.  Assume there are 16 FC
| >>devices.  That is  several hundred syscalls just to complete one
| >>hotswap operation.
| >>
| >>
| >
| >Why is speed so important?
| >
| >
| Telecoms and Datacoms have told me in numerous conversations that a hotswap
| operation should occur in 20msec.  I've arbitrarily set 10msec as my
| target to
| ensure that I meet the worse-case bus-is-loaded responses during scans, etc.
|
| I can't mention the names of the telecoms, but several with 10000+ employees
| have mentioned it.

| >>I think this would be too slow.  10 msec for my entire hotswap is
| >>available.  If you calculate 2msec for the actual hotswap disk
| >>operation, that leaves 8 msec for the rest of the mess.  Scanning
| >>through tables or scanning tens or hundreds of files through hundreds
| >>of  syscalls may betoo slow.
| >>
| >
| >Where does the 10ms figure come from?
| >
| See above

I've already ask Steve about this and received his answers.
Can't say that I agree with them though, so I asked someone from
a Telecom Equipment Mfr. about this.  He said that it's just for
equipment testing, where technicians verify that hotswap works,
and they are impatient to wait, so they practice surprise removal
instead of coordinated removal.  He doesn't think that's how it's
actually done out in the field, just in test labs.

Preface question:  does cPCI support surprise removal (in the
PICMG specs, not in some implementation)?  I know that PCI hotplug
doesn't support surprise removal, only "coordinated" removal.

So the question that has to be answered IMO is:  do we want to
support surprise removal for something like manufacturing test,
which doesn't abide by the coordinated removal protocol?

or:  Do we have to support surprise removal, only because it can't
be prevented?  I expect that this is the case, but I still don't
see or understand the 20 ms time requirement.

-- 
~Randy


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 21:05           ` Randy.Dunlap
  (?)
@ 2002-10-24 21:48           ` Steven Dake
  -1 siblings, 0 replies; 25+ messages in thread
From: Steven Dake @ 2002-10-24 21:48 UTC (permalink / raw)
  To: Randy.Dunlap; +Cc: James Bottomley, linux-scsi, linux-kernel



Randy.Dunlap wrote:

>On Thu, 24 Oct 2002, Steven Dake wrote:
>
>| James
>| Some responses below:
>|
>| James Bottomley wrote:
>|
>| >sdake@mvista.com said:
>
>| >I don't really think it's the job of the kernel to conatin usage information.
>| >That's the job of the user level documentation.
>| >
>| >
>| I've gotten mixed feedback on this.  I'll add you to the list that
>| doesn't like this.
>
>add me to that list also.
>
>| perhaps it should be removed (even though it takes up minimal memory).
>yes, i agree.
>
>| >>Imagine scanning each disk in driverfs looking at its WWN attribute
>| >>(if  it has one) until a match is found.  Assume there are 16 FC
>| >>devices.  That is  several hundred syscalls just to complete one
>| >>hotswap operation.
>| >>
>| >>
>| >
>| >Why is speed so important?
>| >
>| >
>| Telecoms and Datacoms have told me in numerous conversations that a hotswap
>| operation should occur in 20msec.  I've arbitrarily set 10msec as my
>| target to
>| ensure that I meet the worse-case bus-is-loaded responses during scans, etc.
>|
>| I can't mention the names of the telecoms, but several with 10000+ employees
>| have mentioned it.
>
>| >>I think this would be too slow.  10 msec for my entire hotswap is
>| >>available.  If you calculate 2msec for the actual hotswap disk
>| >>operation, that leaves 8 msec for the rest of the mess.  Scanning
>| >>through tables or scanning tens or hundreds of files through hundreds
>| >>of  syscalls may betoo slow.
>| >>
>| >
>| >Where does the 10ms figure come from?
>| >
>| See above
>
>I've already ask Steve about this and received his answers.
>Can't say that I agree with them though, so I asked someone from
>a Telecom Equipment Mfr. about this.  He said that it's just for
>equipment testing, where technicians verify that hotswap works,
>and they are impatient to wait, so they practice surprise removal
>instead of coordinated removal.  He doesn't think that's how it's
>actually done out in the field, just in test labs.
>
>Preface question:  does cPCI support surprise removal (in the
>PICMG specs, not in some implementation)?  I know that PCI hotplug
>doesn't support surprise removal, only "coordinated" removal.
>  
>
PICMG 2.12 doesn't support surprise removal (the hardware does, the 
software doesn't).
The latch must first be popped, then the user must wait for the blue 
led.  If the blue led
isn't lit, the operating system isn't ready for the board to be removed.  

This said, operators are paid 10 bucks an hour to replace boards and you 
know how that goes. :)

For Compact PCI, the surprise removal rate is about 100 msec.  This is 
as fast as the user can
rip the board out of a chassis, meaning if you can light the blue led in 
less then 100 msec
it doesn't matter if the extraction is a surprise or not.

>So the question that has to be answered IMO is:  do we want to
>support surprise removal for something like manufacturing test,
>which doesn't abide by the coordinated removal protocol?
>
>or:  Do we have to support surprise removal, only because it can't
>be prevented?  I expect that this is the case, but I still don't
>see or understand the 20 ms time requirement.
>  
>
For Advanced TCA, there isn't a "latch" required to unpop before 
removing the board.  For
Compact PCI, the latch must be popped, allowing a signal to be sent to 
the board.  For ATCA,
a button is pressed (which is a major complaint of Advanced TCA, boards 
can be removed without
any signaling to the OS that the board is being removed).  I'm not sure 
what the PICMG3 foks
are going to do about that problem.  I'm assuming they are going to 
rework the enumeration of
the hotswap event to be driven by extracting the board instead of by a 
button.

In this case, extremely fast hotswap times are required, because the 
board can be removed
very fast in Advanced TCA (vs the latched method of Compact PCI).

Perhaps this is where the timing constraints originate.

>  
>


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24  0:48 [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap Steven Dake
  2002-10-24 14:25 ` James Bottomley
@ 2002-10-24 22:32 ` Patrick Mansfield
  2002-10-24 22:36 ` Mike Anderson
  2 siblings, 0 replies; 25+ messages in thread
From: Patrick Mansfield @ 2002-10-24 22:32 UTC (permalink / raw)
  To: Steven Dake; +Cc: linux-scsi

On Wed, Oct 23, 2002 at 05:48:46PM -0700, Steven Dake wrote:
> linux-scsi,
> 
> 

> diff -uNr linux-2.5.44-qla/drivers/scsi/scsi_error.c linux-2.5.44-scsi-hotswap/drivers/scsi/scsi_error.c
> --- linux-2.5.44-qla/drivers/scsi/scsi_error.c	Fri Oct 18 21:01:07 2002
> +++ linux-2.5.44-scsi-hotswap/drivers/scsi/scsi_error.c	Wed Oct 23 11:48:20 2002

> @@ -962,6 +970,8 @@
>  
>  	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Trying BDR\n", __FUNCTION__));
>  
> +	spin_lock (&shost->host_queue_lock);
> +
>  	for (sdev = shost->host_queue; sdev; sdev = sdev->next) {
>  		for (scmd = sc_todo; scmd; scmd = scmd->bh_next)
>  			if ((scmd->device == sdev) &&
> @@ -985,6 +995,7 @@
>  							scsi_eh_finish_cmd(scmd, shost);
>  					}
>  	}
> +	spin_unlock (&shost->host_queue_lock);
>  
>  	return shost->host_failed;
>  }

The bus device reset functions are allowed sleep, so you cannot hold a lock
while calling them.

-- Patrick Mansfield

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24  0:48 [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap Steven Dake
  2002-10-24 14:25 ` James Bottomley
  2002-10-24 22:32 ` Patrick Mansfield
@ 2002-10-24 22:36 ` Mike Anderson
  2002-10-24 22:47   ` Steven Dake
  2 siblings, 1 reply; 25+ messages in thread
From: Mike Anderson @ 2002-10-24 22:36 UTC (permalink / raw)
  To: Steven Dake; +Cc: linux-scsi

Steven Dake [sdake@mvista.com] wrote:
> +static char scsi_hotswap_insert_by_scsi_id_usage[] = {
> +	"Usage: echo \"[host] [channel] [lun] [id]\" > insert_by_scsi_id\n"
> +};
> +

Why is the interface lun id istead of id lun.
The same for lun wwn instead of wwn lun.

-andmike
--
Michael Anderson
andmike@us.ibm.com


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 22:36 ` Mike Anderson
@ 2002-10-24 22:47   ` Steven Dake
  0 siblings, 0 replies; 25+ messages in thread
From: Steven Dake @ 2002-10-24 22:47 UTC (permalink / raw)
  To: Mike Anderson; +Cc: linux-scsi

Thanks for pointing that out.  I fixed this once but must have used the 
wrong set of code
when starting this patch.  I'll fix.

Thanks again!
-steve

Mike Anderson wrote:

>Steven Dake [sdake@mvista.com] wrote:
>  
>
>>+static char scsi_hotswap_insert_by_scsi_id_usage[] = {
>>+	"Usage: echo \"[host] [channel] [lun] [id]\" > insert_by_scsi_id\n"
>>+};
>>+
>>    
>>
>
>Why is the interface lun id istead of id lun.
>The same for lun wwn instead of wwn lun.
>
>-andmike
>--
>Michael Anderson
>andmike@us.ibm.com
>
>
>
>  
>


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 20:02     ` James Bottomley
  2002-10-24 20:45       ` Steven Dake
@ 2002-10-24 22:58       ` Mike Anderson
  1 sibling, 0 replies; 25+ messages in thread
From: Mike Anderson @ 2002-10-24 22:58 UTC (permalink / raw)
  To: James Bottomley; +Cc: Steven Dake, linux-scsi

James Bottomley [James.Bottomley@steeleye.com] wrote:
> sdake@mvista.com said:
> > I plan to produce a now patch that dumps the filesystem interface and
> > replaces it with driverfs files in /sys/bus/scsi.  These things take
> > time, but I hope to be  finished by October 25th. 
> 
> OK, that's good, thanks.
> 

A note here is that the SCSI device model still may need to be altered. I
am having issues of trying to fill out support and in looks like we
might have to restructure a few things. 

If the nodes are structure under your own directory they should be ok.

It makes a asymmetric interface, but some parameters can be applied on
removal by a cd to the correct leaf node.

Lock operations are somewhat simplified if we convert some of these
operations to the device model.

> There will be a point where for a large number of drivers, a linear scan even 
> in the kernel will be slower than a good DB lookup in userspace.
> 
> > Hotplugs on FibreChannel don't trigger "events".  What they can do is
> > LIP (loop initialization procedure) if the device has been configured
> > in it's SCSI code pages to  do such a thing.  Since this is device
> > specific I'd hate to rely on it for hotswap. 
> 
> They don't now, but they should.  The LIP protocol makes the FC driver aware 
> of the gain or loss of devices.  This should be communicated to the mid-layer 
> and then trigger a hotplug event.  Someone needs to write this, I was just 
> wondering if you might.

In switched FC fabrics you do receive SCNs if you have registered for
them which most adapters do. 

We already have interface support from the device model we just need to make the
calls.

-andmike
--
Michael Anderson
andmike@us.ibm.com


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 21:05           ` Randy.Dunlap
@ 2002-10-24 23:00             ` Scott Murray
  -1 siblings, 0 replies; 25+ messages in thread
From: Scott Murray @ 2002-10-24 23:00 UTC (permalink / raw)
  To: Randy.Dunlap; +Cc: Steven Dake, James Bottomley, linux-scsi, linux-kernel

On Thu, 24 Oct 2002, Randy.Dunlap wrote:

> Preface question:  does cPCI support surprise removal (in the
> PICMG specs, not in some implementation)?  I know that PCI hotplug
> doesn't support surprise removal, only "coordinated" removal.

No, according to PICMG 2.1 R2.0, suprise removal is "non-compliant".

> So the question that has to be answered IMO is:  do we want to
> support surprise removal for something like manufacturing test,
> which doesn't abide by the coordinated removal protocol?
>
> or:  Do we have to support surprise removal, only because it can't
> be prevented?  I expect that this is the case, but I still don't
> see or understand the 20 ms time requirement.

I've not implemented it yet, but I'm pretty sure I can detect surprise
extractions in my cPCI driver.  The only thing holding me back at the
moment is that there's no clear way to report this status change via
pcihpfs without doing something a bit funky like reporting "-1" in the
"adapter" node.

Scott


-- 
Scott Murray
SOMA Networks, Inc.
Toronto, Ontario
e-mail: scottm@somanetworks.com


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
@ 2002-10-24 23:00             ` Scott Murray
  0 siblings, 0 replies; 25+ messages in thread
From: Scott Murray @ 2002-10-24 23:00 UTC (permalink / raw)
  To: Randy.Dunlap; +Cc: Steven Dake, James Bottomley, linux-scsi, linux-kernel

On Thu, 24 Oct 2002, Randy.Dunlap wrote:

> Preface question:  does cPCI support surprise removal (in the
> PICMG specs, not in some implementation)?  I know that PCI hotplug
> doesn't support surprise removal, only "coordinated" removal.

No, according to PICMG 2.1 R2.0, suprise removal is "non-compliant".

> So the question that has to be answered IMO is:  do we want to
> support surprise removal for something like manufacturing test,
> which doesn't abide by the coordinated removal protocol?
>
> or:  Do we have to support surprise removal, only because it can't
> be prevented?  I expect that this is the case, but I still don't
> see or understand the 20 ms time requirement.

I've not implemented it yet, but I'm pretty sure I can detect surprise
extractions in my cPCI driver.  The only thing holding me back at the
moment is that there's no clear way to report this status change via
pcihpfs without doing something a bit funky like reporting "-1" in the
"adapter" node.

Scott


-- 
Scott Murray
SOMA Networks, Inc.
Toronto, Ontario
e-mail: scottm@somanetworks.com


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 23:00             ` Scott Murray
  (?)
@ 2002-10-24 23:22             ` Greg KH
  2002-10-24 23:48               ` Steven Dake
  2002-10-25  0:18                 ` Scott Murray
  -1 siblings, 2 replies; 25+ messages in thread
From: Greg KH @ 2002-10-24 23:22 UTC (permalink / raw)
  To: Scott Murray
  Cc: Randy.Dunlap, Steven Dake, James Bottomley, linux-scsi, linux-kernel

On Thu, Oct 24, 2002 at 07:00:23PM -0400, Scott Murray wrote:
> 
> I've not implemented it yet, but I'm pretty sure I can detect surprise
> extractions in my cPCI driver.  The only thing holding me back at the
> moment is that there's no clear way to report this status change via
> pcihpfs without doing something a bit funky like reporting "-1" in the
> "adapter" node.

Why would you need to report anything other than if the card is present
or not?  What would a "supprise" removal cause you to do differently?
Hm, well I guess we should be extra careful in trying to shut down any
driver bound to that card...

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 20:45       ` Steven Dake
  2002-10-24 21:05           ` Randy.Dunlap
@ 2002-10-24 23:42         ` James Bottomley
  2002-10-24 23:52           ` Jeff Garzik
  1 sibling, 1 reply; 25+ messages in thread
From: James Bottomley @ 2002-10-24 23:42 UTC (permalink / raw)
  To: Steven Dake; +Cc: linux-scsi, linux-kernel

> The locking most definately needs to be added to the kernel.  I'm
> surprised the original patch didn't contain any locking, but then
> again, my first patch didn't  either:) 

When I first read the SCSI code many years ago, I found surprise wasn't 
adequate and I was forced to resort to astonishment.  It's being cleaned up 
slowly.

Originally hot removal/insertion was the exception, so nobody tripped over the 
locking issue.  Now it's fast becoming the rule.

> This may be true, but most systems will only have at most 4-5 devices.
> 
>  Theres only so much room on PCI for FC devices :) 

I have to think about other SCSI systems as well.  Some IBM beasties have > 
256 PCI slots.  Infiniband is threatening direct bus-fibre attachment.

> In Advanced TCA (what spawned this work) a button is pressed to
> indicate  hotswap removal which makes for easy detection of hotswap
> events.  This is why there are  kernel interfaces for removal and
> insertion (so a kernel driver can be written to detect  the button
> press and remove the devices from the os data structures and then
> light a blue  led indicating safe for removal). 

OK, I understand what's going on now.  It's no different from those hotplug 
PCI busses where you press the button and a second or so later the LED goes 
out and you can remove the card.  10ms sounds rather a short maximum time for 
a technician to wait for a light to go out....I suppose Telco technicians are 
rather impatient.

I really think you need to lengthen this interval.  The kernel is moving 
towards this type of hotplug infrastructure which you can easily leverage (or 
even help build), but it's definitely going to be mainly in user space.

James




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 23:22             ` Greg KH
@ 2002-10-24 23:48               ` Steven Dake
  2002-10-25  0:20                 ` Jeff Garzik
  2002-10-25 10:04                 ` Alan Cox
  2002-10-25  0:18                 ` Scott Murray
  1 sibling, 2 replies; 25+ messages in thread
From: Steven Dake @ 2002-10-24 23:48 UTC (permalink / raw)
  To: Greg KH
  Cc: Scott Murray, Randy.Dunlap, James Bottomley, linux-scsi, linux-kernel

Montavista has discussed at length Compact PCI hotswap using surprise 
removal events.

The key feature of any hotswap operation that happens in a surprise 
fashion is that
the device driver might want a hint that the hardware is no longer 
present so it can
immediatly dump its buffers/io maps/etc and totally stop accessing the 
device.  An
expected removal, on the other hand, would give the device driver time 
to flush its
buffers (for example a scsi driver could dump its outstanding queued 
scsi messages).
Once the driver is done accessing the device, the blue led on the 
CompactPCI board
can be lit and it can be removed.

This is the main difference.  Since the driver model of Linux doesn't 
support a surprise
extract method call for drivers, I don't think its been implemented 
here.  Further the
drivers must be modified to actually use the hint instead of doing its 
normal shutdown
operation.

Surprise extraction is not a simple problem especially to ensure the 
device drivers exit
cleanly without dumping more data on the PCI bus to a PCI device that 
may not
exist.

Thanks!
-steve

Greg KH wrote:

>On Thu, Oct 24, 2002 at 07:00:23PM -0400, Scott Murray wrote:
>  
>
>>I've not implemented it yet, but I'm pretty sure I can detect surprise
>>extractions in my cPCI driver.  The only thing holding me back at the
>>moment is that there's no clear way to report this status change via
>>pcihpfs without doing something a bit funky like reporting "-1" in the
>>"adapter" node.
>>    
>>
>
>Why would you need to report anything other than if the card is present
>or not?  What would a "supprise" removal cause you to do differently?
>Hm, well I guess we should be extra careful in trying to shut down any
>driver bound to that card...
>
>thanks,
>
>greg k-h
>
>
>
>  
>


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 23:42         ` James Bottomley
@ 2002-10-24 23:52           ` Jeff Garzik
  2002-10-27 15:08             ` Rob Landley
  0 siblings, 1 reply; 25+ messages in thread
From: Jeff Garzik @ 2002-10-24 23:52 UTC (permalink / raw)
  To: James Bottomley; +Cc: Steven Dake, linux-scsi, linux-kernel

James Bottomley wrote:

>>n Advanced TCA (what spawned this work) a button is pressed to
>>indicate  hotswap removal which makes for easy detection of hotswap
>>events.  This is why there are  kernel interfaces for removal and
>>insertion (so a kernel driver can be written to detect  the button
>>press and remove the devices from the os data structures and then
>>light a blue  led indicating safe for removal). 
>>    
>>
>
>OK, I understand what's going on now.  It's no different from those hotplug 
>PCI busses where you press the button and a second or so later the LED goes 
>out and you can remove the card.  10ms sounds rather a short maximum time for 
>a technician to wait for a light to go out....I suppose Telco technicians are 
>rather impatient.
>
>I really think you need to lengthen this interval.  The kernel is moving 
>towards this type of hotplug infrastructure which you can easily leverage (or 
>even help build), but it's definitely going to be mainly in user space.
>  
>


Caveat coder -- you also have to handle the case where the device is 
already gone, by the time you are notified of the hot-unplug event. 
 Some ejections are less friendly than others...  though from a SCSI 
standpoint, hopefully that case is easier -- error out all I/Os in 
flight, and unregister the host and device structures associated with 
the recently-removed host.  The devil, of course, is in the details ;-)

    Jeff





^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 23:22             ` Greg KH
@ 2002-10-25  0:18                 ` Scott Murray
  2002-10-25  0:18                 ` Scott Murray
  1 sibling, 0 replies; 25+ messages in thread
From: Scott Murray @ 2002-10-25  0:18 UTC (permalink / raw)
  To: Greg KH
  Cc: Randy.Dunlap, Steven Dake, James Bottomley, linux-scsi, linux-kernel

On Thu, 24 Oct 2002, Greg KH wrote:

> On Thu, Oct 24, 2002 at 07:00:23PM -0400, Scott Murray wrote:
> >
> > I've not implemented it yet, but I'm pretty sure I can detect surprise
> > extractions in my cPCI driver.  The only thing holding me back at the
> > moment is that there's no clear way to report this status change via
> > pcihpfs without doing something a bit funky like reporting "-1" in the
> > "adapter" node.
>
> Why would you need to report anything other than if the card is present
> or not?  What would a "supprise" removal cause you to do differently?

Thinking about it a bit more, my idea to use -1 is indeed unnecessary,
since userspace code can check if the adapter node changes to 0 before
it itself writes a 0 to it.  If multiple users/software play around with
the nodes at the same time, they'll get what's coming to them...

> Hm, well I guess we should be extra careful in trying to shut down any
> driver bound to that card...

Yeah, as Steven mentions in his reply, Linux drivers don't handle this
well at the moment.

Scott


-- 
Scott Murray
SOMA Networks, Inc.
Toronto, Ontario
e-mail: scottm@somanetworks.com



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
@ 2002-10-25  0:18                 ` Scott Murray
  0 siblings, 0 replies; 25+ messages in thread
From: Scott Murray @ 2002-10-25  0:18 UTC (permalink / raw)
  To: Greg KH
  Cc: Randy.Dunlap, Steven Dake, James Bottomley, linux-scsi, linux-kernel

On Thu, 24 Oct 2002, Greg KH wrote:

> On Thu, Oct 24, 2002 at 07:00:23PM -0400, Scott Murray wrote:
> >
> > I've not implemented it yet, but I'm pretty sure I can detect surprise
> > extractions in my cPCI driver.  The only thing holding me back at the
> > moment is that there's no clear way to report this status change via
> > pcihpfs without doing something a bit funky like reporting "-1" in the
> > "adapter" node.
>
> Why would you need to report anything other than if the card is present
> or not?  What would a "supprise" removal cause you to do differently?

Thinking about it a bit more, my idea to use -1 is indeed unnecessary,
since userspace code can check if the adapter node changes to 0 before
it itself writes a 0 to it.  If multiple users/software play around with
the nodes at the same time, they'll get what's coming to them...

> Hm, well I guess we should be extra careful in trying to shut down any
> driver bound to that card...

Yeah, as Steven mentions in his reply, Linux drivers don't handle this
well at the moment.

Scott


-- 
Scott Murray
SOMA Networks, Inc.
Toronto, Ontario
e-mail: scottm@somanetworks.com



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 23:48               ` Steven Dake
@ 2002-10-25  0:20                 ` Jeff Garzik
  2002-10-25 10:04                 ` Alan Cox
  1 sibling, 0 replies; 25+ messages in thread
From: Jeff Garzik @ 2002-10-25  0:20 UTC (permalink / raw)
  To: Steven Dake
  Cc: Greg KH, Scott Murray, Randy.Dunlap, James Bottomley, linux-scsi,
	linux-kernel

Steven Dake wrote:

> Montavista has discussed at length Compact PCI hotswap using surprise 
> removal events.
>
> The key feature of any hotswap operation that happens in a surprise 
> fashion is that
> the device driver might want a hint that the hardware is no longer 
> present so it can
> immediatly dump its buffers/io maps/etc and totally stop accessing the 
> device.  An
> expected removal, on the other hand, would give the device driver time 
> to flush its
> buffers (for example a scsi driver could dump its outstanding queued 
> scsi messages).
> Once the driver is done accessing the device, the blue led on the 
> CompactPCI board
> can be lit and it can be removed.
>
> This is the main difference.  Since the driver model of Linux doesn't 
> support a surprise
> extract method call for drivers, I don't think its been implemented 
> here.  Further the
> drivers must be modified to actually use the hint instead of doing its 
> normal shutdown
> operation. 


Wrong.  The _only_ supported method so far has been surprise removal. 
 For years now.  This happens every day in the land of CardBus, which 
was the first "PCI" hotplug implementation in the Linux kernel.  PCI 
HotPlug introduces a new, non-surprise removal.

Thus, the current model should be assumed to be surprise removal, and 
you need an additional notification from the system if a "nice" removal 
is about to occur.

> Surprise extraction is not a simple problem especially to ensure the 
> device drivers exit
> cleanly without dumping more data on the PCI bus to a PCI device that 
> may not
> exist. 

PCI is electrically safe.  Reads to non-existent areas return 
0xffffffff, etc.  Take a look at net drivers some day, we have been 
handling this for years.

Surprise removal is actually easier from many perspectives -- you don't 
have to worry about quiescing the hardware, you simply have to error out 
all I/Os, and clean up the kernel structures that are left behind (host 
info, device info, etc.).  The non-surprise removal is more annoying, in 
that you could potentially have an indefinite wait (and must actively 
avoid such a situation) while shutting down the hardware, completing 
I/Os, etc.

    Jeff





^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 23:48               ` Steven Dake
  2002-10-25  0:20                 ` Jeff Garzik
@ 2002-10-25 10:04                 ` Alan Cox
  1 sibling, 0 replies; 25+ messages in thread
From: Alan Cox @ 2002-10-25 10:04 UTC (permalink / raw)
  To: Steven Dake
  Cc: Greg KH, Scott Murray, Randy.Dunlap, James Bottomley, linux-scsi,
	Linux Kernel Mailing List

On Fri, 2002-10-25 at 00:48, Steven Dake wrote:
> Surprise extraction is not a simple problem especially to ensure the 
> device drivers exit
> cleanly without dumping more data on the PCI bus to a PCI device that 
> may not
> exist.

Thats primarily about resource handling orders. Making sure we don't
release the claimed pci resources in the driver until the driver itself
is sure it has shut up.

I'm doing suprise removal ok with the thinkpad 600 (in 2.4 with some
limits due to the 2.4 pci layer). Network stuff seems to be fine. The
block layer has major issues.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-24 23:52           ` Jeff Garzik
@ 2002-10-27 15:08             ` Rob Landley
  2002-10-27 20:25                 ` Randy.Dunlap
  0 siblings, 1 reply; 25+ messages in thread
From: Rob Landley @ 2002-10-27 15:08 UTC (permalink / raw)
  To: Jeff Garzik, James Bottomley; +Cc: Steven Dake, linux-scsi, linux-kernel

On Thursday 24 October 2002 18:52, Jeff Garzik wrote:
> James Bottomley wrote:
> >>n Advanced TCA (what spawned this work) a button is pressed to
> >>indicate  hotswap removal which makes for easy detection of hotswap
> >>events.  This is why there are  kernel interfaces for removal and
> >>insertion (so a kernel driver can be written to detect  the button
> >>press and remove the devices from the os data structures and then
> >>light a blue  led indicating safe for removal).
> >
> >OK, I understand what's going on now.  It's no different from those
> > hotplug PCI busses where you press the button and a second or so later
> > the LED goes out and you can remove the card.  10ms sounds rather a short
> > maximum time for a technician to wait for a light to go out....I suppose
> > Telco technicians are rather impatient.
> >
> >I really think you need to lengthen this interval.  The kernel is moving
> >towards this type of hotplug infrastructure which you can easily leverage
> > (or even help build), but it's definitely going to be mainly in user
> > space.
>
> Caveat coder -- you also have to handle the case where the device is
> already gone, by the time you are notified of the hot-unplug event.
>  Some ejections are less friendly than others...  though from a SCSI
> standpoint, hopefully that case is easier -- error out all I/Os in
> flight, and unregister the host and device structures associated with
> the recently-removed host.  The devil, of course, is in the details ;-)

Hmmm...  Not being familiar with the SCSI layer but sticking my nose in anyway 
on general block device/mount point hotplug issues:

How hard would it be to write a simple debugging function to lobotomize a 
block device?  (So that all further I/O to that sucker immediately returns an 
error.)  Not just simulating an a hot extraction (or catastrophic failure) of 
a block device, but also something you could use to see how gracefully 
filesystems react.

The reason I ask is there was a discussion a while back about the new lazy 
unmount (umount -l /blah/foo) not always being quite enough, and that 
sometimes what what you want is basically "umount -9 /blah/foo" (ala kill 
-9).  Close all files, reparent all process home directories and chroot mount 
points to a dummy inode, flush all I/O, drive a stake through the 
superblock's heart, and scatter the ashes at sea.  Somebody posted a patch to 
actually do this.  (Against 2.4, i think.)  I could probably dig it up if you 
were curious.  Let's see...

http://marc.theaimsgroup.com/?l=linux-kernel&m=103443466225915&q=raw

The eject command should certainly have an "umount with shotgun" option, so 
zombie processes can't pin your CD in the drive.  (Your average end-user is 
NOT going to be able to grovel through /proc to figure out which processes 
have an open filehandle or home directory under the cdrom mount point so it 
can kill them and get the disk out.  They're going to power cycle the machine 
and eject it while the bios is in charge.  I've done this myself a couple of 
times when I'm in a hurry.)

Anyway, if the block device under the filesystem honestly does go away for 
hotplug eject reasons, the obvious thing to do is umount -9 the sucker 
immediately so userspace can collapse gracefully (or even conceivably 
recover).  The main difference here is that the flushing would all error out 
and get discarded, and this wouldn't always get reported to the user, but 
thanks to write cacheing that's the case anyway.  (Use some variant of 
O_DIRECT or fsync if you care.)  The errors userspace does see switch from 
"all my I/O failed with a media error" to "all my filehandles closed out from 
under me" (and the directory I'm in has been deleted), but that's still 
relatively logical behavior.

Does this sound like it's off in left field?

>     Jeff

Rob

-- 
http://penguicon.sf.net - Terry Pratchett, Eric Raymond, Pete Abrams, Illiad, 
CmdrTaco, liquid nitrogen ice cream, and caffienated jello.  Well why not?

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
  2002-10-27 15:08             ` Rob Landley
@ 2002-10-27 20:25                 ` Randy.Dunlap
  0 siblings, 0 replies; 25+ messages in thread
From: Randy.Dunlap @ 2002-10-27 20:25 UTC (permalink / raw)
  To: Rob Landley
  Cc: Jeff Garzik, James Bottomley, Steven Dake, linux-scsi, linux-kernel

On Sun, 27 Oct 2002, Rob Landley wrote:

(maybe wrap lines around column 70 ? :)

...

Stephen Tweedie did something like this already (for 2.4.19-pre10),
called "testdrive".  It uses loopback over a block device.
He says that it will need modifications to use bio in 2.5.

See here:
http://marc.theaimsgroup.com/?l=linux-kernel&m=102457399020069&w=2

-- 
~Randy

| Hmmm...  Not being familiar with the SCSI layer but sticking my nose in anyway
| on general block device/mount point hotplug issues:
|
| How hard would it be to write a simple debugging function to lobotomize a
| block device?  (So that all further I/O to that sucker immediately returns an
| error.)  Not just simulating an a hot extraction (or catastrophic failure) of
| a block device, but also something you could use to see how gracefully
| filesystems react.
|
| The reason I ask is there was a discussion a while back about the new lazy
| unmount (umount -l /blah/foo) not always being quite enough, and that
| sometimes what what you want is basically "umount -9 /blah/foo" (ala kill
| -9).  Close all files, reparent all process home directories and chroot mount
| points to a dummy inode, flush all I/O, drive a stake through the
| superblock's heart, and scatter the ashes at sea.  Somebody posted a patch to
| actually do this.  (Against 2.4, i think.)  I could probably dig it up if you
| were curious.  Let's see...
|
| http://marc.theaimsgroup.com/?l=linux-kernel&m=103443466225915&q=raw
|
| The eject command should certainly have an "umount with shotgun" option, so
| zombie processes can't pin your CD in the drive.  (Your average end-user is
| NOT going to be able to grovel through /proc to figure out which processes
| have an open filehandle or home directory under the cdrom mount point so it
| can kill them and get the disk out.  They're going to power cycle the machine
| and eject it while the bios is in charge.  I've done this myself a couple of
| times when I'm in a hurry.)
|
| Anyway, if the block device under the filesystem honestly does go away for
| hotplug eject reasons, the obvious thing to do is umount -9 the sucker
| immediately so userspace can collapse gracefully (or even conceivably
| recover).  The main difference here is that the flushing would all error out
| and get discarded, and this wouldn't always get reported to the user, but
| thanks to write cacheing that's the case anyway.  (Use some variant of
| O_DIRECT or fsync if you care.)  The errors userspace does see switch from
| "all my I/O failed with a media error" to "all my filehandles closed out from
| under me" (and the directory I'm in has been deleted), but that's still
| relatively logical behavior.
|
| Does this sound like it's off in left field?
|
| Rob


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap
@ 2002-10-27 20:25                 ` Randy.Dunlap
  0 siblings, 0 replies; 25+ messages in thread
From: Randy.Dunlap @ 2002-10-27 20:25 UTC (permalink / raw)
  To: Rob Landley
  Cc: Jeff Garzik, James Bottomley, Steven Dake, linux-scsi, linux-kernel

On Sun, 27 Oct 2002, Rob Landley wrote:

(maybe wrap lines around column 70 ? :)

...

Stephen Tweedie did something like this already (for 2.4.19-pre10),
called "testdrive".  It uses loopback over a block device.
He says that it will need modifications to use bio in 2.5.

See here:
http://marc.theaimsgroup.com/?l=linux-kernel&m=102457399020069&w=2

-- 
~Randy

| Hmmm...  Not being familiar with the SCSI layer but sticking my nose in anyway
| on general block device/mount point hotplug issues:
|
| How hard would it be to write a simple debugging function to lobotomize a
| block device?  (So that all further I/O to that sucker immediately returns an
| error.)  Not just simulating an a hot extraction (or catastrophic failure) of
| a block device, but also something you could use to see how gracefully
| filesystems react.
|
| The reason I ask is there was a discussion a while back about the new lazy
| unmount (umount -l /blah/foo) not always being quite enough, and that
| sometimes what what you want is basically "umount -9 /blah/foo" (ala kill
| -9).  Close all files, reparent all process home directories and chroot mount
| points to a dummy inode, flush all I/O, drive a stake through the
| superblock's heart, and scatter the ashes at sea.  Somebody posted a patch to
| actually do this.  (Against 2.4, i think.)  I could probably dig it up if you
| were curious.  Let's see...
|
| http://marc.theaimsgroup.com/?l=linux-kernel&m=103443466225915&q=raw
|
| The eject command should certainly have an "umount with shotgun" option, so
| zombie processes can't pin your CD in the drive.  (Your average end-user is
| NOT going to be able to grovel through /proc to figure out which processes
| have an open filehandle or home directory under the cdrom mount point so it
| can kill them and get the disk out.  They're going to power cycle the machine
| and eject it while the bios is in charge.  I've done this myself a couple of
| times when I'm in a hurry.)
|
| Anyway, if the block device under the filesystem honestly does go away for
| hotplug eject reasons, the obvious thing to do is umount -9 the sucker
| immediately so userspace can collapse gracefully (or even conceivably
| recover).  The main difference here is that the flushing would all error out
| and get discarded, and this wouldn't always get reported to the user, but
| thanks to write cacheing that's the case anyway.  (Use some variant of
| O_DIRECT or fsync if you care.)  The errors userspace does see switch from
| "all my I/O failed with a media error" to "all my filehandles closed out from
| under me" (and the directory I'm in has been deleted), but that's still
| relatively logical behavior.
|
| Does this sound like it's off in left field?
|
| Rob


^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2002-10-27 20:25 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-10-24  0:48 [PATCH] [RFC] Advanced TCA SCSI Disk Hotswap Steven Dake
2002-10-24 14:25 ` James Bottomley
2002-10-24 19:40   ` Steven Dake
2002-10-24 20:02     ` James Bottomley
2002-10-24 20:45       ` Steven Dake
2002-10-24 21:05         ` Randy.Dunlap
2002-10-24 21:05           ` Randy.Dunlap
2002-10-24 21:48           ` Steven Dake
2002-10-24 23:00           ` Scott Murray
2002-10-24 23:00             ` Scott Murray
2002-10-24 23:22             ` Greg KH
2002-10-24 23:48               ` Steven Dake
2002-10-25  0:20                 ` Jeff Garzik
2002-10-25 10:04                 ` Alan Cox
2002-10-25  0:18               ` Scott Murray
2002-10-25  0:18                 ` Scott Murray
2002-10-24 23:42         ` James Bottomley
2002-10-24 23:52           ` Jeff Garzik
2002-10-27 15:08             ` Rob Landley
2002-10-27 20:25               ` Randy.Dunlap
2002-10-27 20:25                 ` Randy.Dunlap
2002-10-24 22:58       ` Mike Anderson
2002-10-24 22:32 ` Patrick Mansfield
2002-10-24 22:36 ` Mike Anderson
2002-10-24 22:47   ` Steven Dake

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.