^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) Sistina Software, Inc. 1997-2003 All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "dlm_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "lockspace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "member.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "lowcomms.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 "memory.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "recover.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "util.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "lock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "dir.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * We use the upper 16 bits of the hash value to select the directory node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Low bits are used for distribution of rsb's among hash buckets on each node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * To give the exact range wanted (0 to num_nodes-1), we apply a modulus of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * num_nodes to the hash value. This value in the desired range is used as an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * offset into the sorted list of nodeid's to give the particular nodeid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int dlm_hash2nodeid(struct dlm_ls *ls, uint32_t hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) uint32_t node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (ls->ls_num_nodes == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return dlm_our_nodeid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) node = (hash >> 16) % ls->ls_total_weight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return ls->ls_node_array[node];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int dlm_dir_nodeid(struct dlm_rsb *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return r->res_dir_nodeid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void dlm_recover_dir_nodeid(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct dlm_rsb *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) down_read(&ls->ls_root_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) list_for_each_entry(r, &ls->ls_root_list, res_root_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) r->res_dir_nodeid = dlm_hash2nodeid(ls, r->res_hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) up_read(&ls->ls_root_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int dlm_recover_directory(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct dlm_member *memb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) char *b, *last_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int error = -ENOMEM, last_len, nodeid, result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) uint16_t namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned int count = 0, count_match = 0, count_bad = 0, count_add = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) log_rinfo(ls, "dlm_recover_directory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (dlm_no_directory(ls))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) goto out_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) last_name = kmalloc(DLM_RESNAME_MAXLEN, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (!last_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) list_for_each_entry(memb, &ls->ls_nodes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (memb->nodeid == dlm_our_nodeid())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) memset(last_name, 0, DLM_RESNAME_MAXLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) last_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) error = dlm_recovery_stopped(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) error = dlm_rcom_names(ls, memb->nodeid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) last_name, last_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * pick namelen/name pairs out of received buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) b = ls->ls_recover_buf->rc_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) left = ls->ls_recover_buf->rc_header.h_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) left -= sizeof(struct dlm_rcom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) __be16 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (left < sizeof(__be16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) memcpy(&v, b, sizeof(__be16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) namelen = be16_to_cpu(v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) b += sizeof(__be16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) left -= sizeof(__be16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* namelen of 0xFFFFF marks end of names for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) this node; namelen of 0 marks end of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (namelen == 0xFFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (!namelen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (namelen > left)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (namelen > DLM_RESNAME_MAXLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) error = dlm_master_lookup(ls, memb->nodeid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) b, namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) DLM_LU_RECOVER_DIR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) &nodeid, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) log_error(ls, "recover_dir lookup %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* The name was found in rsbtbl, but the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * master nodeid is different from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * memb->nodeid which says it is the master.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * This should not happen. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (result == DLM_LU_MATCH &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) nodeid != memb->nodeid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) count_bad++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) log_error(ls, "recover_dir lookup %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) "nodeid %d memb %d bad %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) result, nodeid, memb->nodeid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) count_bad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) print_hex_dump_bytes("dlm_recover_dir ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) DUMP_PREFIX_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) b, namelen);
^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) /* The name was found in rsbtbl, and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * master nodeid matches memb->nodeid. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (result == DLM_LU_MATCH &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) nodeid == memb->nodeid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) count_match++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* The name was not found in rsbtbl and was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * added with memb->nodeid as the master. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (result == DLM_LU_ADD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) count_add++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) last_len = namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) memcpy(last_name, b, namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) b += namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) left -= namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) done:
^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) out_status:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dlm_set_recover_status(ls, DLM_RS_DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) log_rinfo(ls, "dlm_recover_directory %u in %u new",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) count, count_add);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) kfree(last_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct dlm_rsb *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) uint32_t hash, bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) hash = jhash(name, len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) bucket = hash & (ls->ls_rsbtbl_size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) spin_lock(&ls->ls_rsbtbl[bucket].lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[bucket].keep, name, len, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[bucket].toss,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) name, len, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) spin_unlock(&ls->ls_rsbtbl[bucket].lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (!rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) down_read(&ls->ls_root_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) list_for_each_entry(r, &ls->ls_root_list, res_root_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (len == r->res_length && !memcmp(name, r->res_name, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) up_read(&ls->ls_root_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) log_debug(ls, "find_rsb_root revert to root_list %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) r->res_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) up_read(&ls->ls_root_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* Find the rsb where we left off (or start again), then send rsb names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) for rsb's we're master of and whose directory node matches the requesting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) node. inbuf is the rsb name last sent, inlen is the name's length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) char *outbuf, int outlen, int nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct list_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct dlm_rsb *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int offset = 0, dir_nodeid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) __be16 be_namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) down_read(&ls->ls_root_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (inlen > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) r = find_rsb_root(ls, inbuf, inlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) inbuf[inlen - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) log_error(ls, "copy_master_names from %d start %d %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) nodeid, inlen, inbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) list = r->res_root_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) list = ls->ls_root_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) for (offset = 0; list != &ls->ls_root_list; list = list->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) r = list_entry(list, struct dlm_rsb, res_root_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (r->res_nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dir_nodeid = dlm_dir_nodeid(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (dir_nodeid != nodeid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * The block ends when we can't fit the following in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * remaining buffer space:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * namelen (uint16_t) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * name (r->res_length) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * end-of-block record 0x0000 (uint16_t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (offset + sizeof(uint16_t)*2 + r->res_length > outlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* Write end-of-block record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) be_namelen = cpu_to_be16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) memcpy(outbuf + offset, &be_namelen, sizeof(__be16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) offset += sizeof(__be16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ls->ls_recover_dir_sent_msg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) goto out;
^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) be_namelen = cpu_to_be16(r->res_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) memcpy(outbuf + offset, &be_namelen, sizeof(__be16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) offset += sizeof(__be16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) memcpy(outbuf + offset, r->res_name, r->res_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) offset += r->res_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ls->ls_recover_dir_sent_res++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * If we've reached the end of the list (and there's room) write a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * terminating record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if ((list == &ls->ls_root_list) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) (offset + sizeof(uint16_t) <= outlen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) be_namelen = cpu_to_be16(0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) memcpy(outbuf + offset, &be_namelen, sizeof(__be16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) offset += sizeof(__be16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ls->ls_recover_dir_sent_msg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) up_read(&ls->ls_root_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)