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