ocfs2: Depend on configfs heartbeat items.
authorJoel Becker <joel.becker@oracle.com>
Fri, 15 Jun 2007 04:40:49 +0000 (21:40 -0700)
committerMark Fasheh <mark.fasheh@oracle.com>
Wed, 11 Jul 2007 00:19:40 +0000 (17:19 -0700)
ocfs2 mounts require a heartbeat region.  Use the new configfs_depend_item()
facility to actually depend on them so they can't go away from under us.

First, teach cluster/nodemanager.c to depend an item on the o2cb subsystem.
Then teach o2hb_register_callbacks to take a UUID and depend on the
appropriate region.  Finally, teach all users of o2hb to pass a UUID or
NULL if they don't require a pin.

Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/heartbeat.h
fs/ocfs2/cluster/nodemanager.c
fs/ocfs2/cluster/nodemanager.h
fs/ocfs2/cluster/tcp.c
fs/ocfs2/dlm/dlmdomain.c
fs/ocfs2/heartbeat.c

index 979113479c664a2a8ea01bab4fa20ff3e8e0dadb..e331f4cb2c818e095d533e1b04efbd42cdea8743 100644 (file)
@@ -1665,7 +1665,56 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc,
 }
 EXPORT_SYMBOL_GPL(o2hb_setup_callback);
 
-int o2hb_register_callback(struct o2hb_callback_func *hc)
+static struct o2hb_region *o2hb_find_region(const char *region_uuid)
+{
+       struct o2hb_region *p, *reg = NULL;
+
+       assert_spin_locked(&o2hb_live_lock);
+
+       list_for_each_entry(p, &o2hb_all_regions, hr_all_item) {
+               if (!strcmp(region_uuid, config_item_name(&p->hr_item))) {
+                       reg = p;
+                       break;
+               }
+       }
+
+       return reg;
+}
+
+static int o2hb_region_get(const char *region_uuid)
+{
+       int ret = 0;
+       struct o2hb_region *reg;
+
+       spin_lock(&o2hb_live_lock);
+
+       reg = o2hb_find_region(region_uuid);
+       if (!reg)
+               ret = -ENOENT;
+       spin_unlock(&o2hb_live_lock);
+
+       if (!ret)
+               ret = o2nm_depend_item(&reg->hr_item);
+
+       return ret;
+}
+
+static void o2hb_region_put(const char *region_uuid)
+{
+       struct o2hb_region *reg;
+
+       spin_lock(&o2hb_live_lock);
+
+       reg = o2hb_find_region(region_uuid);
+
+       spin_unlock(&o2hb_live_lock);
+
+       if (reg)
+               o2nm_undepend_item(&reg->hr_item);
+}
+
+int o2hb_register_callback(const char *region_uuid,
+                          struct o2hb_callback_func *hc)
 {
        struct o2hb_callback_func *tmp;
        struct list_head *iter;
@@ -1681,6 +1730,12 @@ int o2hb_register_callback(struct o2hb_callback_func *hc)
                goto out;
        }
 
+       if (region_uuid) {
+               ret = o2hb_region_get(region_uuid);
+               if (ret)
+                       goto out;
+       }
+
        down_write(&o2hb_callback_sem);
 
        list_for_each(iter, &hbcall->list) {
@@ -1702,16 +1757,21 @@ out:
 }
 EXPORT_SYMBOL_GPL(o2hb_register_callback);
 
-void o2hb_unregister_callback(struct o2hb_callback_func *hc)
+void o2hb_unregister_callback(const char *region_uuid,
+                             struct o2hb_callback_func *hc)
 {
        BUG_ON(hc->hc_magic != O2HB_CB_MAGIC);
 
        mlog(ML_HEARTBEAT, "on behalf of %p for funcs %p\n",
             __builtin_return_address(0), hc);
 
+       /* XXX Can this happen _with_ a region reference? */
        if (list_empty(&hc->hc_item))
                return;
 
+       if (region_uuid)
+               o2hb_region_put(region_uuid);
+
        down_write(&o2hb_callback_sem);
 
        list_del_init(&hc->hc_item);
index cc6d40b397715bda85d68643f90a3cb267f47580..35397dd5ecdbb42c3922cbc9e930081c4c522b87 100644 (file)
@@ -69,8 +69,10 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc,
                         o2hb_cb_func *func,
                         void *data,
                         int priority);
-int o2hb_register_callback(struct o2hb_callback_func *hc);
-void o2hb_unregister_callback(struct o2hb_callback_func *hc);
+int o2hb_register_callback(const char *region_uuid,
+                          struct o2hb_callback_func *hc);
+void o2hb_unregister_callback(const char *region_uuid,
+                             struct o2hb_callback_func *hc);
 void o2hb_fill_node_map(unsigned long *map,
                        unsigned bytes);
 void o2hb_init(void);
index 48b77d113cb26952cfce673d429218ebc0dc3882..eab46d8a7c8ce1aa64d6e79124c697f7c282b980 100644 (file)
@@ -900,6 +900,16 @@ static struct o2nm_cluster_group o2nm_cluster_group = {
        },
 };
 
