[SSI] openssi/kernel/cluster/ssi/util ssidev.c, 1.28, 1.29 ssidev_ics.c, 1.15, 1.16

Roger Tsang <[email protected]> Tue, 02 Feb 2010 05:23:57 +0000
Newsgroups gmane.linux.cluster.ssic.cvs
Message-ID <[email protected]>
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv20997/cluster/ssi/util

Modified Files:
      Tag: OPENSSI-FC
	ssidev.c ssidev_ics.c 
Log Message:
SSIDEV:
- Optimize away kmalloc() calls in rssidev_sync() code path; pre-allocate
  ic_chunks in ics_chunk_t.

SSIDEV (#ifdef SSIDEV_HASH_SD_LIST_FIX):
- Fix dereferencing uninitialized list_head struct in ssidev_hash struct.
  Affects ssidev_unique_list and ssidev_free_list list traversal.
- Fix inappropriate use of doubly linked-list for single linked-list traversal.
- Convert ssidev_linux_hash[] array of pointers to array of Linux list_head
  structs allocated from the slab.


Index: ssidev.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/ssidev.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- ssidev.c	2 Feb 2010 05:00:11 -0000	1.28
+++ ssidev.c	2 Feb 2010 05:23:55 -0000	1.29
@@ -56,7 +56,7 @@
 	(((MAJOR(_dev) << 6) + ((_node) << 3) + MINOR(_dev)) \
 	 & (SSIDEV_HASH_SIZE - 1))
 
-#ifdef SSI_NOTUSED
+#ifdef SSIDEV_SD_SSINEXT
 #define SSIDEV_HASH_SSIDEV(_dev) \
 	((_dev) & (SSIDEV_HASH_SIZE - 1))
 #endif
@@ -66,31 +66,42 @@
 char			ssidev_inited;
 char			ssidev_udev_mounted;
 static char		ssidev_secondary;
-static char		ssidev_updated;
 volatile clusternode_t	ssidev_node = CLUSTERNODE_INVAL;
-static int		ssidev_transid;
+
 #ifdef SSIDEV_LOCK_MUTEX
 static DECLARE_MUTEX(ssidev_sem);
+/*
+ * SMP: following is protected by ssidev_sem mutex
+ */
 #else
 static char		ssidev_busy;
 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(ssidev_spinlock);
 #endif
+#ifdef SSIDEV_HASH_SD_LIST_FIX
+static struct list_head *ssidev_linux_hash;
+#else
 static ssidev_hash_t	*ssidev_linux_hash[SSIDEV_HASH_SIZE];
-#ifdef SSI_NOTUSED
+#endif
+#ifdef SSIDEV_SD_SSINEXT
+#error not supported
 static ssidev_hash_t	*ssidev_ssi_hash[SSIDEV_HASH_SIZE];
 #endif
-static ssidev_hash_t	*ssidev_last;
-static LIST_HEAD(ssidev_unique_list);
 static LIST_HEAD(ssidev_free_list);
+static LIST_HEAD(ssidev_unique_list);
 static dev_t		ssidev_current = SSIDEV_FIRST;
-static DECLARE_WAIT_QUEUE_HEAD (ssidev_wait_queue);
-nsc_nodelist_t		ssidev_secondary_nodelist;
+static int		ssidev_transid;
 static int		ssidev_secondary_nodes;
+static nsc_nodelist_t	ssidev_secondary_nodelist;
+static ssidev_hash_t	*ssidev_last;
+static char		ssidev_updated;
+
+static DECLARE_WAIT_QUEUE_HEAD (ssidev_wait_queue);
 
 static LIST_HEAD(ssidev_poll_cli_list);
 static __cacheline_aligned_in_smp DEFINE_SPINLOCK(ssidev_poll_cli_spinlock);
-static clusternode_t	 ssidev_mount_sem_node;
-static pid_t		 ssidev_mount_sem_epid;
+
+static clusternode_t	 ssidev_mount_sem_node = 0;
+static pid_t		 ssidev_mount_sem_epid = 0;
 static DECLARE_MUTEX(ssidev_mount_sem);
 
 static void ssidev_broadcast_new(ssidev_hash_t *);
@@ -125,7 +136,19 @@
 	int lhash;
 
 	SSI_ASSERT(S_ISCHR(mode) || S_ISBLK(mode));
+
 	lhash = SSIDEV_HASH_LINUXDEV(devnode, mode, linuxdev);
+
+#ifdef SSIDEV_HASH_SD_LIST_FIX
+	list_for_each_entry(hp, &ssidev_linux_hash[lhash], sd_list) {
+		if (hp->sd_data.sd_devnode == devnode &&
+		    hp->sd_data.sd_mode == (mode & S_IFMT) &&
+		    hp->sd_data.sd_linuxdev == linuxdev)
+			return hp;
+	}
+
+	return NULL;
+#else
 	hp = ssidev_linux_hash[lhash];
 	while (hp != NULL) {
 		if (hp->sd_data.sd_devnode == devnode &&
@@ -136,9 +159,10 @@
 	}
 
 	return hp;
+#endif /* !SSIDEV_HASH_SD_LIST_FIX */
 }
 
-#ifdef SSI_NOTUSED
+#ifdef SSIDEV_SD_SSINEXT
 /* Called under ssidev_lock */
 static ssidev_hash_t *
 ssidev_search_ssitolinux(dev_t ssidev)
@@ -159,11 +183,16 @@
 #endif
 
 /* Called under ssidev_lock */
-static inline void ssidev_add(ssidev_hash_t *newp, clusternode_t devnode,
-			      int mode, dev_t linuxdev, dev_t ssidev)
+static inline void
+ssidev_add(
+	ssidev_hash_t *newp,
+	clusternode_t devnode,
+	int mode,
+	dev_t linuxdev,
+	dev_t ssidev)
 {
 	int lhash;
-#ifdef SSI_NOTUSED
+#ifdef SSIDEV_SD_SSINEXT
 	int shash;
 #endif
 
@@ -173,10 +202,14 @@
 	newp->sd_data.sd_mode = mode & S_IFMT;
 
 	lhash = SSIDEV_HASH_LINUXDEV(devnode, mode, linuxdev);
+#ifdef SSIDEV_HASH_SD_LIST_FIX
+	list_add(&newp->sd_list, &ssidev_linux_hash[lhash]);
+#else
 	newp->sd_linuxnext = (void *)ssidev_linux_hash[lhash];
 	ssidev_linux_hash[lhash] = newp;
+#endif /* !SSIDEV_HASH_SD_LIST_FIX */
 
-#ifdef SSI_NOTUSED
+#ifdef SSIDEV_SD_SSINEXT
 	shash = SSIDEV_HASH_SSIDEV(ssidev);
 	newp->sd_ssinext = (void *)ssidev_ssi_hash[shash];
 	ssidev_ssi_hash[shash] = newp;
@@ -256,87 +289,110 @@
 #endif /* !SSIDEV_LOCK_MUTEX */
 
 #ifdef SSIDEV_HASH_KMEM_CACHE
+#ifdef SSIDEV_HASH_SD_LIST_FIX
+static void
+ssidev_hash_ctor(void *foo, kmem_cache_t *cachep, unsigned long flags)
+{
+	ssidev_hash_t *hp = (ssidev_hash_t *) foo;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR) {
+		INIT_LIST_HEAD(&hp->sd_list);
+	}
+}
+#endif /* SSIDEV_HASH_SD_LIST_FIX */
+
 static void ssidev_hash_init(void)
 {
+#ifdef SSIDEV_HASH_SD_LIST_FIX
+	ssidev_hash_cachep = kmem_cache_create("ssidev_hash",
+				sizeof(ssidev_hash_t), 0,
+				SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
+				ssidev_hash_ctor, NULL);
+#else
 	ssidev_hash_cachep = kmem_cache_create("ssidev_hash",
 				sizeof(ssidev_hash_t), 0,
 				SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_PANIC,
 				NULL, NULL);
+#endif /* !SSIDEV_HASH_SD_LIST_FIX */
+}
+#endif /* SSIDEV_HASH_KMEM_CACHE */
+
+/* Called under ssidev_lock */
+static ssidev_hash_t *
+ssidev_get_free(ssidev_hash_data_t *dp)
+{
+	ssidev_hash_t *hp;
+
+	if (list_empty(&ssidev_free_list))
+		return NULL;
+
+	hp = list_entry(ssidev_free_list.next, ssidev_hash_t, sd_list);
+
+	if (unlikely(hp->sd_data.sd_ssidev != dp->sd_ssidev))
+		panic("%s:secondary out of sync\n", __FUNCTION__);
+
+	list_del(&hp->sd_list);
+	return hp;
 }
-#endif
 
 /* Called under ssidev_lock */
 static ssidev_hash_t *
 ssidev_add_last(ssidev_hash_data_t *dp)
 {
-	ssidev_hash_t *newp;
 	ssidev_hash_t *hp;
 
 	if (dp->sd_devnode != CLUSTERNODE_INVAL) {
-		if (!list_empty(&ssidev_free_list)) {
-			hp = list_entry(ssidev_free_list.next,
-					ssidev_hash_t, sd_list);
-			if (hp->sd_data.sd_ssidev != dp->sd_ssidev)
-				panic("%s:secondary out of sync\n",
-				      __FUNCTION__);
-			list_del(&hp->sd_list);
-			newp = hp;
-		} else
+		hp = ssidev_get_free(dp);
+		if (!hp)
 #ifdef SSIDEV_HASH_KMEM_CACHE
-			newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL|__GFP_NOFAIL);
+			hp = kmem_cache_alloc(ssidev_hash_cachep,
+						GFP_KERNEL|__GFP_NOFAIL);
 #else
-			newp = kmalloc_nofail(sizeof(*newp));
+			hp = kmalloc_nofail(sizeof(*hp));
 #endif
-		ssidev_add(newp, dp->sd_devnode, dp->sd_mode,
+		ssidev_add(hp, dp->sd_devnode, dp->sd_mode,
 			   dp->sd_linuxdev, dp->sd_ssidev);
-	} else {
-		SSI_ASSERT(dp->sd_mode == 0 || dp->sd_mode == 1);
-		if (dp->sd_mode == 0) {
-			if (!list_empty(&ssidev_free_list)) {
-				hp = list_entry(ssidev_free_list.next,
-						ssidev_hash_t, sd_list);
-				if (hp->sd_data.sd_ssidev != dp->sd_ssidev)
-					panic("%s:secondary out of sync\n",
-					      __FUNCTION__);
-				list_del(&hp->sd_list);
-				newp = hp;
-				newp->sd_data.sd_mode = 0;
-			} else {
+	} else if (dp->sd_mode == 0) {
+		if ((hp = ssidev_get_free(dp))) {
+			hp->sd_data.sd_mode = 0;
+		} else {
 #ifdef SSIDEV_HASH_KMEM_CACHE
-				newp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL|__GFP_NOFAIL);
-				INIT_LIST_HEAD(&newp->sd_list);
+			hp = kmem_cache_alloc(ssidev_hash_cachep,
+						GFP_KERNEL|__GFP_NOFAIL);
+#ifndef SSIDEV_HASH_SD_LIST_FIX
+			INIT_LIST_HEAD(&hp->sd_list);
+#endif
 #else
-				newp = kmalloc_nofail(sizeof(*newp));
+			hp = kmalloc_nofail(sizeof(*hp));
 #endif
-				newp->sd_data = *dp;
-			}
-			list_add(&newp->sd_list, &ssidev_unique_list);
-		} else {
-			newp = NULL;
-			list_for_each_entry(hp, &ssidev_unique_list, sd_list) {
-				if (hp->sd_data.sd_ssidev == dp->sd_ssidev) {
-					list_del(&hp->sd_list);
-					newp = hp;
-					newp->sd_data.sd_mode = 1;
-					break;
-				}
+			hp->sd_data = *dp;
+		}
+		list_add(&hp->sd_list, &ssidev_unique_list);
+	} else {
+		SSI_ASSERT(dp->sd_mode == 1);
+
+		list_for_each_entry(hp, &ssidev_unique_list, sd_list) {
+			if (hp->sd_data.sd_ssidev == dp->sd_ssidev) {
+				list_move(&hp->sd_list, &ssidev_free_list);
+				hp->sd_data.sd_mode = 1;
+				break;
 			}
-			if (newp == NULL)
-				panic("%s:secondary out of sync\n",
-				      __FUNCTION__);
-			list_add(&newp->sd_list, &ssidev_free_list);
 		}
+		if (unlikely(&hp->sd_list == &ssidev_unique_list))
+			panic("%s:secondary out of sync\n",
+			      __FUNCTION__);
 	}
 
-	return newp;
+	return hp;
 }
 
 /* Called under ssidev_lock */
 static void
 ssidev_sync_add_entries(int num, ssidev_hash_data_t *dp)
 {
-	int j;
 	ssidev_hash_t *newp;
+	int j;
 
 	for (j = 0; j < num; j++, dp++) {
 #ifdef SSIDEV_HASH_KMEM_CACHE
@@ -392,10 +448,24 @@
 
 	(void)to_node;
 	*rerror = 0;
+
+	ics_chunk_init(datap, sizeof(*dp));
 	ssidev_lock_busy();
-	ics_chunk_init(datap, sizeof(ssidev_hash_data_t));
+
 	if (secondary) {
-#ifdef SSI_NOTUSED
+		struct list_head *pos;
+		unsigned int count = 0;
+
+		list_for_each(pos, &ssidev_free_list)
+			count++;
+		list_for_each(pos, &ssidev_unique_list)
+			count++;
+		if (!count)
+			goto broadcast_sync;
+
+		ics_chunk_prealloc(datap, count);
+
+#ifdef SSIDEV_SD_SSINEXT
 		int i;
 		for (i = 0; i < SSIDEV_HASH_SIZE; i++) {
 			hp = ssidev_ssi_hash[i];
@@ -414,6 +484,8 @@
 			dp = ics_chunk_add_entry(datap);
 			*dp = hp->sd_data;
 		}
+
+broadcast_sync:
 		if (!NSC_NODELIST_TEST1(&ssidev_secondary_nodelist,
 					from_node)) {
 			ssidev_broadcast_sync(from_node);
@@ -493,7 +565,9 @@
 		return 0;
 	}
 #endif
+
 	ssidev_lock();
+
 	hp = ssidev_search_linuxtossi(devnode, mode, linuxdev);
 	if (hp != NULL) {
 		*ssidevp = hp->sd_data.sd_ssidev;
@@ -516,6 +590,7 @@
 		ssidev_broadcast_new(newp);
 	}
 	ssidev_unlock();
+
 	return 0;
 }
 
@@ -532,7 +607,9 @@
 		return 0;
 	}
 #endif
+
 	ssidev_lock_busy();
+
 #ifdef SSIDEV_HASH_KMEM_CACHE
 	newp = ssidev_alloc_next(ssidevp);
 	if (IS_ERR(newp)) {
@@ -552,6 +629,7 @@
 		ssidev_broadcast_new(newp);
 	}
 	ssidev_unlock();
+
 	return 0;
 }
 
@@ -562,17 +640,18 @@
 
 	*rerror = -ENOENT;
 	ssidev_lock_busy();
+
 	list_for_each_entry(hp, &ssidev_unique_list, sd_list) {
 		if (hp->sd_data.sd_ssidev == ssidev) {
-			list_del(&hp->sd_list);
 			hp->sd_data.sd_mode = 1;
-			list_add(&hp->sd_list, &ssidev_free_list);
+			list_move(&hp->sd_list, &ssidev_free_list);
 			ssidev_broadcast_new(hp);
 			*rerror = 0;
 			break;
 		}
 	}
 	ssidev_unlock();
+
 	if (*rerror < 0)
 		printk(KERN_WARNING "%s: ssidev 0x%x not found\n",
 		       __FUNCTION__, ssidev);
@@ -591,10 +670,13 @@
 		      __FUNCTION__, devnode, MAJOR(linuxdev), MINOR(linuxdev));
 		/*NOTREACHED*/
 	}
