aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/cluster/heartbeat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/cluster/heartbeat.c')
-rw-r--r--fs/ocfs2/cluster/heartbeat.c64
1 files changed, 62 insertions, 2 deletions
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 979113479c66..e331f4cb2c81 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1665,7 +1665,56 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc,
1665} 1665}
1666EXPORT_SYMBOL_GPL(o2hb_setup_callback); 1666EXPORT_SYMBOL_GPL(o2hb_setup_callback);
1667 1667
1668int o2hb_register_callback(struct o2hb_callback_func *hc) 1668static struct o2hb_region *o2hb_find_region(const char *region_uuid)
1669{
1670 struct o2hb_region *p, *reg = NULL;
1671
1672 assert_spin_locked(&o2hb_live_lock);
1673
1674 list_for_each_entry(p, &o2hb_all_regions, hr_all_item) {
1675 if (!strcmp(region_uuid, config_item_name(&p->hr_item))) {
1676 reg = p;
1677 break;
1678 }
1679 }
1680
1681 return reg;
1682}
1683
1684static int o2hb_region_get(const char *region_uuid)
1685{
1686 int ret = 0;
1687 struct o2hb_region *reg;
1688
1689 spin_lock(&o2hb_live_lock);
1690
1691 reg = o2hb_find_region(region_uuid);
1692 if (!reg)
1693 ret = -ENOENT;
1694 spin_unlock(&o2hb_live_lock);
1695
1696 if (!ret)
1697 ret = o2nm_depend_item(&reg->hr_item);
1698
1699 return ret;
1700}
1701
1702static void o2hb_region_put(const char *region_uuid)
1703{
1704 struct o2hb_region *reg;
1705
1706 spin_lock(&o2hb_live_lock);
1707
1708 reg = o2hb_find_region(region_uuid);
1709
1710 spin_unlock(&o2hb_live_lock);
1711
1712 if (reg)
1713 o2nm_undepend_item(&reg->hr_item);
1714}
1715
1716int o2hb_register_callback(const char *region_uuid,
1717 struct o2hb_callback_func *hc)
1669{ 1718{
1670 struct o2hb_callback_func *tmp; 1719 struct o2hb_callback_func *tmp;
1671 struct list_head *iter; 1720 struct list_head *iter;
@@ -1681,6 +1730,12 @@ int o2hb_register_callback(struct o2hb_callback_func *hc)
1681 goto out; 1730 goto out;
1682 } 1731 }
1683 1732
1733 if (region_uuid) {
1734 ret = o2hb_region_get(region_uuid);
1735 if (ret)
1736 goto out;
1737 }
1738
1684 down_write(&o2hb_callback_sem); 1739 down_write(&o2hb_callback_sem);
1685 1740
1686 list_for_each(iter, &hbcall->list) { 1741 list_for_each(iter, &hbcall->list) {
@@ -1702,16 +1757,21 @@ out:
1702} 1757}
1703EXPORT_SYMBOL_GPL(o2hb_register_callback); 1758EXPORT_SYMBOL_GPL(o2hb_register_callback);
1704 1759
1705void o2hb_unregister_callback(struct o2hb_callback_func *hc) 1760void o2hb_unregister_callback(const char *region_uuid,
1761 struct o2hb_callback_func *hc)
1706{ 1762{
1707 BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); 1763 BUG_ON(hc->hc_magic != O2HB_CB_MAGIC);
1708 1764
1709 mlog(ML_HEARTBEAT, "on behalf of %p for funcs %p\n", 1765 mlog(ML_HEARTBEAT, "on behalf of %p for funcs %p\n",
1710 __builtin_return_address(0), hc); 1766 __builtin_return_address(0), hc);
1711 1767
1768 /* XXX Can this happen _with_ a region reference? */
1712 if (list_empty(&hc->hc_item)) 1769 if (list_empty(&hc->hc_item))
1713 return; 1770 return;
1714 1771
1772 if (region_uuid)
1773 o2hb_region_put(region_uuid);
1774
1715 down_write(&o2hb_callback_sem); 1775 down_write(&o2hb_callback_sem);
1716 1776
1717 list_del_init(&hc->hc_item); 1777 list_del_init(&hc->hc_item);