/* SPDX-License-Identifier: GPL-2.0-only */ /****************************************************************************** ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. ** Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved. ** ** *******************************************************************************
******************************************************************************/
/* * Lock block * * A lock can be one of three types: * * local copy lock is mastered locally * (lkb_nodeid is zero and DLM_LKF_MSTCPY is not set) * process copy lock is mastered on a remote node * (lkb_nodeid is non-zero and DLM_LKF_MSTCPY is not set) * master copy master node's copy of a lock owned by remote node * (lkb_nodeid is non-zero and DLM_LKF_MSTCPY is set) * * lkb_exflags: a copy of the most recent flags arg provided to dlm_lock or * dlm_unlock. The dlm does not modify these or use any private flags in * this field; it only contains DLM_LKF_ flags from dlm.h. These flags * are sent as-is to the remote master when the lock is remote. * * lkb_flags: internal dlm flags (DLM_IFL_ prefix) from dlm_internal.h. * Some internal flags are shared between the master and process nodes; * these shared flags are kept in the lower two bytes. One of these * flags set on the master copy will be propagated to the process copy * and v.v. Other internal flags are private to the master or process * node (e.g. DLM_IFL_MSTCPY). These are kept in the high two bytes. * * lkb_sbflags: status block flags. These flags are copied directly into * the caller's lksb.sb_flags prior to the dlm_lock/dlm_unlock completion * ast. All defined in dlm.h with DLM_SBF_ prefix. * * lkb_status: the lock status indicates which rsb queue the lock is * on, grant, convert, or wait. DLM_LKSTS_ WAITING/GRANTED/CONVERT * * lkb_wait_type: the dlm message type (DLM_MSG_ prefix) for which a * reply is needed. Only set when the lkb is on the lockspace waiters * list awaiting a reply from a remote node. * * lkb_nodeid: when the lkb is a local copy, nodeid is 0; when the lkb * is a master copy, nodeid specifies the remote lock holder, when the * lkb is a process copy, the nodeid specifies the lock master.
*/
/* much of this is just saving user space pointers associated with the * lock that we pass back to the user lib with an ast
*/
struct dlm_user_args { struct dlm_user_proc *proc; /* each process that opens the lockspace * device has private data * (dlm_user_proc) on the struct file, * the process's locks point back to it
*/ struct dlm_lksb lksb; struct dlm_lksb __user *user_lksb; void __user *castparam; void __user *castaddr; void __user *bastparam; void __user *bastaddr;
uint64_t xid;
};
struct dlm_callback {
uint32_t flags; /* DLM_CBF_ */ int sb_status; /* copy to lksb status */
uint8_t sb_flags; /* copy to lksb flags */
int8_t mode; /* rq mode of bast, gr mode of cast */ bool copy_lvb; struct dlm_lksb *lkb_lksb; unsignedchar lvbptr[DLM_USER_LVB_LEN];
int8_t lkb_wait_type; /* type of reply waiting for */
int8_t lkb_wait_count; int lkb_wait_nodeid; /* for debugging */
struct list_head lkb_statequeue; /* rsb g/c/w list */ struct list_head lkb_rsb_lookup; /* waiting for rsb lookup */ struct list_head lkb_wait_reply; /* waiting for remote reply */ struct list_head lkb_ownqueue; /* list of locks for a process */
ktime_t lkb_timestamp;
int8_t lkb_last_cast_cb_mode;
int8_t lkb_last_bast_cb_mode;
int8_t lkb_last_cb_mode;
uint8_t lkb_last_cb_flags;
ktime_t lkb_last_cast_time; /* for debugging */
ktime_t lkb_last_bast_time; /* for debugging */
uint64_t lkb_recover_seq; /* from ls_recover_seq */
/* * res_master_nodeid is "normal": 0 is unset/invalid, non-zero is the real * nodeid, even when nodeid is our_nodeid. * * res_nodeid is "odd": -1 is unset/invalid, zero means our_nodeid, * greater than zero when another nodeid. * * (TODO: remove res_nodeid and only use res_master_nodeid)
*/
struct dlm_rsb { struct dlm_ls *res_ls; /* the lockspace */ struct kref res_ref;
spinlock_t res_lock; unsignedlong res_flags; int res_length; /* length of rsb name */ int res_nodeid; int res_master_nodeid; int res_dir_nodeid; unsignedlong res_id; /* for ls_recover_xa */
uint32_t res_lvbseq;
uint32_t res_hash; unsignedlong res_toss_time;
uint32_t res_first_lkid; struct list_head res_lookup; /* lkbs waiting on first */ struct rhash_head res_node; /* rsbtbl */ struct list_head res_grantqueue; struct list_head res_convertqueue; struct list_head res_waitqueue;
struct list_head res_slow_list; /* ls_slow_* */ struct list_head res_scan_list; struct list_head res_root_list; /* used for recovery */ struct list_head res_masters_list; /* used for recovery */ struct list_head res_recover_list; /* used for recovery */ int res_recover_locks_count; struct rcu_head rcu;
struct dlm_ls { struct list_head ls_list; /* list of lockspaces */
uint32_t ls_global_id; /* global unique lockspace ID */
uint32_t ls_generation;
uint32_t ls_exflags; int ls_lvblen;
atomic_t ls_count; /* refcount of processes in
the dlm using this ls */
wait_queue_head_t ls_count_wait; int ls_create_count; /* create/release refcount */ unsignedlong ls_flags; /* LSFL_ */ struct kobject ls_kobj;
struct xarray ls_lkbxa;
rwlock_t ls_lkbxa_lock;
/* an rsb is on rsbtl for primary locking functions,
and on a slow list for recovery/dump iteration */ struct rhashtable ls_rsbtbl;
rwlock_t ls_rsbtbl_lock; /* for ls_rsbtbl and ls_slow */ struct list_head ls_slow_inactive; /* to iterate rsbtbl */ struct list_head ls_slow_active; /* to iterate rsbtbl */
struct timer_list ls_scan_timer; /* based on first scan_list rsb toss_time */ struct list_head ls_scan_list; /* rsbs ordered by res_toss_time */
spinlock_t ls_scan_lock;
struct list_head ls_nodes; /* current nodes in ls */ struct list_head ls_nodes_gone; /* dead node list, recovery */ int ls_num_nodes; /* number of nodes in ls */ int ls_low_nodeid; int ls_total_weight; int *ls_node_array;
int ls_slot; int ls_num_slots; int ls_slots_size; struct dlm_slot *ls_slots;
struct dlm_rsb ls_local_rsb; /* for returning errors */ struct dlm_lkb ls_local_lkb; /* for returning errors */ struct dlm_message ls_local_ms; /* for faking a reply */
int ls_namelen; char ls_name[DLM_LOCKSPACE_LEN + 1];
};
/* * LSFL_RECOVER_STOP - dlm_ls_stop() sets this to tell dlm recovery routines * that they should abort what they're doing so new recovery can be started. * * LSFL_RECOVER_DOWN - dlm_ls_stop() sets this to tell dlm_recoverd that it * should do down_write() on the in_recovery rw_semaphore. (doing down_write * within dlm_ls_stop causes complaints about the lock acquired/released * in different contexts.) * * LSFL_RECOVER_LOCK - dlm_recoverd holds the in_recovery rw_semaphore. * It sets this after it is done with down_write() on the in_recovery * rw_semaphore and clears it after it has released the rw_semaphore. * * LSFL_RECOVER_WORK - dlm_ls_start() sets this to tell dlm_recoverd that it * should begin recovery of the lockspace. * * LSFL_RUNNING - set when normal locking activity is enabled. * dlm_ls_stop() clears this to tell dlm locking routines that they should * quit what they are doing so recovery can run. dlm_recoverd sets * this after recovery is finished.
*/
/* coming from UAPI header * * TODO: * Move this to UAPI header and let other values point to them and use BIT()
*/ #define DLM_SBF_DEMOTED_BIT 0 #define __DLM_SBF_MIN_BIT DLM_SBF_DEMOTED_BIT #define DLM_SBF_VALNOTVALID_BIT 1 #define DLM_SBF_ALTMODE_BIT 2 #define __DLM_SBF_MAX_BIT DLM_SBF_ALTMODE_BIT
staticinline uint32_t dlm_sbflags_val(conststruct dlm_lkb *lkb)
{ /* be sure the next person updates this */
BUILD_BUG_ON(BIT(__DLM_SBF_MAX_BIT) != DLM_SBF_ALTMODE);
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.