+
 	if (ssidev_is_local(mode, linuxdev))
 		devnode = CLUSTERNODE_THIS;
+
 	SSI_ASSERT(devnode != CLUSTERNODE_INVAL);
 	ssidev_lock();
+
 	hp = ssidev_search_linuxtossi(devnode, mode, linuxdev);
 	if (hp) {
 		ssidev = hp->sd_data.sd_ssidev;
@@ -602,29 +684,31 @@
 		return ssidev;
 	}
 	ssidev_unlock();
+
 	error = ssidev_new(devnode, mode, linuxdev, &ssidev);
-	if (error >= 0) {
-		if (this_node != ssidev_node && !ssidev_secondary) {
+	if (unlikely(error < 0)) {
+		printk(KERN_ERR "%s: ssidev not created for node %u (%d, %d),"
+			" error: %d\n", __FUNCTION__, devnode, MAJOR(linuxdev),
+			MINOR(linuxdev), error);
+		return NODEV;
+	}
+
+	if (!ssidev_secondary && ssidev_node != this_node) {
 #ifdef SSIDEV_HASH_KMEM_CACHE
-			hp = kmem_cache_alloc(ssidev_hash_cachep, GFP_KERNEL|__GFP_NOFAIL);
+		hp = kmem_cache_alloc(ssidev_hash_cachep,
+					GFP_KERNEL|__GFP_NOFAIL);
 #else
-			hp = kmalloc_nofail(sizeof(*hp));
+		hp = kmalloc_nofail(sizeof(*hp));
 #endif
-			ssidev_lock();
-			ssidev_add(hp, devnode, mode & S_IFMT,
-				   linuxdev, ssidev);
-			ssidev_unlock();
-		}
-		return ssidev;
+		ssidev_lock();
+		ssidev_add(hp, devnode, mode & S_IFMT, linuxdev, ssidev);
+		ssidev_unlock();
 	}
-	printk(KERN_WARNING
-	       "%s: ssidev not created for node %u (%d, %d), error: %d\n",
-	       __FUNCTION__, devnode, MAJOR(linuxdev), MINOR(linuxdev), error);
 
-	return NODEV;
+	return ssidev;
 }
 
