dlm_internal.h 19.8 KB
Newer Older
1 2 3 4
/******************************************************************************
*******************************************************************************
**
**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
D
David Teigland 已提交
5
**  Copyright (C) 2004-2011 Red Hat, Inc.  All rights reserved.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
**
**  This copyrighted material is made available to anyone wishing to use,
**  modify, copy, or redistribute it subject to the terms and conditions
**  of the GNU General Public License v.2.
**
*******************************************************************************
******************************************************************************/

#ifndef __DLM_INTERNAL_DOT_H__
#define __DLM_INTERNAL_DOT_H__

/*
 * This is the main header file to be included in each DLM source file.
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/ctype.h>
#include <linux/spinlock.h>
#include <linux/vmalloc.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/random.h>
#include <linux/delay.h>
#include <linux/socket.h>
#include <linux/kthread.h>
#include <linux/kobject.h>
#include <linux/kref.h>
#include <linux/kernel.h>
#include <linux/jhash.h>
D
David Teigland 已提交
38
#include <linux/miscdevice.h>
39
#include <linux/mutex.h>
D
David Teigland 已提交
40
#include <linux/idr.h>
D
David Teigland 已提交
41
#include <linux/ratelimit.h>
42 43 44
#include <asm/uaccess.h>

#include <linux/dlm.h>
45
#include "config.h"
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

/* Size of the temp buffer midcomms allocates on the stack.
   We try to make this large enough so most messages fit.
   FIXME: should sctp make this unnecessary? */

#define DLM_INBUF_LEN		148

struct dlm_ls;
struct dlm_lkb;
struct dlm_rsb;
struct dlm_member;
struct dlm_rsbtable;
struct dlm_recover;
struct dlm_header;
struct dlm_message;
struct dlm_rcom;
struct dlm_mhandle;

