1/*
2 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3 * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
4 *
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
7 * of the GNU General Public License version 2.
8 */
9
10#ifndef LOCK_DLM_DOT_H
11#define LOCK_DLM_DOT_H
12
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/spinlock.h>
16#include <linux/module.h>
17#include <linux/types.h>
18#include <linux/string.h>
19#include <linux/list.h>
20#include <linux/socket.h>
21#include <linux/delay.h>
22#include <linux/kthread.h>
23#include <linux/kobject.h>
24#include <linux/fcntl.h>
25#include <linux/wait.h>
26#include <net/sock.h>
27
28#include <linux/dlm.h>
29#include <linux/lm_interface.h>
30
31/*
32 * Internally, we prefix things with gdlm_ and GDLM_ (for gfs-dlm) since a
33 * prefix of lock_dlm_ gets awkward.  Externally, GFS refers to this module
34 * as "lock_dlm".
35 */
36
37#define GDLM_STRNAME_BYTES	24
38#define GDLM_LVB_SIZE		32
39#define GDLM_DROP_COUNT		0
40#define GDLM_DROP_PERIOD	60
41#define GDLM_NAME_LEN		128
42
43/* GFS uses 12 bytes to identify a resource (32 bit type + 64 bit number).
44   We sprintf these numbers into a 24 byte string of hex values to make them
45   human-readable (to make debugging simpler.) */
46
47struct gdlm_strname {
48	unsigned char		name[GDLM_STRNAME_BYTES];
49	unsigned short		namelen;
50};
51
52enum {
53	DFL_BLOCK_LOCKS		= 0,
54	DFL_SPECTATOR		= 1,
55	DFL_WITHDRAW		= 2,
56};
57
58struct gdlm_ls {
59	u32		id;
60	int			jid;
61	int			first;
62	int			first_done;
63	unsigned long		flags;
64	struct kobject		kobj;
65	char			clustername[GDLM_NAME_LEN];
66	char			fsname[GDLM_NAME_LEN];
67	int			fsflags;
68	dlm_lockspace_t		*dlm_lockspace;
69	lm_callback_t		fscb;
70	struct gfs2_sbd		*sdp;
71	int			recover_jid;
72	int			recover_jid_done;
73	int			recover_jid_status;
74	spinlock_t		async_lock;
75	struct list_head	complete;
76	struct list_head	blocking;
77	struct list_head	delayed;
78	struct list_head	submit;
79	struct list_head	all_locks;
80	u32		all_locks_count;
81	wait_queue_head_t	wait_control;
82	struct task_struct	*thread1;
83	struct task_struct	*thread2;
84	wait_queue_head_t	thread_wait;
85	unsigned long		drop_time;
86	int			drop_locks_count;
87	int			drop_locks_period;
88};
89
90enum {
91	LFL_NOBLOCK		= 0,
92	LFL_NOCACHE		= 1,
93	LFL_DLM_UNLOCK		= 2,
94	LFL_DLM_CANCEL		= 3,
95	LFL_SYNC_LVB		= 4,
96	LFL_FORCE_PROMOTE	= 5,
97	LFL_REREQUEST		= 6,
98	LFL_ACTIVE		= 7,
99	LFL_INLOCK		= 8,
100	LFL_CANCEL		= 9,
101	LFL_NOBAST		= 10,
102	LFL_HEADQUE		= 11,
103	LFL_UNLOCK_DELETE	= 12,
104};
105
106struct gdlm_lock {
107	struct gdlm_ls		*ls;
108	struct lm_lockname	lockname;
109	struct gdlm_strname	strname;
110	char			*lvb;
111	struct dlm_lksb		lksb;
112
113	s16			cur;
114	s16			req;
115	s16			prev_req;
116	u32			lkf;		/* dlm flags DLM_LKF_ */
117	unsigned long		flags;		/* lock_dlm flags LFL_ */
118
119	int			bast_mode;	/* protected by async_lock */
120	struct completion	ast_wait;
121
122	struct list_head	clist;		/* complete */
123	struct list_head	blist;		/* blocking */
124	struct list_head	delay_list;	/* delayed */
125	struct list_head	all_list;	/* all locks for the fs */
126	struct gdlm_lock	*hold_null;	/* NL lock for hold_lvb */
127};
128
129#define gdlm_assert(assertion, fmt, args...)                                  \
130do {                                                                          \
131	if (unlikely(!(assertion))) {                                         \
132		printk(KERN_EMERG "lock_dlm: fatal assertion failed \"%s\"\n" \
133				  "lock_dlm:  " fmt "\n",                     \
134				  #assertion, ##args);                        \
135		BUG();                                                        \
136	}                                                                     \
137} while (0)
138
139#define log_print(lev, fmt, arg...) printk(lev "lock_dlm: " fmt "\n" , ## arg)
140#define log_info(fmt, arg...)  log_print(KERN_INFO , fmt , ## arg)
141#define log_error(fmt, arg...) log_print(KERN_ERR , fmt , ## arg)
142#ifdef LOCK_DLM_LOG_DEBUG
143#define log_debug(fmt, arg...) log_print(KERN_DEBUG , fmt , ## arg)
144#else
145#define log_debug(fmt, arg...)
146#endif
147
148/* sysfs.c */
149
150int gdlm_sysfs_init(void);
151void gdlm_sysfs_exit(void);
152int gdlm_kobject_setup(struct gdlm_ls *, struct kobject *);
153void gdlm_kobject_release(struct gdlm_ls *);
154
155/* thread.c */
156
157int gdlm_init_threads(struct gdlm_ls *);
158void gdlm_release_threads(struct gdlm_ls *);
159
160/* lock.c */
161
162s16 gdlm_make_lmstate(s16);
163void gdlm_queue_delayed(struct gdlm_lock *);
164void gdlm_submit_delayed(struct gdlm_ls *);
165int gdlm_release_all_locks(struct gdlm_ls *);
166void gdlm_delete_lp(struct gdlm_lock *);
167unsigned int gdlm_do_lock(struct gdlm_lock *);
168
169int gdlm_get_lock(void *, struct lm_lockname *, void **);
170void gdlm_put_lock(void *);
171unsigned int gdlm_lock(void *, unsigned int, unsigned int, unsigned int);
172unsigned int gdlm_unlock(void *, unsigned int);
173void gdlm_cancel(void *);
174int gdlm_hold_lvb(void *, char **);
175void gdlm_unhold_lvb(void *, char *);
176
177/* plock.c */
178
179int gdlm_plock_init(void);
180void gdlm_plock_exit(void);
181int gdlm_plock(void *, struct lm_lockname *, struct file *, int,
182		struct file_lock *);
183int gdlm_plock_get(void *, struct lm_lockname *, struct file *,
184		struct file_lock *);
185int gdlm_punlock(void *, struct lm_lockname *, struct file *,
186		struct file_lock *);
187#endif
188