-#ifdef SSI_NOTUSED
+#ifdef SSIDEV_SD_SSINEXT
 dev_t ssidev_ssitolinux(dev_t ssidev, int *mode)
 {
 	ssidev_hash_t	*hp;
@@ -644,6 +728,7 @@
 }
 #endif
 
+/* Called under ssidev_lock */
 static void
 ssidev_snap_failover_data(ssidev_failover_data_t *fp)
 {
@@ -669,7 +754,9 @@
 		return 0;
 	}
 	*data_len = sizeof(*fp);
+
 	ssidev_lock_failover();
+
 	ssidev_snap_failover_data(fp);
 	ssidev_unlock();
 
@@ -711,7 +798,9 @@
 	if (buffer_len == 0)
 		return;
 	SSI_ASSERT(buffer_len == sizeof(ssidev_failover_data_t));
-	ssidev_lock_busy(); /* SSI: lock for possible ssidev_add_last() path */
+
+	ssidev_lock_busy();
+
 	ssidev_failover_update((void *)buffer);
 	ssidev_unlock();
 }
@@ -719,9 +808,9 @@
 void ssidev_failover(nsc_nodelist_t *nodelist)
 {
 	ssidev_lock_busy();
+
 	ssidev_node = this_node;
 	ssidev_updated = 0;
-	/* ssidev_node = this_node; */
 	clms_key_svc_pull_data(ssidev_key_service,
 			       sizeof(ssidev_failover_data_t),
 			       nodelist);
@@ -731,6 +820,7 @@
 	}
 	ssidev_broadcast_failover();
 	ssidev_unlock();
