18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* -*- mode: c; c-basic-offset: 8; -*- 38c2ecf20Sopenharmony_ci * vim: noexpandtab sw=8 ts=8 sts=0: 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * heartbeat.c 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Register ourselves with the heartbaet service, keep our node maps 88c2ecf20Sopenharmony_ci * up to date, and fire off recovery when needed. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Copyright (C) 2002, 2004 Oracle. All rights reserved. 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/fs.h> 148c2ecf20Sopenharmony_ci#include <linux/types.h> 158c2ecf20Sopenharmony_ci#include <linux/highmem.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <cluster/masklog.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#include "ocfs2.h" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include "alloc.h" 228c2ecf20Sopenharmony_ci#include "heartbeat.h" 238c2ecf20Sopenharmony_ci#include "inode.h" 248c2ecf20Sopenharmony_ci#include "journal.h" 258c2ecf20Sopenharmony_ci#include "ocfs2_trace.h" 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#include "buffer_head_io.h" 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistatic inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map, 308c2ecf20Sopenharmony_ci int bit); 318c2ecf20Sopenharmony_cistatic inline void __ocfs2_node_map_clear_bit(struct ocfs2_node_map *map, 328c2ecf20Sopenharmony_ci int bit); 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci/* special case -1 for now 358c2ecf20Sopenharmony_ci * TODO: should *really* make sure the calling func never passes -1!! */ 368c2ecf20Sopenharmony_cistatic void ocfs2_node_map_init(struct ocfs2_node_map *map) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci map->num_nodes = OCFS2_NODE_MAP_MAX_NODES; 398c2ecf20Sopenharmony_ci memset(map->map, 0, BITS_TO_LONGS(OCFS2_NODE_MAP_MAX_NODES) * 408c2ecf20Sopenharmony_ci sizeof(unsigned long)); 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_civoid ocfs2_init_node_maps(struct ocfs2_super *osb) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci spin_lock_init(&osb->node_map_lock); 468c2ecf20Sopenharmony_ci ocfs2_node_map_init(&osb->osb_recovering_orphan_dirs); 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_civoid ocfs2_do_node_down(int node_num, void *data) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci struct ocfs2_super *osb = data; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci BUG_ON(osb->node_num == node_num); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci trace_ocfs2_do_node_down(node_num); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci if (!osb->cconn) { 588c2ecf20Sopenharmony_ci /* 598c2ecf20Sopenharmony_ci * No cluster connection means we're not even ready to 608c2ecf20Sopenharmony_ci * participate yet. We check the slots after the cluster 618c2ecf20Sopenharmony_ci * comes up, so we will notice the node death then. We 628c2ecf20Sopenharmony_ci * can safely ignore it here. 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_ci return; 658c2ecf20Sopenharmony_ci } 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci ocfs2_recovery_thread(osb, node_num); 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map, 718c2ecf20Sopenharmony_ci int bit) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci set_bit(bit, map->map); 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_civoid ocfs2_node_map_set_bit(struct ocfs2_super *osb, 778c2ecf20Sopenharmony_ci struct ocfs2_node_map *map, 788c2ecf20Sopenharmony_ci int bit) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci if (bit==-1) 818c2ecf20Sopenharmony_ci return; 828c2ecf20Sopenharmony_ci BUG_ON(bit >= map->num_nodes); 838c2ecf20Sopenharmony_ci spin_lock(&osb->node_map_lock); 848c2ecf20Sopenharmony_ci __ocfs2_node_map_set_bit(map, bit); 858c2ecf20Sopenharmony_ci spin_unlock(&osb->node_map_lock); 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic inline void __ocfs2_node_map_clear_bit(struct ocfs2_node_map *map, 898c2ecf20Sopenharmony_ci int bit) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci clear_bit(bit, map->map); 928c2ecf20Sopenharmony_ci} 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_civoid ocfs2_node_map_clear_bit(struct ocfs2_super *osb, 958c2ecf20Sopenharmony_ci struct ocfs2_node_map *map, 968c2ecf20Sopenharmony_ci int bit) 978c2ecf20Sopenharmony_ci{ 988c2ecf20Sopenharmony_ci if (bit==-1) 998c2ecf20Sopenharmony_ci return; 1008c2ecf20Sopenharmony_ci BUG_ON(bit >= map->num_nodes); 1018c2ecf20Sopenharmony_ci spin_lock(&osb->node_map_lock); 1028c2ecf20Sopenharmony_ci __ocfs2_node_map_clear_bit(map, bit); 1038c2ecf20Sopenharmony_ci spin_unlock(&osb->node_map_lock); 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ciint ocfs2_node_map_test_bit(struct ocfs2_super *osb, 1078c2ecf20Sopenharmony_ci struct ocfs2_node_map *map, 1088c2ecf20Sopenharmony_ci int bit) 1098c2ecf20Sopenharmony_ci{ 1108c2ecf20Sopenharmony_ci int ret; 1118c2ecf20Sopenharmony_ci if (bit >= map->num_nodes) { 1128c2ecf20Sopenharmony_ci mlog(ML_ERROR, "bit=%d map->num_nodes=%d\n", bit, map->num_nodes); 1138c2ecf20Sopenharmony_ci BUG(); 1148c2ecf20Sopenharmony_ci } 1158c2ecf20Sopenharmony_ci spin_lock(&osb->node_map_lock); 1168c2ecf20Sopenharmony_ci ret = test_bit(bit, map->map); 1178c2ecf20Sopenharmony_ci spin_unlock(&osb->node_map_lock); 1188c2ecf20Sopenharmony_ci return ret; 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 121