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