+
 	clms_set_key_service_ready(ssidev_key_service);
 	NSC_NODELIST_FREE(nodelist);
 }
@@ -742,8 +832,18 @@
 
 void ssidev_init(void)
 {
-	/* Wait for the SSI device server if we're not it. */
-	ssidev_node = clms_get_key_server_node(ssidev_key_service, 1);
+#ifdef SSIDEV_HASH_SD_LIST_FIX
+	int i;
+
+	ssidev_linux_hash = kmalloc(sizeof(struct list_head)
+				    * SSIDEV_HASH_SIZE, GFP_KERNEL);
+	if (!ssidev_linux_hash)
+		panic("%s: Unable to allocate ssidev_linux_hash\n", __FUNCTION__);
+
+	for (i = 0; i < SSIDEV_HASH_SIZE; i++)
+		INIT_LIST_HEAD(&ssidev_linux_hash[i]);
+#endif /* SSIDEV_HASH_SD_LIST_FIX */
+
 #ifdef SSIDEV_HASH_KMEM_CACHE
 	ssidev_hash_init();
 #endif
@@ -753,16 +853,21 @@
 #ifdef SSIDEV_POLL_CLI_KMEM_CACHE
 	ssidev_poll_cli_init();
 #endif
+	/* Wait for the SSI device server if we're not it. */
+	ssidev_node = clms_get_key_server_node(ssidev_key_service, 1);
 	if (ssidev_node == this_node) {
 		ssidev_inited = 1;
 		clms_set_key_service_ready(ssidev_key_service);
 	} else {
 		clms_waitfor_key_service(ssidev_key_service);
 		ssidev_secondary = clms_is_secondary(this_node);
+
 		ssidev_lock_busy();
+
 		ssidev_sync(ssidev_secondary);
 		ssidev_inited = 1;
 		ssidev_unlock();
+
 		if (ssidev_secondary)
 			clms_set_key_secondary_ready(ssidev_key_service);
 	}
@@ -781,7 +886,9 @@
 	icssvr_nodedown_svc_wait(node, cluster_ssidev_svc);
 	ssidev_poll_svr_nodedown(node);
 	(void)rssidev_global_mount_sem(this_node, NULL, node, 0, 0);
+
 	ssidev_lock();
+
 	if (NSC_NODELIST_TEST1(&ssidev_secondary_nodelist, node)) {
 		ssidev_secondary_nodes--;
 		NSC_NODELIST_CLR1(&ssidev_secondary_nodelist, node);
@@ -789,6 +896,7 @@
 	if (node == ssidev_node)
 		ssidev_node = CLUSTERNODE_INVAL;
 	ssidev_unlock();
+
 	clms_nodedown_callback(clms_handle, service, node);
 	return 0;
 }
@@ -1880,7 +1988,10 @@
 			 clusternode_t from_node, pid_t from_epid,
 			 int do_down)
 {
+	SSI_ASSERT(from_node != 0);
+
 	if (do_down) {
+		/* SMP-safe */
 		if (ssidev_mount_sem_node != from_node ||
 		    ssidev_mount_sem_epid != from_epid) {
 			down(&ssidev_mount_sem);
@@ -1893,11 +2004,13 @@
 				return 0;
 			panic("%s: mount_sem released by wrong node\n",
 			      __FUNCTION__);
+			/* NOTREACHED */
 		}
 		ssidev_mount_sem_node = 0;
 		ssidev_mount_sem_epid = 0;
 		up(&ssidev_mount_sem);
 	}
+
 	if (retval != NULL)
 		*retval = 0;
 	if (this_node == ssidev_node) {
@@ -1914,6 +2027,7 @@
 		      dev_t curdev, ssidev_hash_data_t *dp)
 {
 	*rerror = 0;
+
 	ssidev_lock_busy();
 	ssidev_transid = transid;
 	ssidev_current = curdev;
@@ -1923,6 +2037,7 @@
 	return 0;
 }
 
+/* Called under ssidev_lock */
 static void
 ssidev_broadcast_new(ssidev_hash_t *newp)
 {
@@ -2006,6 +2121,7 @@
 	return 0;
 }
 
+/* Called under ssidev_lock */
 static void
 ssidev_broadcast_sync(clusternode_t new_node)
 {
@@ -2086,6 +2202,7 @@
 	return 0;
 }
 
+/* Called under ssidev_lock */
 static void
 ssidev_broadcast_mount_sem(clusternode_t from_node, pid_t from_epid,
 			   int do_down)
@@ -2167,22 +2284,19 @@
 	return 0;
 }
 
