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