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 <linux/idr.h>
41#include <linux/ratelimit.h>
42#include <asm/uaccess.h>
43
44#include <linux/dlm.h>
45#include "config.h"
46
47
48
49
50
51#define DLM_INBUF_LEN 148
52
53struct dlm_ls;
54struct dlm_lkb;
55struct dlm_rsb;
56struct dlm_member;
57struct dlm_rsbtable;
58struct dlm_recover;
59struct dlm_header;
60struct dlm_message;
61struct dlm_rcom;
62struct dlm_mhandle;
63
64#define log_print(fmt, args...) \
65 printk(KERN_ERR "dlm: "fmt"\n" , ##args)
66#define log_error(ls, fmt, args...) \
67 printk(KERN_ERR "dlm: %s: " fmt "\n", (ls)->ls_name , ##args)
68#define log_rinfo(ls, fmt, args...) \
69 printk(KERN_INFO "dlm: %s: " fmt "\n", (ls)->ls_name , ##args);
70
71#define log_debug(ls, fmt, args...) \
72do { \
73 if (dlm_config.ci_log_debug) \
74 printk(KERN_DEBUG "dlm: %s: " fmt "\n", \
75 (ls)->ls_name , ##args); \
76} while (0)
77
78#define log_limit(ls, fmt, args...) \
79do { \
80 if (dlm_config.ci_log_debug) \
81 printk_ratelimited(KERN_DEBUG "dlm: %s: " fmt "\n", \
82 (ls)->ls_name , ##args); \
83} while (0)
84
85#define DLM_ASSERT(x, do) \
86{ \
87 if (!(x)) \
88 { \
89 printk(KERN_ERR "\nDLM: Assertion failed on line %d of file %s\n" \
90 "DLM: assertion: \"%s\"\n" \
91 "DLM: time = %lu\n", \
92 __LINE__, __FILE__, #x, jiffies); \
93 {do} \
94 printk("\n"); \
95 BUG(); \
96 panic("DLM: Record message above and reboot.\n"); \
97 } \
98}
99
100
101#define DLM_RTF_SHRINK 0x00000001
102
103struct dlm_rsbtable {
104 struct rb_root keep;
105 struct rb_root toss;
106 spinlock_t lock;
107 uint32_t flags;
108};
109
110
111
112
113
114
115struct dlm_member {
116 struct list_head list;
117 int nodeid;
118 int weight;
119 int slot;
120 int slot_prev;
121 int comm_seq;
122 uint32_t generation;
123};
124
125
126
127
128
129struct dlm_recover {
130 struct list_head list;
131 struct dlm_config_node *nodes;
132 int nodes_count;
133 uint64_t seq;
134};
135
136
137
138
139
140struct dlm_args {
141 uint32_t flags;
142 void (*astfn) (void *astparam);
143 void *astparam;
144 void (*bastfn) (void *astparam, int mode);
145 int mode;
146 struct dlm_lksb *lksb;
147 unsigned long timeout;
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#define DLM_LKSTS_WAITING 1
194#define DLM_LKSTS_GRANTED 2
195#define DLM_LKSTS_CONVERT 3
196
197
198
199#define DLM_IFL_MSTCPY 0x00010000
200#define DLM_IFL_RESEND 0x00020000
201#define DLM_IFL_DEAD 0x00040000
202#define DLM_IFL_OVERLAP_UNLOCK 0x00080000
203#define DLM_IFL_OVERLAP_CANCEL 0x00100000
204#define DLM_IFL_ENDOFLIFE 0x00200000
205#define DLM_IFL_WATCH_TIMEWARN 0x00400000
206#define DLM_IFL_TIMEOUT_CANCEL 0x00800000
207#define DLM_IFL_DEADLOCK_CANCEL 0x01000000
208#define DLM_IFL_STUB_MS 0x02000000
209#define DLM_IFL_USER 0x00000001
210#define DLM_IFL_ORPHAN 0x00000002
211
212#define DLM_CALLBACKS_SIZE 6
213
214#define DLM_CB_CAST 0x00000001
215#define DLM_CB_BAST 0x00000002
216#define DLM_CB_SKIP 0x00000004
217
218struct dlm_callback {
219 uint64_t seq;
220 uint32_t flags;
221 int sb_status;
222 uint8_t sb_flags;
223 int8_t mode;
224};
225
226struct dlm_lkb {
227 struct dlm_rsb *lkb_resource;
228 struct kref lkb_ref;
229 int lkb_nodeid;
230 int lkb_ownpid;
231 uint32_t lkb_id;
232 uint32_t lkb_remid;
233 uint32_t lkb_exflags;
234 uint32_t lkb_sbflags;
235 uint32_t lkb_flags;
236 uint32_t lkb_lvbseq;
237
238 int8_t lkb_status;
239 int8_t lkb_rqmode;
240 int8_t lkb_grmode;
241 int8_t lkb_highbast;
242
243 int8_t lkb_wait_type;
244 int8_t lkb_wait_count;
245 int lkb_wait_nodeid;
246
247 struct list_head lkb_statequeue;
248 struct list_head lkb_rsb_lookup;
249 struct list_head lkb_wait_reply;
250 struct list_head lkb_ownqueue;
251 struct list_head lkb_time_list;
252 ktime_t lkb_timestamp;
253 ktime_t lkb_wait_time;
254 unsigned long lkb_timeout_cs;
255
256 struct mutex lkb_cb_mutex;
257 struct work_struct lkb_cb_work;
258 struct list_head lkb_cb_list;
259 struct dlm_callback lkb_callbacks[DLM_CALLBACKS_SIZE];
260 struct dlm_callback lkb_last_cast;
261 struct dlm_callback lkb_last_bast;
262 ktime_t lkb_last_cast_time;
263 ktime_t lkb_last_bast_time;
264
265 uint64_t lkb_recover_seq;
266
267 char *lkb_lvbptr;
268 struct dlm_lksb *lkb_lksb;
269 void (*lkb_astfn) (void *astparam);
270 void (*lkb_bastfn) (void *astparam, int mode);
271 union {
272 void *lkb_astparam;
273 struct dlm_user_args *lkb_ua;
274 };
275};
276
277
278
279
280
281
282
283
284
285
286
287struct dlm_rsb {
288 struct dlm_ls *res_ls;
289 struct kref res_ref;
290 struct mutex res_mutex;
291 unsigned long res_flags;
292 int res_length;
293 int res_nodeid;
294 int res_master_nodeid;
295 int res_dir_nodeid;
296 int res_id;
297 uint32_t res_lvbseq;
298 uint32_t res_hash;
299 uint32_t res_bucket;
300 unsigned long res_toss_time;
301 uint32_t res_first_lkid;
302 struct list_head res_lookup;
303 union {
304 struct list_head res_hashchain;
305 struct rb_node res_hashnode;
306 };
307 struct list_head res_grantqueue;
308 struct list_head res_convertqueue;
309 struct list_head res_waitqueue;
310
311 struct list_head res_root_list;
312 struct list_head res_recover_list;
313 int res_recover_locks_count;
314
315 char *res_lvbptr;
316 char res_name[DLM_RESNAME_MAXLEN+1];
317};
318
319
320
321#define DLM_LU_RECOVER_DIR 1
322#define DLM_LU_RECOVER_MASTER 2
323
324
325
326#define DLM_LU_MATCH 1
327#define DLM_LU_ADD 2
328
329
330
331#define R_REQUEST 0x00000001
332#define R_RECEIVE_REQUEST 0x00000002
333#define R_RECEIVE_RECOVER 0x00000004
334
335
336
337enum rsb_flags {
338 RSB_MASTER_UNCERTAIN,
339 RSB_VALNOTVALID,
340 RSB_VALNOTVALID_PREV,
341 RSB_NEW_MASTER,
342 RSB_NEW_MASTER2,
343 RSB_RECOVER_CONVERT,
344 RSB_RECOVER_GRANT,
345 RSB_RECOVER_LVB_INVAL,
346};
347
348static inline void rsb_set_flag(struct dlm_rsb *r, enum rsb_flags flag)
349{
350 __set_bit(flag, &r->res_flags);
351}
352
353static inline void rsb_clear_flag(struct dlm_rsb *r, enum rsb_flags flag)
354{
355 __clear_bit(flag, &r->res_flags);
356}
357
358static inline int rsb_flag(struct dlm_rsb *r, enum rsb_flags flag)
359{
360 return test_bit(flag, &r->res_flags);
361}
362
363
364
365
366#define DLM_HEADER_MAJOR 0x00030000
367#define DLM_HEADER_MINOR 0x00000001
368
369#define DLM_HEADER_SLOTS 0x00000001
370
371#define DLM_MSG 1
372#define DLM_RCOM 2
373
374struct dlm_header {
375 uint32_t h_version;
376 uint32_t h_lockspace;
377 uint32_t h_nodeid;
378 uint16_t h_length;
379 uint8_t h_cmd;
380 uint8_t h_pad;
381};
382
383
384#define DLM_MSG_REQUEST 1
385#define DLM_MSG_CONVERT 2
386#define DLM_MSG_UNLOCK 3
387#define DLM_MSG_CANCEL 4
388#define DLM_MSG_REQUEST_REPLY 5
389#define DLM_MSG_CONVERT_REPLY 6
390#define DLM_MSG_UNLOCK_REPLY 7
391#define DLM_MSG_CANCEL_REPLY 8
392#define DLM_MSG_GRANT 9
393#define DLM_MSG_BAST 10
394#define DLM_MSG_LOOKUP 11
395#define DLM_MSG_REMOVE 12
396#define DLM_MSG_LOOKUP_REPLY 13
397#define DLM_MSG_PURGE 14
398
399struct dlm_message {
400 struct dlm_header m_header;
401 uint32_t m_type;
402 uint32_t m_nodeid;
403 uint32_t m_pid;
404 uint32_t m_lkid;
405 uint32_t m_remid;
406 uint32_t m_parent_lkid;
407 uint32_t m_parent_remid;
408 uint32_t m_exflags;
409 uint32_t m_sbflags;
410 uint32_t m_flags;
411 uint32_t m_lvbseq;
412 uint32_t m_hash;
413 int m_status;
414 int m_grmode;
415 int m_rqmode;
416 int m_bastmode;
417 int m_asts;
418 int m_result;
419 char m_extra[0];
420};
421
422
423#define DLM_RS_NODES 0x00000001
424#define DLM_RS_NODES_ALL 0x00000002
425#define DLM_RS_DIR 0x00000004
426#define DLM_RS_DIR_ALL 0x00000008
427#define DLM_RS_LOCKS 0x00000010
428#define DLM_RS_LOCKS_ALL 0x00000020
429#define DLM_RS_DONE 0x00000040
430#define DLM_RS_DONE_ALL 0x00000080
431
432#define DLM_RCOM_STATUS 1
433#define DLM_RCOM_NAMES 2
434#define DLM_RCOM_LOOKUP 3
435#define DLM_RCOM_LOCK 4
436#define DLM_RCOM_STATUS_REPLY 5
437#define DLM_RCOM_NAMES_REPLY 6
438#define DLM_RCOM_LOOKUP_REPLY 7
439#define DLM_RCOM_LOCK_REPLY 8
440
441struct dlm_rcom {
442 struct dlm_header rc_header;
443 uint32_t rc_type;
444 int rc_result;
445 uint64_t rc_id;
446 uint64_t rc_seq;
447 uint64_t rc_seq_reply;
448 char rc_buf[0];
449};
450
451union dlm_packet {
452 struct dlm_header header;
453 struct dlm_message message;
454 struct dlm_rcom rcom;
455};
456
457#define DLM_RSF_NEED_SLOTS 0x00000001
458
459
460struct rcom_status {
461 __le32 rs_flags;
462 __le32 rs_unused1;
463 __le64 rs_unused2;
464};
465
466
467struct rcom_config {
468 __le32 rf_lvblen;
469 __le32 rf_lsflags;
470
471
472 __le32 rf_flags;
473 __le16 rf_our_slot;
474 __le16 rf_num_slots;
475 __le32 rf_generation;
476 __le32 rf_unused1;
477 __le64 rf_unused2;
478};
479
480struct rcom_slot {
481 __le32 ro_nodeid;
482 __le16 ro_slot;
483 __le16 ro_unused1;
484 __le64 ro_unused2;
485};
486
487struct rcom_lock {
488 __le32 rl_ownpid;
489 __le32 rl_lkid;
490 __le32 rl_remid;
491 __le32 rl_parent_lkid;
492 __le32 rl_parent_remid;
493 __le32 rl_exflags;
494 __le32 rl_flags;
495 __le32 rl_lvbseq;
496 __le32 rl_result;
497 int8_t rl_rqmode;
498 int8_t rl_grmode;
499 int8_t rl_status;
500 int8_t rl_asts;
501 __le16 rl_wait_type;
502 __le16 rl_namelen;
503 char rl_name[DLM_RESNAME_MAXLEN];
504 char rl_lvb[0];
505};
506
507
508
509
510
511
512#define DLM_REMOVE_NAMES_MAX 8
513
514struct dlm_ls {
515 struct list_head ls_list;
516 dlm_lockspace_t *ls_local_handle;
517 uint32_t ls_global_id;
518 uint32_t ls_generation;
519 uint32_t ls_exflags;
520 int ls_lvblen;
521 int ls_count;
522
523 int ls_create_count;
524 unsigned long ls_flags;
525 unsigned long ls_scan_time;
526 struct kobject ls_kobj;
527
528 struct idr ls_lkbidr;
529 spinlock_t ls_lkbidr_spin;
530
531 struct dlm_rsbtable *ls_rsbtbl;
532 uint32_t ls_rsbtbl_size;
533
534 struct mutex ls_waiters_mutex;
535 struct list_head ls_waiters;
536
537 struct mutex ls_orphans_mutex;
538 struct list_head ls_orphans;
539
540 struct mutex ls_timeout_mutex;
541 struct list_head ls_timeout;
542
543 spinlock_t ls_new_rsb_spin;
544 int ls_new_rsb_count;
545 struct list_head ls_new_rsb;
546
547 spinlock_t ls_remove_spin;
548 char ls_remove_name[DLM_RESNAME_MAXLEN+1];
549 char *ls_remove_names[DLM_REMOVE_NAMES_MAX];
550 int ls_remove_len;
551 int ls_remove_lens[DLM_REMOVE_NAMES_MAX];
552
553 struct list_head ls_nodes;
554 struct list_head ls_nodes_gone;
555 int ls_num_nodes;
556 int ls_low_nodeid;
557 int ls_total_weight;
558 int *ls_node_array;
559
560 int ls_slot;
561 int ls_num_slots;
562 int ls_slots_size;
563 struct dlm_slot *ls_slots;
564
565 struct dlm_rsb ls_stub_rsb;
566 struct dlm_lkb ls_stub_lkb;
567 struct dlm_message ls_stub_ms;
568
569 struct dentry *ls_debug_rsb_dentry;
570 struct dentry *ls_debug_waiters_dentry;
571 struct dentry *ls_debug_locks_dentry;
572 struct dentry *ls_debug_all_dentry;
573 struct dentry *ls_debug_toss_dentry;
574
575 wait_queue_head_t ls_uevent_wait;
576 int ls_uevent_result;
577 struct completion ls_members_done;
578 int ls_members_result;
579
580 struct miscdevice ls_device;
581
582 struct workqueue_struct *ls_callback_wq;
583
584
585
586 struct mutex ls_cb_mutex;
587 struct list_head ls_cb_delay;
588 struct timer_list ls_timer;
589 struct task_struct *ls_recoverd_task;
590 struct mutex ls_recoverd_active;
591 spinlock_t ls_recover_lock;
592 unsigned long ls_recover_begin;
593 uint32_t ls_recover_status;
594 uint64_t ls_recover_seq;
595 struct dlm_recover *ls_recover_args;
596 struct rw_semaphore ls_in_recovery;
597 struct rw_semaphore ls_recv_active;
598 struct list_head ls_requestqueue;
599 struct mutex ls_requestqueue_mutex;
600 struct dlm_rcom *ls_recover_buf;
601 int ls_recover_nodeid;
602 unsigned int ls_recover_dir_sent_res;
603 unsigned int ls_recover_dir_sent_msg;
604 unsigned int ls_recover_locks_in;
605 uint64_t ls_rcom_seq;
606 spinlock_t ls_rcom_spin;
607 struct list_head ls_recover_list;
608 spinlock_t ls_recover_list_lock;
609 int ls_recover_list_count;
610 struct idr ls_recover_idr;
611 spinlock_t ls_recover_idr_lock;
612 wait_queue_head_t ls_wait_general;
613 wait_queue_head_t ls_recover_lock_wait;
614 struct mutex ls_clear_proc_locks;
615
616 struct list_head ls_root_list;
617 struct rw_semaphore ls_root_sem;
618
619 const struct dlm_lockspace_ops *ls_ops;
620 void *ls_ops_arg;
621
622 int ls_namelen;
623 char ls_name[1];
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#define LSFL_RECOVER_STOP 0
649#define LSFL_RECOVER_DOWN 1
650#define LSFL_RECOVER_LOCK 2
651#define LSFL_RECOVER_WORK 3
652#define LSFL_RUNNING 4
653
654#define LSFL_RCOM_READY 5
655#define LSFL_RCOM_WAIT 6
656#define LSFL_UEVENT_WAIT 7
657#define LSFL_TIMEWARN 8
658#define LSFL_CB_DELAY 9
659#define LSFL_NODIR 10
660
661
662
663
664struct dlm_user_args {
665 struct dlm_user_proc *proc;
666
667
668
669 struct dlm_lksb lksb;
670 struct dlm_lksb __user *user_lksb;
671 void __user *castparam;
672 void __user *castaddr;
673 void __user *bastparam;
674 void __user *bastaddr;
675 uint64_t xid;
676};
677
678#define DLM_PROC_FLAGS_CLOSING 1
679#define DLM_PROC_FLAGS_COMPAT 2
680
681
682
683
684struct dlm_user_proc {
685 dlm_lockspace_t *lockspace;
686 unsigned long flags;
687 struct list_head asts;
688 spinlock_t asts_spin;
689 struct list_head locks;
690 spinlock_t locks_spin;
691 struct list_head unlocking;
692 wait_queue_head_t wait;
693};
694
695static inline int dlm_locking_stopped(struct dlm_ls *ls)
696{
697 return !test_bit(LSFL_RUNNING, &ls->ls_flags);
698}
699
700static inline int dlm_recovery_stopped(struct dlm_ls *ls)
701{
702 return test_bit(LSFL_RECOVER_STOP, &ls->ls_flags);
703}
704
705static inline int dlm_no_directory(struct dlm_ls *ls)
706{
707 return test_bit(LSFL_NODIR, &ls->ls_flags);
708}
709
710int dlm_netlink_init(void);
711void dlm_netlink_exit(void);
712void dlm_timeout_warn(struct dlm_lkb *lkb);
713int dlm_plock_init(void);
714void dlm_plock_exit(void);
715
716#ifdef CONFIG_DLM_DEBUG
717int dlm_register_debugfs(void);
718void dlm_unregister_debugfs(void);
719int dlm_create_debug_file(struct dlm_ls *ls);
720void dlm_delete_debug_file(struct dlm_ls *ls);
721#else
722static inline int dlm_register_debugfs(void) { return 0; }
723static inline void dlm_unregister_debugfs(void) { }
724static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
725static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
726#endif
727
728#endif
729
730