+/* Called under ssidev_lock */
 static void
 ssidev_broadcast_failover(void)
 {
-	int error;
-	int rerror;
-	nsc_nlcookie_t cookie;
-	clusternode_t to_node;
 	cli_handle_t **hlistp;
-	int sent;
-	int i;
 	ssidev_failover_data_t f;
+	nsc_nlcookie_t cookie = CLUSTERNODE_INVAL;
+	clusternode_t to_node;
+	int error, rerror, i, sent = 0;
 
 	ssidev_snap_failover_data(&f);
-	cookie = CLUSTERNODE_INVAL;
+
 	hlistp = kzmalloc_nofail(sizeof(*hlistp) * ssidev_secondary_nodes);
-	sent = 0;
 	for (;;) {
 		to_node = nsc_nodelist_get_next(&cookie,
 						&ssidev_secondary_nodelist);

Index: ssidev_ics.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/util/ssidev_ics.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- ssidev_ics.c	27 Oct 2009 03:18:29 -0000	1.15
+++ ssidev_ics.c	2 Feb 2010 05:23:55 -0000	1.16
@@ -63,6 +63,7 @@
 #define ps_wakeup	0x1	/* wake ps_proc */
 #endif
 
+/* Might call ssidev_lock() */
 int ssidev_new(clusternode_t devnode, int mode, dev_t linuxdev,
 	       dev_t *ssidevp)
 {
@@ -974,11 +975,16 @@
 	int rerror;
 	clusternode_t to_node;
 
+	if (!ssidev_inited) {
+#ifdef DEBUG
+		printk("%s: ssidev not yet initialized\n", __FUNCTION__);
+		dump_stack();
+#endif
+		/* error = 0; */
+		return;
+	}
+
 	for (;;) {
-		if (!ssidev_inited) {
-			error = 0;
-			break;
-		}
 		to_node = ssidev_node;
 		if (to_node == this_node)
 			error = rssidev_global_mount_sem(to_node, &rerror,
@@ -1013,16 +1019,14 @@
 		      __FUNCTION__, (do_down ? "acquire" : "release"));
 }
 
+/* Called with ssidev_lock */
 void ssidev_sync(int secondary)
 {
-	int error;
-	int rerror;
+	ics_chunk_t data;
+	nsc_nodelist_t secondary_nodelist;
 	clusternode_t to_node;
 	dev_t curdev;
-	int transid;
-	int secondary_nodes;
-	nsc_nodelist_t secondary_nodelist;
-	ics_chunk_t data;
+	int error, rerror, transid, secondary_nodes;
 
 	ics_chunk_init(&data, 0);
 	for (;;) {


------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com