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/slab.h>
22#include <linux/sched.h>
23#include <linux/types.h>
24#include <linux/ctype.h>
25#include <linux/spinlock.h>
26#include <linux/vmalloc.h>
27#include <linux/list.h>
28#include <linux/errno.h>
29#include <linux/random.h>
30#include <linux/delay.h>
31#include <linux/socket.h>
32#include <linux/kthread.h>
33#include <linux/kobject.h>
34#include <linux/kref.h>
35#include <linux/kernel.h>
36#include <linux/jhash.h>
37#include <linux/miscdevice.h>
38#include <linux/mutex.h>
39#include <linux/idr.h>
40#include <linux/ratelimit.h>
41#include <linux/uaccess.h>
42
43#include <linux/dlm.h>
44#include "config.h"
45
46
47
48
49
50#define DLM_INBUF_LEN 148
51
52struct dlm_ls;
53struct dlm_lkb;
54struct dlm_rsb;
55struct dlm_member;
56struct dlm_rsbtable;
57struct dlm_recover;
58struct dlm_header;
59struct dlm_message;
60struct dlm_rcom;
61struct dlm_mhandle;
62
63#define log_print(fmt, args...) \
64 printk(KERN_ERR "dlm: "fmt"\n" , ##args)
65#define log_error(ls, fmt, args...) \
66 printk(KERN_ERR "dlm: %s: " fmt "\n", (ls)->ls_name , ##args)
67
68#define log_rinfo(ls, fmt, args...) \
69do { \
70 if (dlm_config.ci_log_info) \
71 printk(KERN_INFO "dlm: %s: " fmt "\n", \
72 (ls)->ls_name, ##args); \
73 else 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_debug(ls, fmt, args...) \
79do { \
80 if (dlm_config.ci_log_debug) \
81 printk(KERN_DEBUG "dlm: %s: " fmt "\n", \
82 (ls)->ls_name , ##args); \
83} while (0)
84
85#define log_limit(ls, fmt, args...) \
86do { \
87 if (dlm_config.ci_log_debug) \
88 printk_ratelimited(KERN_DEBUG "dlm: %s: " fmt "\n", \
89 (ls)->ls_name , ##args); \
90} while (0)
91
92#define DLM_ASSERT(x, do) \
93{ \
94 if (!(x)) \
95 { \
96 printk(KERN_ERR "\nDLM: Assertion failed on line %d of file %s\n" \
97 "DLM: assertion: \"%s\"\n" \
98 "DLM: time = %lu\n", \
99 __LINE__, __FILE__, #x, jiffies); \
100 {do} \
101 printk("\n"); \
102 BUG(); \
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 0x00000001
375
376#define DLM_HEADER_SLOTS 0x00000001
377
378#define DLM_MSG 1
379#define DLM_RCOM 2
380
381struct dlm_header {
382 uint32_t h_version;
383 uint32_t h_lockspace;
384 uint32_t h_nodeid;
385 uint16_t h_length;
386 uint8_t h_cmd;
387 uint8_t h_pad;
388};
389
390
391#define DLM_MSG_REQUEST 1
392#define DLM_MSG_CONVERT 2
393#define DLM_MSG_UNLOCK 3
394#define DLM_MSG_CANCEL 4
395#define DLM_MSG_REQUEST_REPLY 5
396#define DLM_MSG_CONVERT_REPLY 6
397#define DLM_MSG_UNLOCK_REPLY 7
398#define DLM_MSG_CANCEL_REPLY 8
399#define DLM_MSG_GRANT 9
400#define DLM_MSG_BAST 10
401#define DLM_MSG_LOOKUP 11
402#define DLM_MSG_REMOVE 12
403#define DLM_MSG_LOOKUP_REPLY 13
404#define DLM_MSG_PURGE 14
405
406struct dlm_message {
407 struct dlm_header m_header;
408 uint32_t m_type;
409 uint32_t m_nodeid;
410 uint32_t m_pid;
411 uint32_t m_lkid;
412 uint32_t m_remid;
413 uint32_t m_parent_lkid;
414 uint32_t m_parent_remid;
415 uint32_t m_exflags;
416 uint32_t m_sbflags;
417 uint32_t m_flags;
418 uint32_t m_lvbseq;
419 uint32_t m_hash;
420 int m_status;
421 int m_grmode;
422 int m_rqmode;
423 int m_bastmode;
424 int m_asts;
425 int m_result;
426 char m_extra[0];
427};
428
429
430#define DLM_RS_NODES 0x00000001
431#define DLM_RS_NODES_ALL 0x00000002
432#define DLM_RS_DIR 0x00000004
433#define DLM_RS_DIR_ALL 0x00000008
434#define DLM_RS_LOCKS 0x00000010
435#define DLM_RS_LOCKS_ALL 0x00000020
436#define DLM_RS_DONE 0x00000040
437#define DLM_RS_DONE_ALL 0x00000080
438
439#define DLM_RCOM_STATUS 1
440#define DLM_RCOM_NAMES 2
441#define DLM_RCOM_LOOKUP 3
442#define DLM_RCOM_LOCK 4
443#define DLM_RCOM_STATUS_REPLY 5
444#define DLM_RCOM_NAMES_REPLY 6
445#define DLM_RCOM_LOOKUP_REPLY 7
446#define DLM_RCOM_LOCK_REPLY 8
447
448struct dlm_rcom {
449 struct dlm_header rc_header;
450 uint32_t rc_type;
451 int rc_result;
452 uint64_t rc_id;
453 uint64_t rc_seq;
454 uint64_t rc_seq_reply;
455 char rc_buf[0];
456};
457
458union dlm_packet {
459 struct dlm_header header;
460 struct dlm_message message;
461 struct dlm_rcom rcom;
462};
463
464#define DLM_RSF_NEED_SLOTS 0x00000001
465
466
467struct rcom_status {
468 __le32 rs_flags;
469 __le32 rs_unused1;
470 __le64 rs_unused2;
471};
472
473
474struct rcom_config {
475 __le32 rf_lvblen;
476 __le32 rf_lsflags;
477
478
479 __le32 rf_flags;
480 __le16 rf_our_slot;
481 __le16 rf_num_slots;
482 __le32 rf_generation;
483 __le32 rf_unused1;
484 __le64 rf_unused2;
485};
486
487struct rcom_slot {
488 __le32 ro_nodeid;
489 __le16 ro_slot;
490 __le16 ro_unused1;
491 __le64 ro_unused2;
492};
493
494struct rcom_lock {
495 __le32 rl_ownpid;
496 __le32 rl_lkid;
497 __le32 rl_remid;
498 __le32 rl_parent_lkid;
499 __le32 rl_parent_remid;
500 __le32 rl_exflags;
501 __le32 rl_flags;
502 __le32 rl_lvbseq;
503 __le32 rl_result;
504 int8_t rl_rqmode;
505 int8_t rl_grmode;
506 int8_t rl_status;
507 int8_t rl_asts;
508 __le16 rl_wait_type;
509 __le16 rl_namelen;
510 char rl_name[DLM_RESNAME_MAXLEN];
511 char rl_lvb[0];
512};
513
514
515
516
517
518
519#define DLM_REMOVE_NAMES_MAX 8
520
521struct dlm_ls {
522 struct list_head ls_list;
523 dlm_lockspace_t *ls_local_handle;
524 uint32_t ls_global_id;
525 uint32_t ls_generation;
526 uint32_t ls_exflags;
527 int ls_lvblen;
528 int ls_count;
529
530 int ls_create_count;
531 unsigned long ls_flags;
532 unsigned long ls_scan_time;
533 struct kobject ls_kobj;
534
535 struct idr ls_lkbidr;
536 spinlock_t ls_lkbidr_spin;
537
538 struct dlm_rsbtable *ls_rsbtbl;
539 uint32_t ls_rsbtbl_size;
540
541 struct mutex ls_waiters_mutex;
542 struct list_head ls_waiters;
543
544 struct mutex ls_orphans_mutex;
545 struct list_head ls_orphans;
546
547 struct mutex ls_timeout_mutex;
548 struct list_head ls_timeout;
549
550 spinlock_t ls_new_rsb_spin;
551 int ls_new_rsb_count;
552 struct list_head ls_new_rsb;
553
554 spinlock_t ls_remove_spin;
555 char ls_remove_name[DLM_RESNAME_MAXLEN+1];
556 char *ls_remove_names[DLM_REMOVE_NAMES_MAX];
557 int ls_remove_len;
558 int ls_remove_lens[DLM_REMOVE_NAMES_MAX];
559
560 struct list_head ls_nodes;
561 struct list_head ls_nodes_gone;
562 int ls_num_nodes;
563 int ls_low_nodeid;
564 int ls_total_weight;
565 int *ls_node_array;
566
567 int ls_slot;
568 int ls_num_slots;
569 int ls_slots_size;
570 struct dlm_slot *ls_slots;
571
572 struct dlm_rsb ls_stub_rsb;
573 struct dlm_lkb ls_stub_lkb;
574 struct dlm_message ls_stub_ms;
575
576 struct dentry *ls_debug_rsb_dentry;
577 struct dentry *ls_debug_waiters_dentry;
578 struct dentry *ls_debug_locks_dentry;
579 struct dentry *ls_debug_all_dentry;
580 struct dentry *ls_debug_toss_dentry;
581
582 wait_queue_head_t ls_uevent_wait;
583 int ls_uevent_result;
584 struct completion ls_members_done;
585 int ls_members_result;
586
587 struct miscdevice ls_device;
588
589 struct workqueue_struct *ls_callback_wq;
590
591
592
593 struct mutex ls_cb_mutex;
594 struct list_head ls_cb_delay;
595 struct timer_list ls_timer;
596 struct task_struct *ls_recoverd_task;
597 struct mutex ls_recoverd_active;
598 spinlock_t ls_recover_lock;
599 unsigned long ls_recover_begin;
600 uint32_t ls_recover_status;
601 uint64_t ls_recover_seq;
602 struct dlm_recover *ls_recover_args;
603 struct rw_semaphore ls_in_recovery;
604 struct rw_semaphore ls_recv_active;
605 struct list_head ls_requestqueue;
606 struct mutex ls_requestqueue_mutex;
607 struct dlm_rcom *ls_recover_buf;
608 int ls_recover_nodeid;
609 unsigned int ls_recover_dir_sent_res;
610 unsigned int ls_recover_dir_sent_msg;
611 unsigned int ls_recover_locks_in;
612 uint64_t ls_rcom_seq;
613 spinlock_t ls_rcom_spin;
614 struct list_head ls_recover_list;
615 spinlock_t ls_recover_list_lock;
616 int ls_recover_list_count;
617 struct idr ls_recover_idr;
618 spinlock_t ls_recover_idr_lock;
619 wait_queue_head_t ls_wait_general;
620 wait_queue_head_t ls_recover_lock_wait;
621 struct mutex ls_clear_proc_locks;
622
623 struct list_head ls_root_list;
624 struct rw_semaphore ls_root_sem;
625
626 const struct dlm_lockspace_ops *ls_ops;
627 void *ls_ops_arg;
628
629 int ls_namelen;
630 char ls_name[1];
631};
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655#define LSFL_RECOVER_STOP 0
656#define LSFL_RECOVER_DOWN 1
657#define LSFL_RECOVER_LOCK 2
658#define LSFL_RECOVER_WORK 3
659#define LSFL_RUNNING 4
660
661#define LSFL_RCOM_READY 5
662#define LSFL_RCOM_WAIT 6
663#define LSFL_UEVENT_WAIT 7
664#define LSFL_TIMEWARN 8
665#define LSFL_CB_DELAY 9
666#define LSFL_NODIR 10
667
668
669
670
671struct dlm_user_args {
672 struct dlm_user_proc *proc;
673
674
675
676 struct dlm_lksb lksb;
677 struct dlm_lksb __user *user_lksb;
678 void __user *castparam;
679 void __user *castaddr;
680 void __user *bastparam;
681 void __user *bastaddr;
682 uint64_t xid;
683};
684
685#define DLM_PROC_FLAGS_CLOSING 1
686#define DLM_PROC_FLAGS_COMPAT 2
687
688
689
690
691struct dlm_user_proc {
692 dlm_lockspace_t *lockspace;
693 unsigned long flags;
694 struct list_head asts;
695 spinlock_t asts_spin;
696 struct list_head locks;
697 spinlock_t locks_spin;
698 struct list_head unlocking;
699 wait_queue_head_t wait;
700};
701
702static inline int dlm_locking_stopped(struct dlm_ls *ls)
703{
704 return !test_bit(LSFL_RUNNING, &ls->ls_flags);
705}
706
707static inline int dlm_recovery_stopped(struct dlm_ls *ls)
708{
709 return test_bit(LSFL_RECOVER_STOP, &ls->ls_flags);
710}
711
712static inline int dlm_no_directory(struct dlm_ls *ls)
713{
714 return test_bit(LSFL_NODIR, &ls->ls_flags);
715}
716
717int dlm_netlink_init(void);
718void dlm_netlink_exit(void);
719void dlm_timeout_warn(struct dlm_lkb *lkb);
720int dlm_plock_init(void);
721void dlm_plock_exit(void);
722
723#ifdef CONFIG_DLM_DEBUG
724int dlm_register_debugfs(void);
725void dlm_unregister_debugfs(void);
726int dlm_create_debug_file(struct dlm_ls *ls);
727void dlm_delete_debug_file(struct dlm_ls *ls);
728#else
729static inline int dlm_register_debugfs(void) { return 0; }
730static inline void dlm_unregister_debugfs(void) { }
731static inline int dlm_create_debug_file(struct dlm_ls *ls) { return 0; }
732static inline void dlm_delete_debug_file(struct dlm_ls *ls) { }
733#endif
734
735#endif
736
737