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