[Ocfs2-commits] mfasheh commits r2433 - in trunk/fs/ocfs2: . dlm

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Tue Jun 28 16:08:02 CDT 2005


Author: mfasheh
Signed-off-by: khackel
Date: 2005-06-27 13:42:46 -0500 (Mon, 27 Jun 2005)
New Revision: 2433

Modified:
   trunk/fs/ocfs2/dlm/dlmapi.h
   trunk/fs/ocfs2/dlm/dlmcommon.h
   trunk/fs/ocfs2/dlm/dlmdomain.c
   trunk/fs/ocfs2/dlm/dlmdomain.h
   trunk/fs/ocfs2/dlm/dlmrecovery.c
   trunk/fs/ocfs2/dlmglue.c
   trunk/fs/ocfs2/heartbeat.c
   trunk/fs/ocfs2/heartbeat.h
   trunk/fs/ocfs2/journal.c
   trunk/fs/ocfs2/ocfs2.h
Log:
* Setup a dlm node eviction callback and plug the file system into it.

Signed-off-by: khackel



Modified: trunk/fs/ocfs2/dlm/dlmapi.h
===================================================================
--- trunk/fs/ocfs2/dlm/dlmapi.h	2005-06-26 22:55:48 UTC (rev 2432)
+++ trunk/fs/ocfs2/dlm/dlmapi.h	2005-06-27 18:42:46 UTC (rev 2433)
@@ -195,4 +195,17 @@
 
 void dlm_print_one_lock(dlm_lock *lockid);
 
+typedef void (dlm_eviction_func)(int, void *);
+struct dlm_eviction_cb {
+	struct list_head        ec_item;
+	dlm_eviction_func       *ec_func;
+	void                    *ec_data;
+};
+void dlm_setup_eviction_cb(struct dlm_eviction_cb *cb,
+			   dlm_eviction_func *f,
+			   void *data);
+void dlm_register_eviction_cb(dlm_ctxt *dlm,
+			      struct dlm_eviction_cb *cb);
+void dlm_unregister_eviction_cb(struct dlm_eviction_cb *cb);
+
 #endif /* DLMAPI_H */

Modified: trunk/fs/ocfs2/dlm/dlmcommon.h
===================================================================
--- trunk/fs/ocfs2/dlm/dlmcommon.h	2005-06-26 22:55:48 UTC (rev 2432)
+++ trunk/fs/ocfs2/dlm/dlmcommon.h	2005-06-27 18:42:46 UTC (rev 2433)
@@ -130,6 +130,7 @@
 	struct list_head work_list;
 	spinlock_t work_lock;
 	struct list_head	dlm_domain_handlers;
