// SPDX-License-Identifier: GPL-2.0-only /****************************************************************************** ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. ** ** *******************************************************************************
******************************************************************************/
/* * We use the upper 16 bits of the hash value to select the directory node. * Low bits are used for distribution of rsb's among hash buckets on each node. * * To give the exact range wanted (0 to num_nodes-1), we apply a modulus of * num_nodes to the hash value. This value in the desired range is used as an * offset into the sorted list of nodeid's to give the particular nodeid.
*/
int dlm_hash2nodeid(struct dlm_ls *ls, uint32_t hash)
{
uint32_t node;
struct dlm_dir_dump { /* init values to match if whole * dump fits to one seq. Sanity check only.
*/
uint64_t seq_init;
uint64_t nodeid_init; /* compare local pointer with last lookup, * just a sanity check.
*/ struct list_head *last;
unsignedint sent_res; /* for log info */ unsignedint sent_msg; /* for log info */
/* Find the rsb where we left off (or start again), then send rsb names for rsb's we're master of and whose directory node matches the requesting
node. inbuf is the rsb name last sent, inlen is the name's length */
void dlm_copy_master_names(struct dlm_ls *ls, constchar *inbuf, int inlen, char *outbuf, int outlen, int nodeid)
{ struct list_head *list; struct dlm_rsb *r; int offset = 0, dir_nodeid; struct dlm_dir_dump *dd;
__be16 be_namelen;
read_lock_bh(&ls->ls_masters_lock);
if (inlen > 1) {
dd = lookup_dir_dump(ls, nodeid); if (!dd) {
log_error(ls, "failed to lookup dir dump context nodeid: %d",
nodeid); goto out;
}
/* next chunk in dump */
r = find_rsb_root(ls, inbuf, inlen); if (!r) {
log_error(ls, "copy_master_names from %d start %d %.*s",
nodeid, inlen, inlen, inbuf); goto out;
}
list = r->res_masters_list.next;
/* sanity checks */ if (dd->last != &r->res_masters_list ||
dd->seq_init != ls->ls_recover_seq) {
log_error(ls, "failed dir dump sanity check seq_init: %llu seq: %llu",
(unsignedlonglong)dd->seq_init,
(unsignedlonglong)ls->ls_recover_seq); goto out;
}
} else {
dd = init_dir_dump(ls, nodeid); if (!dd) {
log_error(ls, "failed to allocate dir dump context"); goto out;
}
for (offset = 0; list != &ls->ls_masters_list; list = list->next) {
r = list_entry(list, struct dlm_rsb, res_masters_list);
dir_nodeid = dlm_dir_nodeid(r); if (dir_nodeid != nodeid) continue;
/* * The block ends when we can't fit the following in the * remaining buffer space: * namelen (uint16_t) + * name (r->res_length) + * end-of-block record 0x0000 (uint16_t)
*/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.