#define log_print(fmt, args...) \
	printk(KERN_ERR "dlm: "fmt"\n" , ##args)
#define log_error(ls, fmt, args...) \
	printk(KERN_ERR "dlm: %s: " fmt "\n", (ls)->ls_name , ##args)

69 70 71 72 73 74
#define log_debug(ls, fmt, args...) \
do { \
	if (dlm_config.ci_log_debug) \
		printk(KERN_DEBUG "dlm: %s: " fmt "\n", \
		       (ls)->ls_name , ##args); \
} while (0)
75

D
David Teigland 已提交
76 77 78 79 80 81 82
#define log_limit(ls, fmt, args...) \
do { \
	if (dlm_config.ci_log_debug) \
		printk_ratelimited(KERN_DEBUG "dlm: %s: " fmt "\n", \
			(ls)->ls_name , ##args); \
} while (0)

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
#define DLM_ASSERT(x, do) \
{ \
  if (!(x)) \
  { \
    printk(KERN_ERR "\nDLM:  Assertion failed on line %d of file %s\n" \
               "DLM:  assertion:  \"%s\"\n" \
               "DLM:  time = %lu\n", \
               __LINE__, __FILE__, #x, jiffies); \
    {do} \
    printk("\n"); \
    BUG(); \
    panic("DLM:  Record message above and reboot.\n"); \
  } \
}


struct dlm_rsbtable {
B
Bob Peterson 已提交
100 101
	struct rb_root		keep;
	struct rb_root		toss;
102
	spinlock_t		lock;
103 104 105 106 107 108 109 110 111 112 113
};


/*
 * Lockspace member (per node in a ls)
 */

struct dlm_member {
	struct list_head	list;
	int			nodeid;
	int			weight;
114 115
	int			slot;
	int			slot_prev;
D
David Teigland 已提交
116
	int			comm_seq;
117 118 119
	uint32_t		generation;
};

120 121 122 123 124 125
/*
 * Save and manage recovery state for a lockspace.
 */

struct dlm_recover {
	struct list_head	list;
D
David Teigland 已提交
126 127
	struct dlm_config_node	*nodes;
	int			nodes_count;
128 129 130 131 132 133 134 135 136
	uint64_t		seq;
};

/*
 * Pass input args to second stage locking function.
 */

struct dlm_args {
	uint32_t		flags;
137 138 139
	void			(*astfn) (void *astparam);
	void			*astparam;
	void			(*bastfn) (void *astparam, int mode);
140 141
	int			mode;
	struct dlm_lksb		*lksb;
142
	unsigned long		timeout;
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
};


/*
 * 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.
 */

/* lkb_status */

#define DLM_LKSTS_WAITING	1
#define DLM_LKSTS_GRANTED	2
#define DLM_LKSTS_CONVERT	3

/* lkb_flags */

#define DLM_IFL_MSTCPY		0x00010000
#define DLM_IFL_RESEND		0x00020000
D
David Teigland 已提交
196
#define DLM_IFL_DEAD		0x00040000
197 198 199
#define DLM_IFL_OVERLAP_UNLOCK  0x00080000
#define DLM_IFL_OVERLAP_CANCEL  0x00100000
#define DLM_IFL_ENDOFLIFE	0x00200000
200
#define DLM_IFL_WATCH_TIMEWARN	0x00400000
D
David Teigland 已提交
201
#define DLM_IFL_TIMEOUT_CANCEL	0x00800000
D
David Teigland 已提交
202
#define DLM_IFL_DEADLOCK_CANCEL	0x01000000
203
#define DLM_IFL_STUB_MS		0x02000000 /* magic number for m_flags */
D
David Teigland 已提交
204 205
#define DLM_IFL_USER		0x00000001
#define DLM_IFL_ORPHAN		0x00000002
206

D
David Teigland 已提交
207 208 209 210 211 212 213 214 215 216 217 218 219 220
#define DLM_CALLBACKS_SIZE	6

#define DLM_CB_CAST		0x00000001
#define DLM_CB_BAST		0x00000002
#define DLM_CB_SKIP		0x00000004

struct dlm_callback {
	uint64_t		seq;
	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 */
};

221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
struct dlm_lkb {
	struct dlm_rsb		*lkb_resource;	/* the rsb */
	struct kref		lkb_ref;
	int			lkb_nodeid;	/* copied from rsb */
	int			lkb_ownpid;	/* pid of lock owner */
	uint32_t		lkb_id;		/* our lock ID */
	uint32_t		lkb_remid;	/* lock ID on remote partner */
	uint32_t		lkb_exflags;	/* external flags from caller */
	uint32_t		lkb_sbflags;	/* lksb flags */
	uint32_t		lkb_flags;	/* internal flags */
	uint32_t		lkb_lvbseq;	/* lvb sequence number */

	int8_t			lkb_status;     /* granted, waiting, convert */
	int8_t			lkb_rqmode;	/* requested lock mode */
	int8_t			lkb_grmode;	/* granted lock mode */
	int8_t			lkb_highbast;	/* highest mode bast sent for */
237

238
	int8_t			lkb_wait_type;	/* type of reply waiting for */
239
	int8_t			lkb_wait_count;
240
	int			lkb_wait_nodeid; /* for debugging */
241 242 243 244

	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 */
D
David Teigland 已提交
245
	struct list_head	lkb_ownqueue;	/* list of locks for a process */
246
	struct list_head	lkb_time_list;
D
David Teigland 已提交
247
	ktime_t			lkb_timestamp;
248
	ktime_t			lkb_wait_time;
249
	unsigned long		lkb_timeout_cs;
250

251 252 253
	struct mutex		lkb_cb_mutex;
	struct work_struct	lkb_cb_work;
	struct list_head	lkb_cb_list; /* for ls_cb_delay or proc->asts */
D
David Teigland 已提交
254 255 256 257 258 259
	struct dlm_callback	lkb_callbacks[DLM_CALLBACKS_SIZE];
	struct dlm_callback	lkb_last_cast;
	struct dlm_callback	lkb_last_bast;
	ktime_t			lkb_last_cast_time;	/* for debugging */
	ktime_t			lkb_last_bast_time;	/* for debugging */

D
David Teigland 已提交
260 261
	uint64_t		lkb_recover_seq; /* from ls_recover_seq */

262 263
	char			*lkb_lvbptr;
	struct dlm_lksb		*lkb_lksb;      /* caller's status block */
264 265
	void			(*lkb_astfn) (void *astparam);
	void			(*lkb_bastfn) (void *astparam, int mode);
266 267 268 269
	union {
		void			*lkb_astparam;	/* caller's ast arg */
		struct dlm_user_args	*lkb_ua;
	};
270 271
};

272 273 274 275 276 277 278 279 280
/*
 * 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)
 */
281 282 283 284

struct dlm_rsb {
	struct dlm_ls		*res_ls;	/* the lockspace */
	struct kref		res_ref;
285
	struct mutex		res_mutex;
286 287 288
	unsigned long		res_flags;
	int			res_length;	/* length of rsb name */
	int			res_nodeid;
289 290
	int			res_master_nodeid;
	int			res_dir_nodeid;
291
	int			res_id;		/* for ls_recover_idr */
292 293 294 295 296 297
	uint32_t                res_lvbseq;
	uint32_t		res_hash;
	uint32_t		res_bucket;	/* rsbtbl */
	unsigned long		res_toss_time;
	uint32_t		res_first_lkid;
	struct list_head	res_lookup;	/* lkbs waiting on first */
B
Bob Peterson 已提交
298 299 300 301
	union {
		struct list_head	res_hashchain;
		struct rb_node		res_hashnode;	/* rsbtbl */
	};
302 303 304 305 306 307 308 309 310
	struct list_head	res_grantqueue;
	struct list_head	res_convertqueue;
	struct list_head	res_waitqueue;

	struct list_head	res_root_list;	    /* used for recovery */
	struct list_head	res_recover_list;   /* used for recovery */
	int			res_recover_locks_count;

	char			*res_lvbptr;
D
David Teigland 已提交
311
	char			res_name[DLM_RESNAME_MAXLEN+1];
312 313
};

314 315 316 317 318 319 320 321 322 323
/* dlm_master_lookup() flags */

#define DLM_LU_RECOVER_DIR	1
#define DLM_LU_RECOVER_MASTER	2

/* dlm_master_lookup() results */

#define DLM_LU_MATCH		1
#define DLM_LU_ADD		2

324 325
/* find_rsb() flags */

326 327 328
#define R_REQUEST		0x00000001
#define R_RECEIVE_REQUEST	0x00000002
#define R_RECEIVE_RECOVER	0x00000004
329 330 331 332 333 334 335 336 337 338

/* rsb_flags */

enum rsb_flags {
	RSB_MASTER_UNCERTAIN,
	RSB_VALNOTVALID,
	RSB_VALNOTVALID_PREV,
	RSB_NEW_MASTER,
	RSB_NEW_MASTER2,
	RSB_RECOVER_CONVERT,
D
David Teigland 已提交
339
	RSB_RECOVER_GRANT,
340
	RSB_RECOVER_LVB_INVAL,
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
};

static inline void rsb_set_flag(struct dlm_rsb *r, enum rsb_flags flag)
{
	__set_bit(flag, &r->res_flags);
}

static inline void rsb_clear_flag(struct dlm_rsb *r, enum rsb_flags flag)
{
	__clear_bit(flag, &r->res_flags);
}

static inline int rsb_flag(struct dlm_rsb *r, enum rsb_flags flag)
{
	return test_bit(flag, &r->res_flags);
}


/* dlm_header is first element of all structs sent between nodes */

D
David Teigland 已提交
361
#define DLM_HEADER_MAJOR	0x00030000
362 363 364
#define DLM_HEADER_MINOR	0x00000001

#define DLM_HEADER_SLOTS	0x00000001
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391

#define DLM_MSG			1
#define DLM_RCOM		2

struct dlm_header {
	uint32_t		h_version;
	uint32_t		h_lockspace;
	uint32_t		h_nodeid;	/* nodeid of sender */
	uint16_t		h_length;
	uint8_t			h_cmd;		/* DLM_MSG, DLM_RCOM */
	uint8_t			h_pad;
};


#define DLM_MSG_REQUEST		1
#define DLM_MSG_CONVERT		2
#define DLM_MSG_UNLOCK		3
#define DLM_MSG_CANCEL		4
#define DLM_MSG_REQUEST_REPLY	5
#define DLM_MSG_CONVERT_REPLY	6
#define DLM_MSG_UNLOCK_REPLY	7
#define DLM_MSG_CANCEL_REPLY	8
#define DLM_MSG_GRANT		9
#define DLM_MSG_BAST		10
#define DLM_MSG_LOOKUP		11
#define DLM_MSG_REMOVE		12
#define DLM_MSG_LOOKUP_REPLY	13
392
#define DLM_MSG_PURGE		14
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440

struct dlm_message {
	struct dlm_header	m_header;
	uint32_t		m_type;		/* DLM_MSG_ */
	uint32_t		m_nodeid;
	uint32_t		m_pid;
	uint32_t		m_lkid;		/* lkid on sender */
	uint32_t		m_remid;	/* lkid on receiver */
	uint32_t		m_parent_lkid;
	uint32_t		m_parent_remid;
	uint32_t		m_exflags;
	uint32_t		m_sbflags;
	uint32_t		m_flags;
	uint32_t		m_lvbseq;
	uint32_t		m_hash;
	int			m_status;
	int			m_grmode;
	int			m_rqmode;
	int			m_bastmode;
	int			m_asts;
	int			m_result;	/* 0 or -EXXX */
	char			m_extra[0];	/* name or lvb */
};


#define DLM_RS_NODES		0x00000001
#define DLM_RS_NODES_ALL	0x00000002
#define DLM_RS_DIR		0x00000004
#define DLM_RS_DIR_ALL		0x00000008
#define DLM_RS_LOCKS		0x00000010
#define DLM_RS_LOCKS_ALL	0x00000020
#define DLM_RS_DONE		0x00000040
#define DLM_RS_DONE_ALL		0x00000080

#define DLM_RCOM_STATUS		1
#define DLM_RCOM_NAMES		2
#define DLM_RCOM_LOOKUP		3
#define DLM_RCOM_LOCK		4
#define DLM_RCOM_STATUS_REPLY	5
#define DLM_RCOM_NAMES_REPLY	6
#define DLM_RCOM_LOOKUP_REPLY	7
#define DLM_RCOM_LOCK_REPLY	8

struct dlm_rcom {
	struct dlm_header	rc_header;
	uint32_t		rc_type;	/* DLM_RCOM_ */
	int			rc_result;	/* multi-purpose */
	uint64_t		rc_id;		/* match reply with request */
D
David Teigland 已提交
441 442
	uint64_t		rc_seq;		/* sender's ls_recover_seq */
	uint64_t		rc_seq_reply;	/* remote ls_recover_seq */
443 444 445
	char			rc_buf[0];
};

446 447 448 449 450 451
union dlm_packet {
	struct dlm_header	header;		/* common to other two */
	struct dlm_message	message;
	struct dlm_rcom		rcom;
};

452 453 454 455 456 457 458 459 460 461
#define DLM_RSF_NEED_SLOTS	0x00000001

/* RCOM_STATUS data */
struct rcom_status {
	__le32			rs_flags;
	__le32			rs_unused1;
	__le64			rs_unused2;
};

/* RCOM_STATUS_REPLY data */
462
struct rcom_config {
A
Al Viro 已提交
463 464
	__le32			rf_lvblen;
	__le32			rf_lsflags;
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479

	/* DLM_HEADER_SLOTS adds: */
	__le32			rf_flags;
	__le16			rf_our_slot;
	__le16			rf_num_slots;
	__le32			rf_generation;
	__le32			rf_unused1;
	__le64			rf_unused2;
};

struct rcom_slot {
	__le32			ro_nodeid;
	__le16			ro_slot;
	__le16			ro_unused1;
	__le64			ro_unused2;
480 481 482
};

struct rcom_lock {
A
Al Viro 已提交
483 484 485 486 487 488 489 490 491
	__le32			rl_ownpid;
	__le32			rl_lkid;
	__le32			rl_remid;
	__le32			rl_parent_lkid;
	__le32			rl_parent_remid;
	__le32			rl_exflags;
	__le32			rl_flags;
	__le32			rl_lvbseq;
	__le32			rl_result;
492 493 494 495
	int8_t			rl_rqmode;
	int8_t			rl_grmode;
	int8_t			rl_status;
	int8_t			rl_asts;
A
Al Viro 已提交
496 497
	__le16			rl_wait_type;
	__le16			rl_namelen;
498 499 500 501
	char			rl_name[DLM_RESNAME_MAXLEN];
	char			rl_lvb[0];
};

502 503 504 505 506 507 508
/*
 * The max number of resources per rsbtbl bucket that shrink will attempt
 * to remove in each iteration.
 */

#define DLM_REMOVE_NAMES_MAX 8

509 510
struct dlm_ls {
	struct list_head	ls_list;	/* list of lockspaces */
D
David Teigland 已提交
511
	dlm_lockspace_t		*ls_local_handle;
512
	uint32_t		ls_global_id;	/* global unique lockspace ID */
513
	uint32_t		ls_generation;
514 515
	uint32_t		ls_exflags;
	int			ls_lvblen;
516 517 518
	int			ls_count;	/* refcount of processes in
						   the dlm using this ls */
	int			ls_create_count; /* create/release refcount */
519
	unsigned long		ls_flags;	/* LSFL_ */
520
	unsigned long		ls_scan_time;
521 522
	struct kobject		ls_kobj;

D
David Teigland 已提交
523 524 525
	struct idr		ls_lkbidr;
	spinlock_t		ls_lkbidr_spin;

526 527 528
	struct dlm_rsbtable	*ls_rsbtbl;
	uint32_t		ls_rsbtbl_size;

529
	struct mutex		ls_waiters_mutex;
530 531
	struct list_head	ls_waiters;	/* lkbs needing a reply */

532 533 534
	struct mutex		ls_orphans_mutex;
	struct list_head	ls_orphans;

535 536 537
	struct mutex		ls_timeout_mutex;
	struct list_head	ls_timeout;

D
David Teigland 已提交
538 539 540 541
	spinlock_t		ls_new_rsb_spin;
	int			ls_new_rsb_count;
	struct list_head	ls_new_rsb;	/* new rsb structs */

542 543 544 545 546 547
	spinlock_t		ls_remove_spin;
	char			ls_remove_name[DLM_RESNAME_MAXLEN+1];
	char			*ls_remove_names[DLM_REMOVE_NAMES_MAX];
	int			ls_remove_len;
	int			ls_remove_lens[DLM_REMOVE_NAMES_MAX];

548 549 550 551 552 553 554
	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;

555 556 557 558 559
	int			ls_slot;
	int			ls_num_slots;
	int			ls_slots_size;
	struct dlm_slot		*ls_slots;

560 561 562 563
	struct dlm_rsb		ls_stub_rsb;	/* for returning errors */
	struct dlm_lkb		ls_stub_lkb;	/* for returning errors */
	struct dlm_message	ls_stub_ms;	/* for faking a reply */

D
David Teigland 已提交
564 565
	struct dentry		*ls_debug_rsb_dentry; /* debugfs */
	struct dentry		*ls_debug_waiters_dentry; /* debugfs */
D
David Teigland 已提交
566
	struct dentry		*ls_debug_locks_dentry; /* debugfs */
D
David Teigland 已提交
567
	struct dentry		*ls_debug_all_dentry; /* debugfs */
568
	struct dentry		*ls_debug_toss_dentry; /* debugfs */
569 570 571

	wait_queue_head_t	ls_uevent_wait;	/* user part of join/leave */
	int			ls_uevent_result;
572 573
	struct completion	ls_members_done;
	int			ls_members_result;
574

D
David Teigland 已提交
575 576
	struct miscdevice       ls_device;

577 578
	struct workqueue_struct	*ls_callback_wq;

579 580
	/* recovery related */

581 582
	struct mutex		ls_cb_mutex;
	struct list_head	ls_cb_delay; /* save for queue_work later */
583 584
	struct timer_list	ls_timer;
	struct task_struct	*ls_recoverd_task;
585
	struct mutex		ls_recoverd_active;
586
	spinlock_t		ls_recover_lock;
587
	unsigned long		ls_recover_begin; /* jiffies timestamp */
588 589 590 591
	uint32_t		ls_recover_status; /* DLM_RS_ */
	uint64_t		ls_recover_seq;
	struct dlm_recover	*ls_recover_args;
	struct rw_semaphore	ls_in_recovery;	/* block local requests */
592
	struct rw_semaphore	ls_recv_active;	/* block dlm_recv */
593
	struct list_head	ls_requestqueue;/* queue remote requests */
594
	struct mutex		ls_requestqueue_mutex;
595
	struct dlm_rcom		*ls_recover_buf;
596
	int			ls_recover_nodeid; /* for debugging */
597 598
	unsigned int		ls_recover_dir_sent_res; /* for log info */
	unsigned int		ls_recover_dir_sent_msg; /* for log info */
D
David Teigland 已提交
599
	unsigned int		ls_recover_locks_in; /* for log info */
600
	uint64_t		ls_rcom_seq;
601
	spinlock_t		ls_rcom_spin;
602 603 604
	struct list_head	ls_recover_list;
	spinlock_t		ls_recover_list_lock;
	int			ls_recover_list_count;
605 606
	struct idr		ls_recover_idr;
	spinlock_t		ls_recover_idr_lock;
607
	wait_queue_head_t	ls_wait_general;
608
	wait_queue_head_t	ls_recover_lock_wait;
D
David Teigland 已提交
609
	struct mutex		ls_clear_proc_locks;
610 611 612 613

	struct list_head	ls_root_list;	/* root resources */
	struct rw_semaphore	ls_root_sem;	/* protect root_list */

D
David Teigland 已提交
614 615 616
	const struct dlm_lockspace_ops *ls_ops;
	void			*ls_ops_arg;

617 618 619 620
	int			ls_namelen;
	char			ls_name[1];
};

621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
/*
 * 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.
 */

#define LSFL_RECOVER_STOP	0
#define LSFL_RECOVER_DOWN	1
#define LSFL_RECOVER_LOCK	2
#define LSFL_RECOVER_WORK	3
#define LSFL_RUNNING		4

#define LSFL_RCOM_READY		5
#define LSFL_RCOM_WAIT		6
#define LSFL_UEVENT_WAIT	7
#define LSFL_TIMEWARN		8
#define LSFL_CB_DELAY		9
#define LSFL_NODIR		10
655

D
David Teigland 已提交
656 657 658 659 660 661 662 663 664 665 666 667 668 669
/* 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;
670
	uint64_t		xid;
D
David Teigland 已提交
671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
};

#define DLM_PROC_FLAGS_CLOSING 1
#define DLM_PROC_FLAGS_COMPAT  2

/* locks list is kept so we can remove all a process's locks when it
   exits (or orphan those that are persistent) */

struct dlm_user_proc {
	dlm_lockspace_t		*lockspace;
	unsigned long		flags; /* DLM_PROC_FLAGS */
	struct list_head	asts;
	spinlock_t		asts_spin;
	struct list_head	locks;
	spinlock_t		locks_spin;
D
David Teigland 已提交
686
	struct list_head	unlocking;
D
David Teigland 已提交
687 688 689
	wait_queue_head_t	wait;
};

690 691 692 693 694 695 696
static inline int dlm_locking_stopped(struct dlm_ls *ls)
{
	return !test_bit(LSFL_RUNNING, &ls->ls_flags);
}

static inline int dlm_recovery_stopped(struct dlm_ls *ls)
{
697
	return test_bit(LSFL_RECOVER_STOP, &ls->ls_flags);
698 699 700 701
}

static inline int dlm_no_directory(struct dlm_ls *ls)
{
D
David Teigland 已提交
702
	return test_bit(LSFL_NODIR, &ls->ls_flags);
703 704
}

A
Adrian Bunk 已提交
705 706 707
int dlm_netlink_init(void);
void dlm_netlink_exit(void);
void dlm_timeout_warn(struct dlm_lkb *lkb);
D
David Teigland 已提交
708 709
int dlm_plock_init(void);
void dlm_plock_exit(void);
A
Adrian Bunk 已提交
710 711 712 713 714 715 716 717 718 719 720 721 722

#ifdef CONFIG_DLM_DEBUG
int dlm_register_debugfs(void);
void dlm_unregister_debugfs(void);
int dlm_create_debug_file(struct dlm_ls *ls);
void dlm_delete_debug_file(struct dlm_ls *ls);
#else
static inline int dlm_register_debugfs(void) { return 0; }
static inline void dlm_unregister_debugfs(void) { }
static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
#endif

723 724
#endif				/* __DLM_INTERNAL_DOT_H__ */