Commit 14829422 authored by Joel Becker's avatar Joel Becker Committed by Mark Fasheh

ocfs2: Depend on configfs heartbeat items.

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: default avatarJoel Becker <joel.becker@oracle.com>
Signed-off-by: default avatarMark Fasheh <mark.fasheh@oracle.com>
parent 631d1feb
...@@ -1665,7 +1665,56 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc, ...@@ -1665,7 +1665,56 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc,
} }
EXPORT_SYMBOL_GPL(o2hb_setup_callback); 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 o2hb_callback_func *tmp;
struct list_head *iter; struct list_head *iter;
...@@ -1681,6 +1730,12 @@ int o2hb_register_callback(struct o2hb_callback_func *hc) ...@@ -1681,6 +1730,12 @@ int o2hb_register_callback(struct o2hb_callback_func *hc)
goto out; goto out;
} }
if (region_uuid) {
ret = o2hb_region_get(region_uuid);
if (ret)
goto out;
}
down_write(&o2hb_callback_sem); down_write(&o2hb_callback_sem);
list_for_each(iter, &hbcall->list) { list_for_each(iter, &hbcall->list) {
...@@ -1702,16 +1757,21 @@ int o2hb_register_callback(struct o2hb_callback_func *hc) ...@@ -1702,16 +1757,21 @@ int o2hb_register_callback(struct o2hb_callback_func *hc)
} }
EXPORT_SYMBOL_GPL(o2hb_register_callback); 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); BUG_ON(hc->hc_magic != O2HB_CB_MAGIC);
mlog(ML_HEARTBEAT, "on behalf of %p for funcs %p\n", mlog(ML_HEARTBEAT, "on behalf of %p for funcs %p\n",
__builtin_return_address(0), hc); __builtin_return_address(0), hc);
/* XXX Can this happen _with_ a region reference? */
if (list_empty(&hc->hc_item)) if (list_empty(&hc->hc_item))
return; return;
if (region_uuid)
o2hb_region_put(region_uuid);
down_write(&o2hb_callback_sem); down_write(&o2hb_callback_sem);
list_del_init(&hc->hc_item); list_del_init(&hc->hc_item);
......
...@@ -69,8 +69,10 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc, ...@@ -69,8 +69,10 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc,
o2hb_cb_func *func, o2hb_cb_func *func,
void *data, void *data,
int priority); int priority);
int o2hb_register_callback(struct o2hb_callback_func *hc); int o2hb_register_callback(const char *region_uuid,
void o2hb_unregister_callback(struct o2hb_callback_func *hc); 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, void o2hb_fill_node_map(unsigned long *map,
unsigned bytes); unsigned bytes);
void o2hb_init(void); void o2hb_init(void);
......
...@@ -900,6 +900,16 @@ static struct o2nm_cluster_group o2nm_cluster_group = { ...@@ -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) static void __exit exit_o2nm(void)
{ {
if (ocfs2_table_header) if (ocfs2_table_header)
......
...@@ -77,4 +77,7 @@ struct o2nm_node *o2nm_get_node_by_ip(__be32 addr); ...@@ -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_get(struct o2nm_node *node);
void o2nm_node_put(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 */ #endif /* O2CLUSTER_NODEMANAGER_H */
...@@ -1638,8 +1638,8 @@ static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num, ...@@ -1638,8 +1638,8 @@ static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num,
void o2net_unregister_hb_callbacks(void) void o2net_unregister_hb_callbacks(void)
{ {
o2hb_unregister_callback(&o2net_hb_up); o2hb_unregister_callback(NULL, &o2net_hb_up);
o2hb_unregister_callback(&o2net_hb_down); o2hb_unregister_callback(NULL, &o2net_hb_down);
} }
int o2net_register_hb_callbacks(void) int o2net_register_hb_callbacks(void)
...@@ -1651,9 +1651,9 @@ 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, o2hb_setup_callback(&o2net_hb_up, O2HB_NODE_UP_CB,
o2net_hb_node_up_cb, NULL, O2NET_HB_PRI); 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) if (ret == 0)
ret = o2hb_register_callback(&o2net_hb_down); ret = o2hb_register_callback(NULL, &o2net_hb_down);
if (ret) if (ret)
o2net_unregister_hb_callbacks(); o2net_unregister_hb_callbacks();
......
...@@ -1128,8 +1128,8 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm) ...@@ -1128,8 +1128,8 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm)
static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm) static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm)
{ {
o2hb_unregister_callback(&dlm->dlm_hb_up); o2hb_unregister_callback(NULL, &dlm->dlm_hb_up);
o2hb_unregister_callback(&dlm->dlm_hb_down); o2hb_unregister_callback(NULL, &dlm->dlm_hb_down);
o2net_unregister_handler_list(&dlm->dlm_domain_handlers); o2net_unregister_handler_list(&dlm->dlm_domain_handlers);
} }
...@@ -1141,13 +1141,13 @@ static int dlm_register_domain_handlers(struct dlm_ctxt *dlm) ...@@ -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, o2hb_setup_callback(&dlm->dlm_hb_down, O2HB_NODE_DOWN_CB,
dlm_hb_node_down_cb, dlm, DLM_HB_NODE_DOWN_PRI); 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) if (status)
goto bail; goto bail;
o2hb_setup_callback(&dlm->dlm_hb_up, O2HB_NODE_UP_CB, o2hb_setup_callback(&dlm->dlm_hb_up, O2HB_NODE_UP_CB,
dlm_hb_node_up_cb, dlm, DLM_HB_NODE_UP_PRI); 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) if (status)
goto bail; goto bail;
......
...@@ -157,16 +157,16 @@ int ocfs2_register_hb_callbacks(struct ocfs2_super *osb) ...@@ -157,16 +157,16 @@ int ocfs2_register_hb_callbacks(struct ocfs2_super *osb)
if (ocfs2_mount_local(osb)) if (ocfs2_mount_local(osb))
return 0; return 0;
status = o2hb_register_callback(&osb->osb_hb_down); status = o2hb_register_callback(osb->uuid_str, &osb->osb_hb_down);
if (status < 0) { if (status < 0) {
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
} }
status = o2hb_register_callback(&osb->osb_hb_up); status = o2hb_register_callback(osb->uuid_str, &osb->osb_hb_up);
if (status < 0) { if (status < 0) {
mlog_errno(status); mlog_errno(status);
o2hb_unregister_callback(&osb->osb_hb_down); o2hb_unregister_callback(osb->uuid_str, &osb->osb_hb_down);
} }
bail: bail:
...@@ -178,8 +178,8 @@ void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb) ...@@ -178,8 +178,8 @@ void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb)
if (ocfs2_mount_local(osb)) if (ocfs2_mount_local(osb))
return; return;
o2hb_unregister_callback(&osb->osb_hb_down); o2hb_unregister_callback(osb->uuid_str, &osb->osb_hb_down);
o2hb_unregister_callback(&osb->osb_hb_up); o2hb_unregister_callback(osb->uuid_str, &osb->osb_hb_up);
} }
void ocfs2_stop_heartbeat(struct ocfs2_super *osb) void ocfs2_stop_heartbeat(struct ocfs2_super *osb)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment