1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifndef __DLM_INTERNAL_DOT_H__
15#define __DLM_INTERNAL_DOT_H__
16
17
18
19
20
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <linux/sched.h>
24#include <linux/types.h>
25#include <linux/ctype.h>
26#include <linux/spinlock.h>
27#include <linux/vmalloc.h>
28#include <linux/list.h>
29#include <linux/errno.h>
30#include <linux/random.h>
31#include <linux/delay.h>
32#include <linux/socket.h>
33#include <linux/kthread.h>
34#include <linux/kobject.h>
35#include <linux/kref.h>
36#include <linux/kernel.h>
37#include <linux/jhash.h>
38#include <linux/miscdevice.h>
39#include <linux/mutex.h>
40#include <asm/uaccess.h>
41
42#include <linux/dlm.h>
43#include "config.h"
44
45
46
47
48
49#define DLM_INBUF_LEN 148
50
51struct dlm_ls;
52struct dlm_lkb;
53struct dlm_rsb;
54struct dlm_member;
55struct dlm_lkbtable;
56struct dlm_rsbtable;
57struct dlm_dirtable;
58struct dlm_direntry;
59struct dlm_recover;
60struct dlm_header;
61struct dlm_message;
62struct dlm_rcom;
63struct dlm_mhandle;
64
65#define log_print(fmt, args...) \
66 printk(KERN_ERR "dlm: "fmt"\n" , ##args)
67#define log_error(ls, fmt, args...) \
68 printk(KERN_ERR "dlm: %s: " fmt "\n", (ls)->ls_name , ##args)
69
70#define log_debug(ls, fmt, args...) \
71do { \
72 if (dlm_config.ci_log_debug) \
73 printk(KERN_DEBUG "dlm: %s: " fmt "\n", \
74 (ls)->ls_name , ##args); \
75} while (0)
76
77#define DLM_ASSERT(x, do) \
78{ \
79 if (!(x)) \
80 { \
81 printk(KERN_ERR "\nDLM: Assertion failed on line %d of file %s\n" \
82 "DLM: assertion: \"%s\"\n" \
83 "DLM: time = %lu\n", \
84 __LINE__, __FILE__, #x, jiffies); \
85 {do} \
86 printk("\n"); \
87 BUG(); \
88 panic("DLM: Record message above and reboot.\n"); \
89 } \
90}
91
92
93struct dlm_direntry {
94 struct list_head list;
95 uint32_t master_nodeid;
96 uint16_t length;
97 char name[1];
98};
99
100struct dlm_dirtable {
101 struct list_head list;
102 spinlock_t lock;
103};
104
105struct dlm_rsbtable {
106 struct list_head list;
107 struct list_head toss;
108 spinlock_t lock;
109};
110
111struct dlm_lkbtable {
112 struct list_head list;
113 rwlock_t lock;
114 uint16_t counter;
115};
116
117
118
119
120
121struct dlm_member {
122 struct list_head list;
123 int nodeid;
124 int weight;
125};
126
127
128
129
130
131struct dlm_recover {
132 struct list_head list;
133 int *nodeids;
134 int node_count;
135 int *new;
136 int new_count;
137 uint64_t seq;
138};
139
140
141
142
143
144struct dlm_args {
145 uint32_t flags;
146 void (*astfn) (void *astparam);
147 void *astparam;
148 void (*bastfn) (void *astparam, int mode);
149 int mode;
150 struct dlm_lksb *lksb;
151 unsigned long timeout;
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
196
197#define AST_COMP 1
198#define AST_BAST 2
199
200
201
202#define DLM_LKSTS_WAITING 1
203#define DLM_LKSTS_GRANTED 2
204#define DLM_LKSTS_CONVERT 3
205
206
207
208#define DLM_IFL_MSTCPY 0x00010000
209#define DLM_IFL_RESEND 0x00020000
210#define DLM_IFL_DEAD 0x00040000
211#define DLM_IFL_OVERLAP_UNLOCK 0x00080000
212#define DLM_IFL_OVERLAP_CANCEL 0x00100000
213#define DLM_IFL_ENDOFLIFE 0x00200000
214#define DLM_IFL_WATCH_TIMEWARN 0x00400000
215#define DLM_IFL_TIMEOUT_CANCEL 0x00800000
216#define DLM_IFL_DEADLOCK_CANCEL 0x01000000
217#define DLM_IFL_USER 0x00000001
218#define DLM_IFL_ORPHAN 0x00000002
219
220struct dlm_lkb {
221 struct dlm_rsb *lkb_resource;
222 struct kref lkb_ref;
223 int lkb_nodeid;
224 int lkb_ownpid;
225 uint32_t lkb_id;
226 uint32_t lkb_remid;
227 uint32_t lkb_exflags;
228 uint32_t lkb_sbflags;
229 uint32_t lkb_flags;
230 uint32_t lkb_lvbseq;
231
232 int8_t lkb_status;
233 int8_t lkb_rqmode;
234 int8_t lkb_grmode;
235 int8_t lkb_bastmode;
236 int8_t lkb_highbast;
237 int8_t lkb_wait_type;
238 int8_t lkb_wait_count;
239 int8_t lkb_ast_type;
240
241 struct list_head lkb_idtbl_list;
242 struct list_head lkb_statequeue;
243 struct list_head lkb_rsb_lookup;
244 struct list_head lkb_wait_reply;
245 struct list_head lkb_astqueue;
246 struct list_head lkb_ownqueue;
247 struct list_head lkb_time_list;
248 ktime_t lkb_time_bast;
249 ktime_t lkb_timestamp;
250 unsigned long lkb_timeout_cs;
251
252 char *lkb_lvbptr;
253 struct dlm_lksb *lkb_lksb;
254 void (*lkb_astfn) (void *astparam);
255 void (*lkb_bastfn) (void *astparam, int mode);
256 union {
257 void *lkb_astparam;
258 struct dlm_user_args *lkb_ua;
259 };
260};
261
262
263struct dlm_rsb {
264 struct dlm_ls *res_ls;
265 struct kref res_ref;
266 struct mutex res_mutex;
267 unsigned long res_flags;
268 int res_length;
269 int res_nodeid;
270 uint32_t res_lvbseq;
271 uint32_t res_hash;
272 uint32_t res_bucket;
273 unsigned long res_toss_time;
274 uint32_t res_first_lkid;
275 struct list_head res_lookup;
276 struct list_head res_hashchain;
277 struct list_head res_grantqueue;
278 struct list_head res_convertqueue;
279 struct list_head res_waitqueue;
280
281 struct list_head res_root_list;
282 struct list_head res_recover_list;
283 int res_recover_locks_count;
284
285 char *res_lvbptr;
286 char res_name[1];
287};
288
289
290
291#define R_MASTER 1
292#define R_CREATE 2
293
294
295
296enum rsb_flags {
297 RSB_MASTER_UNCERTAIN,
298 RSB_VALNOTVALID,
299 RSB_VALNOTVALID_PREV,
300 RSB_NEW_MASTER,
301 RSB_NEW_MASTER2,
302 RSB_RECOVER_CONVERT,
303 RSB_LOCKS_PURGED,
304};
305
306static inline void rsb_set_flag(struct dlm_rsb *r, enum rsb_flags flag)
307{
308 __set_bit(flag, &r->res_flags);
309}
310
311static inline void rsb_clear_flag(struct dlm_rsb *r, enum rsb_flags flag)
312{
313 __clear_bit(flag, &r->res_flags);
314}
315
316static inline int rsb_flag(struct dlm_rsb *r, enum rsb_flags flag)
317{
318 return test_bit(flag, &r->res_flags);
319}
320
321
322
323
324#define DLM_HEADER_MAJOR 0x00030000
325#define DLM_HEADER_MINOR 0x00000000
326
327#define DLM_MSG 1
328#define DLM_RCOM 2
329
330struct dlm_header {
331 uint32_t h_version;
332 uint32_t h_lockspace;
333 uint32_t h_nodeid;
334 uint16_t h_length;
335 uint8_t h_cmd;
336 uint8_t h_pad;
337};
338
339
340#define DLM_MSG_REQUEST 1
341#define DLM_MSG_CONVERT 2
342#define DLM_MSG_UNLOCK 3
343#define DLM_MSG_CANCEL 4
344#define DLM_MSG_REQUEST_REPLY 5
345#define DLM_MSG_CONVERT_REPLY 6
346#define DLM_MSG_UNLOCK_REPLY 7
347#define DLM_MSG_CANCEL_REPLY 8
348#define DLM_MSG_GRANT 9
349#define DLM_MSG_BAST 10
350#define DLM_MSG_LOOKUP 11
351#define DLM_MSG_REMOVE 12
352#define DLM_MSG_LOOKUP_REPLY 13
353#define DLM_MSG_PURGE 14
354
355struct dlm_message {
356 struct dlm_header m_header;
357 uint32_t m_type;
358 uint32_t m_nodeid;
359 uint32_t m_pid;
360 uint32_t m_lkid;
361 uint32_t m_remid;
362 uint32_t m_parent_lkid;
363 uint32_t m_parent_remid;
364 uint32_t m_exflags;
365 uint32_t m_sbflags;
366 uint32_t m_flags;
367 uint32_t m_lvbseq;
368 uint32_t m_hash;
369 int m_status;
370 int m_grmode;
371 int m_rqmode;
372 int m_bastmode;
373 int m_asts;
374 int m_result;
375 char m_extra[0];
376};
377
378
379#define DLM_RS_NODES 0x00000001
380#define DLM_RS_NODES_ALL 0x00000002
381#define DLM_RS_DIR 0x00000004
382#define DLM_RS_DIR_ALL 0x00000008
383#define DLM_RS_LOCKS 0x00000010
384#define DLM_RS_LOCKS_ALL 0x00000020
385#define DLM_RS_DONE 0x00000040
386#define DLM_RS_DONE_ALL 0x00000080
387
388#define DLM_RCOM_STATUS 1
389#define DLM_RCOM_NAMES 2
390#define DLM_RCOM_LOOKUP 3
391#define DLM_RCOM_LOCK 4
392#define DLM_RCOM_STATUS_REPLY 5
393#define DLM_RCOM_NAMES_REPLY 6
394#define DLM_RCOM_LOOKUP_REPLY 7
395#define DLM_RCOM_LOCK_REPLY 8
396
397struct dlm_rcom {
398 struct dlm_header rc_header;
399 uint32_t rc_type;
400 int rc_result;
401 uint64_t rc_id;
402 uint64_t rc_seq;
403 uint64_t rc_seq_reply;
404 char rc_buf[0];
405};
406
407union dlm_packet {
408 struct dlm_header header;
409 struct dlm_message message;
410 struct dlm_rcom rcom;
411};
412
413struct rcom_config {
414 __le32 rf_lvblen;
415 __le32 rf_lsflags;
416 __le64 rf_unused;
417};
418
419struct rcom_lock {
420 __le32 rl_ownpid;
421 __le32 rl_lkid;
422 __le32 rl_remid;
423 __le32 rl_parent_lkid;
424 __le32 rl_parent_remid;
425 __le32 rl_exflags;
426 __le32 rl_flags;
427 __le32 rl_lvbseq;
428 __le32 rl_result;
429 int8_t rl_rqmode;
430 int8_t rl_grmode;
431 int8_t rl_status;
432 int8_t rl_asts;
433 __le16 rl_wait_type;
434 __le16 rl_namelen;
435 char rl_name[DLM_RESNAME_MAXLEN];
436 char rl_lvb[0];
437};
438
439struct dlm_ls {
440 struct list_head ls_list;
441 dlm_lockspace_t *ls_local_handle;
442 uint32_t ls_global_id;
443 uint32_t ls_exflags;
444 int ls_lvblen;
445 int ls_count;
446
447 int ls_create_count;
448 unsigned long ls_flags;
449 unsigned long ls_scan_time;
450 struct kobject ls_kobj;
451
452 struct dlm_rsbtable *ls_rsbtbl;
453 uint32_t ls_rsbtbl_size;
454
455 struct dlm_lkbtable *ls_lkbtbl;
456 uint32_t ls_lkbtbl_size;
457
458 struct dlm_dirtable *ls_dirtbl;
459 uint32_t ls_dirtbl_size;
460
461 struct mutex ls_waiters_mutex;
462 struct list_head ls_waiters;
463
464 struct mutex ls_orphans_mutex;
465 struct list_head ls_orphans;
466
467 struct mutex ls_timeout_mutex;
468 struct list_head ls_timeout;
469
470 struct list_head ls_nodes;
471 struct list_head ls_nodes_gone;
472 int ls_num_nodes;
473 int ls_low_nodeid;
474 int ls_total_weight;
475 int *ls_node_array;
476
477 struct dlm_rsb ls_stub_rsb;
478 struct dlm_lkb ls_stub_lkb;
479 struct dlm_message ls_stub_ms;
480
481 struct dentry *ls_debug_rsb_dentry;
482 struct dentry *ls_debug_waiters_dentry;
483 struct dentry *ls_debug_locks_dentry;
484 struct dentry *ls_debug_all_dentry;
485
486 wait_queue_head_t ls_uevent_wait;
487 int ls_uevent_result;
488 struct completion ls_members_done;
489 int ls_members_result;
490
491 struct miscdevice ls_device;
492
493
494
495 struct timer_list ls_timer;
496 struct task_struct *ls_recoverd_task;
497 struct mutex ls_recoverd_active;
498 spinlock_t ls_recover_lock;
499 unsigned long ls_recover_begin;
500 uint32_t ls_recover_status;
501 uint64_t ls_recover_seq;
502 struct dlm_recover *ls_recover_args;
503 struct rw_semaphore ls_in_recovery;
504 struct rw_semaphore ls_recv_active;
505 struct list_head ls_requestqueue;
506 struct mutex ls_requestqueue_mutex;
507 struct dlm_rcom *ls_recover_buf;
508 int ls_recover_nodeid;
509 uint64_t ls_rcom_seq;
510 spinlock_t ls_rcom_spin;
511 struct list_head ls_recover_list;
512 spinlock_t ls_recover_list_lock;
513 int ls_recover_list_count;
514 wait_queue_head_t ls_wait_general;
515 struct mutex ls_clear_proc_locks;
516
517 struct list_head ls_root_list;
518 struct rw_semaphore ls_root_sem;
519
520 int ls_namelen;
521 char ls_name[1];
522};
523
524#define LSFL_WORK 0
525#define LSFL_RUNNING 1
526#define LSFL_RECOVERY_STOP 2
527#define LSFL_RCOM_READY 3
528#define LSFL_RCOM_WAIT 4
529#define LSFL_UEVENT_WAIT 5
530#define LSFL_TIMEWARN 6
531
532
533
534
535struct dlm_user_args {
536 struct dlm_user_proc *proc;
537
538
539
540 struct dlm_lksb lksb;
541 int old_mode;
542 int update_user_lvb;
543 struct dlm_lksb __user *user_lksb;
544 void __user *castparam;
545 void __user *castaddr;
546 void __user *bastparam;
547 void __user *bastaddr;
548 uint64_t xid;
549};
550
551#define DLM_PROC_FLAGS_CLOSING 1
552#define DLM_PROC_FLAGS_COMPAT 2
553
554
555
556
557struct dlm_user_proc {
558 dlm_lockspace_t *lockspace;
559 unsigned long flags;
560 struct list_head asts;
561 spinlock_t asts_spin;
562 struct list_head locks;
563 spinlock_t locks_spin;
564 struct list_head unlocking;
565 wait_queue_head_t wait;
566};
567
568static inline int dlm_locking_stopped(struct dlm_ls *ls)
569{
570 return !test_bit(LSFL_RUNNING, &ls->ls_flags);
571}
572
573static inline int dlm_recovery_stopped(struct dlm_ls *ls)
574{
575 return test_bit(LSFL_RECOVERY_STOP, &ls->ls_flags);
576}
577
578static inline int dlm_no_directory(struct dlm_ls *ls)
579{
580 return (ls->ls_exflags & DLM_LSFL_NODIR) ? 1 : 0;
581}
582
583int dlm_netlink_init(void);
584void dlm_netlink_exit(void);
585void dlm_timeout_warn(struct dlm_lkb *lkb);
586int dlm_plock_init(void);
587void dlm_plock_exit(void);
588
589#ifdef CONFIG_DLM_DEBUG
590int dlm_register_debugfs(void);
591void dlm_unregister_debugfs(void);
592int dlm_create_debug_file(struct dlm_ls *ls);
593void dlm_delete_debug_file(struct dlm_ls *ls);
594#else
595static inline int dlm_register_debugfs(void) { return 0; }
596static inline void dlm_unregister_debugfs(void) { }
597static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
598static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
599#endif
600
601#endif
602
603