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: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
This commit is contained in:
@@ -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(®->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(®->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);
|
||||
|
Reference in New Issue
Block a user