^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) ** Copyright (C) 2005-2011 Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "dlm_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "lockspace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "member.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "recoverd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "recover.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "rcom.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "config.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "lowcomms.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) int dlm_slots_version(struct dlm_header *h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if ((h->h_version & 0x0000FFFF) < DLM_HEADER_SLOTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) void dlm_slot_save(struct dlm_ls *ls, struct dlm_rcom *rc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct dlm_member *memb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct rcom_config *rf = (struct rcom_config *)rc->rc_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (!dlm_slots_version(&rc->rc_header))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) memb->slot = le16_to_cpu(rf->rf_our_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) memb->generation = le32_to_cpu(rf->rf_generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) void dlm_slots_copy_out(struct dlm_ls *ls, struct dlm_rcom *rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct dlm_slot *slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct rcom_slot *ro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ro = (struct rcom_slot *)(rc->rc_buf + sizeof(struct rcom_config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* ls_slots array is sparse, but not rcom_slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) for (i = 0; i < ls->ls_slots_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) slot = &ls->ls_slots[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (!slot->nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ro->ro_nodeid = cpu_to_le32(slot->nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ro->ro_slot = cpu_to_le16(slot->slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ro++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define SLOT_DEBUG_LINE 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static void log_slots(struct dlm_ls *ls, uint32_t gen, int num_slots,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct rcom_slot *ro0, struct dlm_slot *array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int array_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) char line[SLOT_DEBUG_LINE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int len = SLOT_DEBUG_LINE - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) memset(line, 0, sizeof(line));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (array) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) for (i = 0; i < array_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (!array[i].nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ret = snprintf(line + pos, len - pos, " %d:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) array[i].slot, array[i].nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (ret >= len - pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) pos += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) } else if (ro0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) for (i = 0; i < num_slots; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ret = snprintf(line + pos, len - pos, " %d:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ro0[i].ro_slot, ro0[i].ro_nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (ret >= len - pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) pos += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) log_rinfo(ls, "generation %u slots %d%s", gen, num_slots, line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int dlm_slots_copy_in(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct dlm_member *memb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct dlm_rcom *rc = ls->ls_recover_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct rcom_config *rf = (struct rcom_config *)rc->rc_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct rcom_slot *ro0, *ro;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int our_nodeid = dlm_our_nodeid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int i, num_slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) uint32_t gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (!dlm_slots_version(&rc->rc_header))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) gen = le32_to_cpu(rf->rf_generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (gen <= ls->ls_generation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) log_error(ls, "dlm_slots_copy_in gen %u old %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) gen, ls->ls_generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ls->ls_generation = gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) num_slots = le16_to_cpu(rf->rf_num_slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (!num_slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ro0 = (struct rcom_slot *)(rc->rc_buf + sizeof(struct rcom_config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) for (i = 0, ro = ro0; i < num_slots; i++, ro++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ro->ro_nodeid = le32_to_cpu(ro->ro_nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ro->ro_slot = le16_to_cpu(ro->ro_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) log_slots(ls, gen, num_slots, ro0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) list_for_each_entry(memb, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) for (i = 0, ro = ro0; i < num_slots; i++, ro++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (ro->ro_nodeid != memb->nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) memb->slot = ro->ro_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) memb->slot_prev = memb->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (memb->nodeid == our_nodeid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (ls->ls_slot && ls->ls_slot != memb->slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) log_error(ls, "dlm_slots_copy_in our slot "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) "changed %d %d", ls->ls_slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) memb->slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (!ls->ls_slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ls->ls_slot = memb->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (!memb->slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) log_error(ls, "dlm_slots_copy_in nodeid %d no slot",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) memb->nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* for any nodes that do not support slots, we will not have set memb->slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) in wait_status_all(), so memb->slot will remain -1, and we will not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) assign slots or set ls_num_slots here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int dlm_slots_assign(struct dlm_ls *ls, int *num_slots, int *slots_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct dlm_slot **slots_out, uint32_t *gen_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct dlm_member *memb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct dlm_slot *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int our_nodeid = dlm_our_nodeid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int array_size, max_slots, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int need = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) uint32_t gen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* our own memb struct will have slot -1 gen 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) list_for_each_entry(memb, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (memb->nodeid == our_nodeid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) memb->slot = ls->ls_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) memb->generation = ls->ls_generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) list_for_each_entry(memb, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (memb->generation > gen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) gen = memb->generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* node doesn't support slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (memb->slot == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* node needs a slot assigned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (!memb->slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) need++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* node has a slot assigned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (!max || max < memb->slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) max = memb->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* sanity check, once slot is assigned it shouldn't change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (memb->slot_prev && memb->slot && memb->slot_prev != memb->slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) log_error(ls, "nodeid %d slot changed %d %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) memb->nodeid, memb->slot_prev, memb->slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) memb->slot_prev = memb->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) array_size = max + need;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) array = kcalloc(array_size, sizeof(*array), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* fill in slots (offsets) that are used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) list_for_each_entry(memb, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!memb->slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (memb->slot > array_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) log_error(ls, "invalid slot number %d", memb->slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) kfree(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) array[memb->slot - 1].nodeid = memb->nodeid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) array[memb->slot - 1].slot = memb->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* assign new slots from unused offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) list_for_each_entry(memb, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (memb->slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) for (i = 0; i < array_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (array[i].nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) memb->slot = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) memb->slot_prev = memb->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) array[i].nodeid = memb->nodeid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) array[i].slot = memb->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (!ls->ls_slot && memb->nodeid == our_nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ls->ls_slot = memb->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (!memb->slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) log_error(ls, "no free slot found");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) kfree(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) gen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) log_slots(ls, gen, num, NULL, array, array_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) max_slots = (dlm_config.ci_buffer_size - sizeof(struct dlm_rcom) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) sizeof(struct rcom_config)) / sizeof(struct rcom_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (num > max_slots) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) log_error(ls, "num_slots %d exceeds max_slots %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) num, max_slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) kfree(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) *gen_out = gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) *slots_out = array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *slots_size = array_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) *num_slots = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static void add_ordered_member(struct dlm_ls *ls, struct dlm_member *new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct dlm_member *memb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct list_head *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct list_head *newlist = &new->list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct list_head *head = &ls->ls_nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) list_for_each(tmp, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) memb = list_entry(tmp, struct dlm_member, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (new->nodeid < memb->nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (!memb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) list_add_tail(newlist, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* FIXME: can use list macro here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) newlist->prev = tmp->prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) newlist->next = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) tmp->prev->next = newlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) tmp->prev = newlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static int dlm_add_member(struct dlm_ls *ls, struct dlm_config_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct dlm_member *memb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) memb = kzalloc(sizeof(*memb), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!memb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) error = dlm_lowcomms_connect_node(node->nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) kfree(memb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) memb->nodeid = node->nodeid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) memb->weight = node->weight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) memb->comm_seq = node->comm_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) add_ordered_member(ls, memb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ls->ls_num_nodes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static struct dlm_member *find_memb(struct list_head *head, int nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct dlm_member *memb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) list_for_each_entry(memb, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (memb->nodeid == nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return memb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int dlm_is_member(struct dlm_ls *ls, int nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (find_memb(&ls->ls_nodes, nodeid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int dlm_is_removed(struct dlm_ls *ls, int nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (find_memb(&ls->ls_nodes_gone, nodeid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static void clear_memb_list(struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct dlm_member *memb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) while (!list_empty(head)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) memb = list_entry(head->next, struct dlm_member, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) list_del(&memb->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) kfree(memb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) void dlm_clear_members(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) clear_memb_list(&ls->ls_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ls->ls_num_nodes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) void dlm_clear_members_gone(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) clear_memb_list(&ls->ls_nodes_gone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static void make_member_array(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct dlm_member *memb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) int i, w, x = 0, total = 0, all_zero = 0, *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) kfree(ls->ls_node_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ls->ls_node_array = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) list_for_each_entry(memb, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (memb->weight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) total += memb->weight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* all nodes revert to weight of 1 if all have weight 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (!total) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) total = ls->ls_num_nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) all_zero = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ls->ls_total_weight = total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) array = kmalloc_array(total, sizeof(*array), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (!array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) list_for_each_entry(memb, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (!all_zero && !memb->weight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (all_zero)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) w = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) w = memb->weight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) DLM_ASSERT(x < total, printk("total %d x %d\n", total, x););
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) for (i = 0; i < w; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) array[x++] = memb->nodeid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ls->ls_node_array = array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* send a status request to all members just to establish comms connections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static int ping_members(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct dlm_member *memb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) list_for_each_entry(memb, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) error = dlm_recovery_stopped(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) error = dlm_rcom_status(ls, memb->nodeid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) log_rinfo(ls, "ping_members aborted %d last nodeid %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) error, ls->ls_recover_nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static void dlm_lsop_recover_prep(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (!ls->ls_ops || !ls->ls_ops->recover_prep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ls->ls_ops->recover_prep(ls->ls_ops_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static void dlm_lsop_recover_slot(struct dlm_ls *ls, struct dlm_member *memb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct dlm_slot slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) uint32_t seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (!ls->ls_ops || !ls->ls_ops->recover_slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* if there is no comms connection with this node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) or the present comms connection is newer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) than the one when this member was added, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) we consider the node to have failed (versus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) being removed due to dlm_release_lockspace) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) error = dlm_comm_seq(memb->nodeid, &seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (!error && seq == memb->comm_seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) slot.nodeid = memb->nodeid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) slot.slot = memb->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ls->ls_ops->recover_slot(ls->ls_ops_arg, &slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) void dlm_lsop_recover_done(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct dlm_member *memb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct dlm_slot *slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int i, num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (!ls->ls_ops || !ls->ls_ops->recover_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) num = ls->ls_num_nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) slots = kcalloc(num, sizeof(*slots), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) list_for_each_entry(memb, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (i == num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) log_error(ls, "dlm_lsop_recover_done bad num %d", num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) slots[i].nodeid = memb->nodeid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) slots[i].slot = memb->slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ls->ls_ops->recover_done(ls->ls_ops_arg, slots, num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ls->ls_slot, ls->ls_generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) kfree(slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static struct dlm_config_node *find_config_node(struct dlm_recover *rv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) int nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) for (i = 0; i < rv->nodes_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (rv->nodes[i].nodeid == nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return &rv->nodes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct dlm_member *memb, *safe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct dlm_config_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int i, error, neg = 0, low = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* previously removed members that we've not finished removing need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) count as a negative change so the "neg" recovery steps will happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) list_for_each_entry(memb, &ls->ls_nodes_gone, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) log_rinfo(ls, "prev removed member %d", memb->nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) neg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /* move departed members from ls_nodes to ls_nodes_gone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) node = find_config_node(rv, memb->nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (node && !node->new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) log_rinfo(ls, "remove member %d", memb->nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* removed and re-added */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) log_rinfo(ls, "remove member %d comm_seq %u %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) memb->nodeid, memb->comm_seq, node->comm_seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) neg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) list_move(&memb->list, &ls->ls_nodes_gone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) ls->ls_num_nodes--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) dlm_lsop_recover_slot(ls, memb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* add new members to ls_nodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) for (i = 0; i < rv->nodes_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) node = &rv->nodes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (dlm_is_member(ls, node->nodeid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) dlm_add_member(ls, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) log_rinfo(ls, "add member %d", node->nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) list_for_each_entry(memb, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (low == -1 || memb->nodeid < low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) low = memb->nodeid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ls->ls_low_nodeid = low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) make_member_array(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) *neg_out = neg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) error = ping_members(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (!error || error == -EPROTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /* new_lockspace() may be waiting to know if the config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) is good or bad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ls->ls_members_result = error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) complete(&ls->ls_members_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) log_rinfo(ls, "dlm_recover_members %d nodes", ls->ls_num_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /* Userspace guarantees that dlm_ls_stop() has completed on all nodes before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) dlm_ls_start() is called on any of them to start the new recovery. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) int dlm_ls_stop(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) int new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * Prevent dlm_recv from being in the middle of something when we do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * the stop. This includes ensuring dlm_recv isn't processing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * recovery message (rcom), while dlm_recoverd is aborting and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * resetting things from an in-progress recovery. i.e. we want
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * dlm_recoverd to abort its recovery without worrying about dlm_recv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * processing an rcom at the same time. Stopping dlm_recv also makes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * it easy for dlm_receive_message() to check locking stopped and add a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * message to the requestqueue without races.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) down_write(&ls->ls_recv_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * Abort any recovery that's in progress (see RECOVER_STOP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * dlm_recovery_stopped()) and tell any other threads running in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * dlm to quit any processing (see RUNNING, dlm_locking_stopped()).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) spin_lock(&ls->ls_recover_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) set_bit(LSFL_RECOVER_STOP, &ls->ls_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) new = test_and_clear_bit(LSFL_RUNNING, &ls->ls_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) ls->ls_recover_seq++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) spin_unlock(&ls->ls_recover_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * Let dlm_recv run again, now any normal messages will be saved on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * requestqueue for later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) up_write(&ls->ls_recv_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * This in_recovery lock does two things:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * 1) Keeps this function from returning until all threads are out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * of locking routines and locking is truly stopped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * 2) Keeps any new requests from being processed until it's unlocked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * when recovery is complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) set_bit(LSFL_RECOVER_DOWN, &ls->ls_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) wake_up_process(ls->ls_recoverd_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) wait_event(ls->ls_recover_lock_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) test_bit(LSFL_RECOVER_LOCK, &ls->ls_flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * The recoverd suspend/resume makes sure that dlm_recoverd (if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * running) has noticed RECOVER_STOP above and quit processing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * previous recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) dlm_recoverd_suspend(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) spin_lock(&ls->ls_recover_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) kfree(ls->ls_slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ls->ls_slots = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ls->ls_num_slots = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ls->ls_slots_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ls->ls_recover_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) spin_unlock(&ls->ls_recover_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) dlm_recoverd_resume(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (!ls->ls_recover_begin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) ls->ls_recover_begin = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) dlm_lsop_recover_prep(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) int dlm_ls_start(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct dlm_recover *rv, *rv_old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct dlm_config_node *nodes = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) int error, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) rv = kzalloc(sizeof(*rv), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (!rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) error = dlm_config_nodes(ls->ls_name, &nodes, &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) goto fail_rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) spin_lock(&ls->ls_recover_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /* the lockspace needs to be stopped before it can be started */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (!dlm_locking_stopped(ls)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) spin_unlock(&ls->ls_recover_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) log_error(ls, "start ignored: lockspace running");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) rv->nodes = nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) rv->nodes_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) rv->seq = ++ls->ls_recover_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) rv_old = ls->ls_recover_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) ls->ls_recover_args = rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) spin_unlock(&ls->ls_recover_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (rv_old) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) log_error(ls, "unused recovery %llx %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) (unsigned long long)rv_old->seq, rv_old->nodes_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) kfree(rv_old->nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) kfree(rv_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) set_bit(LSFL_RECOVER_WORK, &ls->ls_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) wake_up_process(ls->ls_recoverd_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) kfree(nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) fail_rv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) kfree(rv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)