162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * heartbeat.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Register ourselves with the heartbeat service, keep our node maps
662306a36Sopenharmony_ci * up to date, and fire off recovery when needed.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/bitmap.h>
1262306a36Sopenharmony_ci#include <linux/fs.h>
1362306a36Sopenharmony_ci#include <linux/types.h>
1462306a36Sopenharmony_ci#include <linux/highmem.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <cluster/masklog.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include "ocfs2.h"
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include "alloc.h"
2162306a36Sopenharmony_ci#include "heartbeat.h"
2262306a36Sopenharmony_ci#include "inode.h"
2362306a36Sopenharmony_ci#include "journal.h"
2462306a36Sopenharmony_ci#include "ocfs2_trace.h"
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#include "buffer_head_io.h"
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/* special case -1 for now
2962306a36Sopenharmony_ci * TODO: should *really* make sure the calling func never passes -1!!  */
3062306a36Sopenharmony_cistatic void ocfs2_node_map_init(struct ocfs2_node_map *map)
3162306a36Sopenharmony_ci{
3262306a36Sopenharmony_ci	map->num_nodes = OCFS2_NODE_MAP_MAX_NODES;
3362306a36Sopenharmony_ci	bitmap_zero(map->map, OCFS2_NODE_MAP_MAX_NODES);
3462306a36Sopenharmony_ci}
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_civoid ocfs2_init_node_maps(struct ocfs2_super *osb)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	spin_lock_init(&osb->node_map_lock);
3962306a36Sopenharmony_ci	ocfs2_node_map_init(&osb->osb_recovering_orphan_dirs);
4062306a36Sopenharmony_ci}
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_civoid ocfs2_do_node_down(int node_num, void *data)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	struct ocfs2_super *osb = data;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	BUG_ON(osb->node_num == node_num);
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	trace_ocfs2_do_node_down(node_num);
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	if (!osb->cconn) {
5162306a36Sopenharmony_ci		/*
5262306a36Sopenharmony_ci		 * No cluster connection means we're not even ready to
5362306a36Sopenharmony_ci		 * participate yet.  We check the slots after the cluster
5462306a36Sopenharmony_ci		 * comes up, so we will notice the node death then.  We
5562306a36Sopenharmony_ci		 * can safely ignore it here.
5662306a36Sopenharmony_ci		 */
5762306a36Sopenharmony_ci		return;
5862306a36Sopenharmony_ci	}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	ocfs2_recovery_thread(osb, node_num);
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_civoid ocfs2_node_map_set_bit(struct ocfs2_super *osb,
6462306a36Sopenharmony_ci			    struct ocfs2_node_map *map,
6562306a36Sopenharmony_ci			    int bit)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	if (bit==-1)
6862306a36Sopenharmony_ci		return;
6962306a36Sopenharmony_ci	BUG_ON(bit >= map->num_nodes);
7062306a36Sopenharmony_ci	spin_lock(&osb->node_map_lock);
7162306a36Sopenharmony_ci	set_bit(bit, map->map);
7262306a36Sopenharmony_ci	spin_unlock(&osb->node_map_lock);
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_civoid ocfs2_node_map_clear_bit(struct ocfs2_super *osb,
7662306a36Sopenharmony_ci			      struct ocfs2_node_map *map,
7762306a36Sopenharmony_ci			      int bit)
7862306a36Sopenharmony_ci{
7962306a36Sopenharmony_ci	if (bit==-1)
8062306a36Sopenharmony_ci		return;
8162306a36Sopenharmony_ci	BUG_ON(bit >= map->num_nodes);
8262306a36Sopenharmony_ci	spin_lock(&osb->node_map_lock);
8362306a36Sopenharmony_ci	clear_bit(bit, map->map);
8462306a36Sopenharmony_ci	spin_unlock(&osb->node_map_lock);
8562306a36Sopenharmony_ci}
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ciint ocfs2_node_map_test_bit(struct ocfs2_super *osb,
8862306a36Sopenharmony_ci			    struct ocfs2_node_map *map,
8962306a36Sopenharmony_ci			    int bit)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	int ret;
9262306a36Sopenharmony_ci	if (bit >= map->num_nodes) {
9362306a36Sopenharmony_ci		mlog(ML_ERROR, "bit=%d map->num_nodes=%d\n", bit, map->num_nodes);
9462306a36Sopenharmony_ci		BUG();
9562306a36Sopenharmony_ci	}
9662306a36Sopenharmony_ci	spin_lock(&osb->node_map_lock);
9762306a36Sopenharmony_ci	ret = test_bit(bit, map->map);
9862306a36Sopenharmony_ci	spin_unlock(&osb->node_map_lock);
9962306a36Sopenharmony_ci	return ret;
10062306a36Sopenharmony_ci}
10162306a36Sopenharmony_ci
102