+int o2nm_depend_item(struct config_item *item)
+{
+       return configfs_depend_item(&o2nm_cluster_group.cs_subsys, item);
+}
+
+void o2nm_undepend_item(struct config_item *item)
+{
+       configfs_undepend_item(&o2nm_cluster_group.cs_subsys, item);
+}
+
 static void __exit exit_o2nm(void)
 {
        if (ocfs2_table_header)
index 070522138ae26c1b10f0f50683a48b5c53f5bf8e..55ae1a00d735c04df3f5b5a850d2353c69ce2bd4 100644 (file)
@@ -77,4 +77,7 @@ struct o2nm_node *o2nm_get_node_by_ip(__be32 addr);
 void o2nm_node_get(struct o2nm_node *node);
 void o2nm_node_put(struct o2nm_node *node);
 
+int o2nm_depend_item(struct config_item *item);
+void o2nm_undepend_item(struct config_item *item);
+
 #endif /* O2CLUSTER_NODEMANAGER_H */
index 0b229a9c7952612e2f30098c3085accbb8b167f9..d58c7dddb8533f3a99f4cd48c280df42741b4c09 100644 (file)
@@ -1638,8 +1638,8 @@ static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num,
 
 void o2net_unregister_hb_callbacks(void)
 {
-       o2hb_unregister_callback(&o2net_hb_up);
-       o2hb_unregister_callback(&o2net_hb_down);
+       o2hb_unregister_callback(NULL, &o2net_hb_up);
+       o2hb_unregister_callback(NULL, &o2net_hb_down);
 }
 
 int o2net_register_hb_callbacks(void)
@@ -1651,9 +1651,9 @@ int o2net_register_hb_callbacks(void)
        o2hb_setup_callback(&o2net_hb_up, O2HB_NODE_UP_CB,
                            o2net_hb_node_up_cb, NULL, O2NET_HB_PRI);
 
-       ret = o2hb_register_callback(&o2net_hb_up);
+       ret = o2hb_register_callback(NULL, &o2net_hb_up);
        if (ret == 0)
-               ret = o2hb_register_callback(&o2net_hb_down);
+               ret = o2hb_register_callback(NULL, &o2net_hb_down);
 
        if (ret)
                o2net_unregister_hb_callbacks();
index d836b98dd99a42614ab0e1afbb4c5f459ef708ae..6954565b8ccb7cac2f895d79292987cb8d8a77ad 100644 (file)
@@ -1128,8 +1128,8 @@ bail:
 
 static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm)
 {
-       o2hb_unregister_callback(&dlm->dlm_hb_up);
-       o2hb_unregister_callback(&dlm->dlm_hb_down);
+       o2hb_unregister_callback(NULL, &dlm->dlm_hb_up);
+       o2hb_unregister_callback(NULL, &dlm->dlm_hb_down);
        o2net_unregister_handler_list(&dlm->dlm_domain_handlers);
 }
 
@@ -1141,13 +1141,13 @@ static int dlm_register_domain_handlers(struct dlm_ctxt *dlm)
 
        o2hb_setup_callback(&dlm->dlm_hb_down, O2HB_NODE_DOWN_CB,
                            dlm_hb_node_down_cb, dlm, DLM_HB_NODE_DOWN_PRI);
-       status = o2hb_register_callback(&dlm->dlm_hb_down);
+       status = o2hb_register_callback(NULL, &dlm->dlm_hb_down);
        if (status)
                goto bail;
 
        o2hb_setup_callback(&dlm->dlm_hb_up, O2HB_NODE_UP_CB,
                            dlm_hb_node_up_cb, dlm, DLM_HB_NODE_UP_PRI);
-       status = o2hb_register_callback(&dlm->dlm_hb_up);
+       status = o2hb_register_callback(NULL, &dlm->dlm_hb_up);
        if (status)
                goto bail;
 
index b25ef63781baafa695e64b1660d12e6d1edf2cb5..352eb4a13f9828717cbe68e2b626227b73c55a22 100644 (file)
@@ -157,16 +157,16 @@ int ocfs2_register_hb_callbacks(struct ocfs2_super *osb)
        if (ocfs2_mount_local(osb))
                return 0;
 
-       status = o2hb_register_callback(&osb->osb_hb_down);
+       status = o2hb_register_callback(osb->uuid_str, &osb->osb_hb_down);
        if (status < 0) {
                mlog_errno(status);
                goto bail;
        }
 
-       status = o2hb_register_callback(&osb->osb_hb_up);
+       status = o2hb_register_callback(osb->uuid_str, &osb->osb_hb_up);
        if (status < 0) {
                mlog_errno(status);
-               o2hb_unregister_callback(&osb->osb_hb_down);
+               o2hb_unregister_callback(osb->uuid_str, &osb->osb_hb_down);
        }
 
 bail:
@@ -178,8 +178,8 @@ void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb)
        if (ocfs2_mount_local(osb))
                return;
 
-       o2hb_unregister_callback(&osb->osb_hb_down);
-       o2hb_unregister_callback(&osb->osb_hb_up);
+       o2hb_unregister_callback(osb->uuid_str, &osb->osb_hb_down);
+       o2hb_unregister_callback(osb->uuid_str, &osb->osb_hb_up);
 }
 
 void ocfs2_stop_heartbeat(struct ocfs2_super *osb)