[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