+	struct list_head	dlm_eviction_callbacks;
 };
 
 /* these keventd work queue items are for less-frequently 

Modified: trunk/fs/ocfs2/dlm/dlmdomain.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmdomain.c	2005-06-26 22:55:48 UTC (rev 2432)
+++ trunk/fs/ocfs2/dlm/dlmdomain.c	2005-06-27 18:42:46 UTC (rev 2433)
@@ -1249,6 +1249,8 @@
 	kref_init(&dlm->dlm_refs, dlm_ctxt_release);
 	dlm->dlm_state = DLM_CTXT_NEW;
 
+	INIT_LIST_HEAD(&dlm->dlm_eviction_callbacks);
+
 	mlog(0, "context init: refcount %u\n",
 		  atomic_read(&dlm->dlm_refs.refcount));
 
@@ -1375,6 +1377,61 @@
 	return status;
 }
 
+/* Domain eviction callback handling.
+ * 
+ * The file system requires notification of node death *before* the
+ * dlm completes it's recovery work, otherwise it may be able to
+ * acquire locks on resources requiring recovery. Since the dlm can
+ * evict a node from it's domain *before* heartbeat fires, a similar
+ * mechanism is required. */
+
+/* Eviction is not expected to happen often, so a per-domain lock is
+ * not necessary. Eviction callbacks are allowed to sleep for short
+ * periods of time. */
+static DECLARE_RWSEM(dlm_callback_sem);
+
+void dlm_fire_domain_eviction_callbacks(dlm_ctxt *dlm,
+					int node_num)
+{
+	struct list_head *iter;
+	struct dlm_eviction_cb *cb;
+
+	down_read(&dlm_callback_sem);
+	list_for_each(iter, &dlm->dlm_eviction_callbacks) {
+		cb = list_entry(iter, struct dlm_eviction_cb, ec_item);
+
+		cb->ec_func(node_num, cb->ec_data);
+	}
+	up_read(&dlm_callback_sem);
+}
+
+void dlm_setup_eviction_cb(struct dlm_eviction_cb *cb,
+			   dlm_eviction_func *f,
+			   void *data)
+{
+	INIT_LIST_HEAD(&cb->ec_item);
+	cb->ec_func = f;
+	cb->ec_data = data;
+}
+EXPORT_SYMBOL_GPL(dlm_setup_eviction_cb);
+
+void dlm_register_eviction_cb(dlm_ctxt *dlm,
+			      struct dlm_eviction_cb *cb)
+{
+	down_write(&dlm_callback_sem);
+	list_add_tail(&cb->ec_item, &dlm->dlm_eviction_callbacks);
+	up_write(&dlm_callback_sem);
+}
+EXPORT_SYMBOL_GPL(dlm_register_eviction_cb);
+
+void dlm_unregister_eviction_cb(struct dlm_eviction_cb *cb)
+{
+	down_write(&dlm_callback_sem);
+	list_del_init(&cb->ec_item);
+	up_write(&dlm_callback_sem);
+}
+EXPORT_SYMBOL_GPL(dlm_unregister_eviction_cb);
+
 static int __init dlm_init(void)
 {
 	int status;

Modified: trunk/fs/ocfs2/dlm/dlmdomain.h
===================================================================
--- trunk/fs/ocfs2/dlm/dlmdomain.h	2005-06-26 22:55:48 UTC (rev 2432)
+++ trunk/fs/ocfs2/dlm/dlmdomain.h	2005-06-27 18:42:46 UTC (rev 2433)
@@ -31,5 +31,7 @@
 dlm_ctxt * __dlm_lookup_domain(const char *domain);
 int dlm_joined(dlm_ctxt *dlm);
 int dlm_shutting_down(dlm_ctxt *dlm);
+void dlm_fire_domain_eviction_callbacks(dlm_ctxt *dlm,
+					int node_num);
 
 #endif

Modified: trunk/fs/ocfs2/dlm/dlmrecovery.c
===================================================================
--- trunk/fs/ocfs2/dlm/dlmrecovery.c	2005-06-26 22:55:48 UTC (rev 2432)
+++ trunk/fs/ocfs2/dlm/dlmrecovery.c	2005-06-27 18:42:46 UTC (rev 2433)
@@ -1940,6 +1940,9 @@
 
 	mlog(0, "node %u wants to recover node %u\n",
 		  br->node_idx, br->dead_node);
+
+	dlm_fire_domain_eviction_callbacks(dlm, br->dead_node);
+
 	spin_lock(&dlm->spinlock);
 	if (dlm->reco.new_master != O2NM_INVALID_NODE_NUM) {
 		mlog(0, "new_master already set to %u!\n",

Modified: trunk/fs/ocfs2/dlmglue.c
===================================================================
--- trunk/fs/ocfs2/dlmglue.c	2005-06-26 22:55:48 UTC (rev 2432)
+++ trunk/fs/ocfs2/dlmglue.c	2005-06-27 18:42:46 UTC (rev 2433)
@@ -1775,6 +1775,8 @@
 	ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb);
 	ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb);
 
+	dlm_register_eviction_cb(dlm, &osb->osb_eviction_cb);
+
 	osb->dlm = dlm;
 
 	status = 0;
@@ -1788,6 +1790,8 @@
 {
 	mlog_entry_void();
 
+	dlm_unregister_eviction_cb(&osb->osb_eviction_cb);
+
 	ocfs2_drop_osb_locks(osb);
 
 	if (osb->vote_task) {

Modified: trunk/fs/ocfs2/heartbeat.c
===================================================================
--- trunk/fs/ocfs2/heartbeat.c	2005-06-26 22:55:48 UTC (rev 2432)
+++ trunk/fs/ocfs2/heartbeat.c	2005-06-27 18:42:46 UTC (rev 2433)
@@ -33,6 +33,8 @@
 #include <cluster/heartbeat.h>
 #include <cluster/nodemanager.h>
 
+#include <dlm/dlmapi.h>
+
 #define MLOG_MASK_PREFIX ML_SUPER
 #include <cluster/masklog.h>
 
@@ -67,12 +69,9 @@
 	ocfs2_node_map_init(&osb->umount_map);
 }
 
-static void ocfs2_hb_node_down_cb(struct o2nm_node *node,
-				  int node_num,
-				  void *data)
+static void ocfs2_do_node_down(int node_num,
+			       ocfs2_super *osb)
 {
-	ocfs2_super *osb = data;
-
 	OCFS2_ASSERT(osb->node_num != node_num);
 
 	mlog(0, "ocfs2: node down event for %d\n", node_num);
@@ -100,6 +99,27 @@
 	ocfs2_remove_node_from_vote_queues(osb, node_num);
 }
 
+static void ocfs2_hb_node_down_cb(struct o2nm_node *node,
+				  int node_num,
+				  void *data)
+{
+	ocfs2_do_node_down(node_num, (ocfs2_super *) data);
+}
+
+/* Called from the dlm when it's about to evict a node. We may also
+ * get a heartbeat callback later. */
+static void ocfs2_dlm_eviction_cb(int node_num,
+				  void *data)
+{
+	ocfs2_super *osb = (ocfs2_super *) data;
+	struct super_block *sb = osb->sb;
+
+	mlog(ML_NOTICE, "device (%u,%u): dlm has evicted node %d\n",
+	     MAJOR(sb->s_dev), MINOR(sb->s_dev), node_num);
+
+	ocfs2_do_node_down(node_num, osb);
+}
+
 static void ocfs2_hb_node_up_cb(struct o2nm_node *node,
 				int node_num,
 				void *data)
@@ -108,7 +128,7 @@
 
 	OCFS2_ASSERT(osb->node_num != node_num);
 
-	mlog(0, "ocfs2: node up event for %d\n", node_num);
+	mlog(0, "node up event for %d\n", node_num);
 	ocfs2_node_map_clear_bit(osb, &osb->umount_map, node_num);
 }
 
@@ -120,6 +140,12 @@
 
 	o2hb_setup_callback(&osb->osb_hb_up, O2HB_NODE_UP_CB,
 			    ocfs2_hb_node_up_cb, osb, OCFS2_HB_NODE_UP_PRI);
+
+	/* Not exactly a heartbeat callback, but leads to essentially
+	 * the same path so we set it up here. */
+	dlm_setup_eviction_cb(&osb->osb_eviction_cb,
+			      ocfs2_dlm_eviction_cb,
+			      osb);
 }
 
 /* Most functions here are just stubs for now... */
@@ -301,13 +327,25 @@
 		target->map[i] = from->map[i];
 }
 
-void ocfs2_recovery_map_set(ocfs2_super *osb,
-			    int num)
+/* Returns whether the recovery bit was actually set - it may not be
+ * if a node is still marked as needing recovery */
+int ocfs2_recovery_map_set(ocfs2_super *osb,
+			   int num)
 {
+	int set = 0;
+
 	spin_lock(&osb->node_map_lock);
+
 	__ocfs2_node_map_clear_bit(&osb->mounted_map, num);
-	__ocfs2_node_map_set_bit(&osb->recovery_map, num);
+
+	if (!test_bit(num, osb->recovery_map.map)) {
+	    __ocfs2_node_map_set_bit(&osb->recovery_map, num);
+	    set = 1;
+	}
+
 	spin_unlock(&osb->node_map_lock);
+
+	return set;
 }
 
 void ocfs2_recovery_map_clear(ocfs2_super *osb,

Modified: trunk/fs/ocfs2/heartbeat.h
===================================================================
--- trunk/fs/ocfs2/heartbeat.h	2005-06-26 22:55:48 UTC (rev 2432)
+++ trunk/fs/ocfs2/heartbeat.h	2005-06-27 18:42:46 UTC (rev 2433)
@@ -55,8 +55,8 @@
 {
 	return ocfs2_node_map_iterate(osb, map, 0);
 }
-void ocfs2_recovery_map_set(ocfs2_super *osb,
-			    int num);
+int ocfs2_recovery_map_set(ocfs2_super *osb,
+			   int num);
 void ocfs2_recovery_map_clear(ocfs2_super *osb,
 			      int num);
 /* returns 1 if bit is the only bit set in target, 0 otherwise */

Modified: trunk/fs/ocfs2/journal.c
===================================================================
--- trunk/fs/ocfs2/journal.c	2005-06-26 22:55:48 UTC (rev 2432)
+++ trunk/fs/ocfs2/journal.c	2005-06-27 18:42:46 UTC (rev 2433)
@@ -1044,9 +1044,11 @@
 	down(&osb->recovery_lock);
 	if (osb->disable_recovery)
 		goto out;
+
 	/* People waiting on recovery will wait on
 	 * the recovery map to empty. */
-	ocfs2_recovery_map_set(osb, node_num);
+	if (!ocfs2_recovery_map_set(osb, node_num))
+		mlog(0, "node %d already be in recovery.\n", node_num);
 
 	mlog(0, "starting recovery thread...\n");
 

Modified: trunk/fs/ocfs2/ocfs2.h
===================================================================
--- trunk/fs/ocfs2/ocfs2.h	2005-06-26 22:55:48 UTC (rev 2432)
+++ trunk/fs/ocfs2/ocfs2.h	2005-06-27 18:42:46 UTC (rev 2433)
@@ -244,6 +244,7 @@
 	dlm_ctxt *dlm;
 	struct ocfs2_lock_res osb_super_lockres;
 	struct ocfs2_lock_res osb_rename_lockres;
+	struct dlm_eviction_cb osb_eviction_cb;
 
 	wait_queue_head_t recovery_event;
 



More information about the Ocfs2-commits mailing list