0001
0002
0003
0004
0005
0006
0007
0008 #ifndef DLMCOMMON_H
0009 #define DLMCOMMON_H
0010
0011 #include <linux/kref.h>
0012
0013 #define DLM_HB_NODE_DOWN_PRI (0xf000000)
0014 #define DLM_HB_NODE_UP_PRI (0x8000000)
0015
0016 #define DLM_LOCKID_NAME_MAX 32
0017
0018 #define DLM_LOCK_RES_OWNER_UNKNOWN O2NM_MAX_NODES
0019
0020 #define DLM_HASH_SIZE_DEFAULT (1 << 17)
0021 #if DLM_HASH_SIZE_DEFAULT < PAGE_SIZE
0022 # define DLM_HASH_PAGES 1
0023 #else
0024 # define DLM_HASH_PAGES (DLM_HASH_SIZE_DEFAULT / PAGE_SIZE)
0025 #endif
0026 #define DLM_BUCKETS_PER_PAGE (PAGE_SIZE / sizeof(struct hlist_head))
0027 #define DLM_HASH_BUCKETS (DLM_HASH_PAGES * DLM_BUCKETS_PER_PAGE)
0028
0029
0030 #define dlm_lockid_hash(_n, _l) full_name_hash(NULL, _n, _l)
0031
0032 enum dlm_mle_type {
0033 DLM_MLE_BLOCK = 0,
0034 DLM_MLE_MASTER = 1,
0035 DLM_MLE_MIGRATION = 2,
0036 DLM_MLE_NUM_TYPES = 3,
0037 };
0038
0039 struct dlm_master_list_entry {
0040 struct hlist_node master_hash_node;
0041 struct list_head hb_events;
0042 struct dlm_ctxt *dlm;
0043 spinlock_t spinlock;
0044 wait_queue_head_t wq;
0045 atomic_t woken;
0046 struct kref mle_refs;
0047 int inuse;
0048 unsigned long maybe_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
0049 unsigned long vote_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
0050 unsigned long response_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
0051 unsigned long node_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
0052 u8 master;
0053 u8 new_master;
0054 enum dlm_mle_type type;
0055 struct o2hb_callback_func mle_hb_up;
0056 struct o2hb_callback_func mle_hb_down;
0057 struct dlm_lock_resource *mleres;
0058 unsigned char mname[DLM_LOCKID_NAME_MAX];
0059 unsigned int mnamelen;
0060 unsigned int mnamehash;
0061 };
0062
0063 enum dlm_ast_type {
0064 DLM_AST = 0,
0065 DLM_BAST = 1,
0066 DLM_ASTUNLOCK = 2,
0067 };
0068
0069
0070 #define LKM_VALID_FLAGS (LKM_VALBLK | LKM_CONVERT | LKM_UNLOCK | \
0071 LKM_CANCEL | LKM_INVVALBLK | LKM_FORCE | \
0072 LKM_RECOVERY | LKM_LOCAL | LKM_NOQUEUE)
0073
0074 #define DLM_RECOVERY_LOCK_NAME "$RECOVERY"
0075 #define DLM_RECOVERY_LOCK_NAME_LEN 9
0076
0077 static inline int dlm_is_recovery_lock(const char *lock_name, int name_len)
0078 {
0079 if (name_len == DLM_RECOVERY_LOCK_NAME_LEN &&
0080 memcmp(lock_name, DLM_RECOVERY_LOCK_NAME, name_len)==0)
0081 return 1;
0082 return 0;
0083 }
0084
0085 #define DLM_RECO_STATE_ACTIVE 0x0001
0086 #define DLM_RECO_STATE_FINALIZE 0x0002
0087
0088 struct dlm_recovery_ctxt
0089 {
0090 struct list_head resources;
0091 struct list_head node_data;
0092 u8 new_master;
0093 u8 dead_node;
0094 u16 state;
0095 unsigned long node_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
0096 wait_queue_head_t event;
0097 };
0098
0099 enum dlm_ctxt_state {
0100 DLM_CTXT_NEW = 0,
0101 DLM_CTXT_JOINED = 1,
0102 DLM_CTXT_IN_SHUTDOWN = 2,
0103 DLM_CTXT_LEAVING = 3,
0104 };
0105
0106 struct dlm_ctxt
0107 {
0108 struct list_head list;
0109 struct hlist_head **lockres_hash;
0110 struct list_head dirty_list;
0111 struct list_head purge_list;
0112 struct list_head pending_asts;
0113 struct list_head pending_basts;
0114 struct list_head tracking_list;
0115 unsigned int purge_count;
0116 spinlock_t spinlock;
0117 spinlock_t ast_lock;
0118 spinlock_t track_lock;
0119 char *name;
0120 u8 node_num;
0121 u32 key;
0122 u8 joining_node;
0123 u8 migrate_done;
0124 wait_queue_head_t dlm_join_events;
0125 unsigned long live_nodes_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
0126 unsigned long domain_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
0127 unsigned long exit_domain_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
0128 unsigned long recovery_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
0129 struct dlm_recovery_ctxt reco;
0130 spinlock_t master_lock;
0131 struct hlist_head **master_hash;
0132 struct list_head mle_hb_events;
0133
0134
0135 atomic_t mle_tot_count[DLM_MLE_NUM_TYPES];
0136 atomic_t mle_cur_count[DLM_MLE_NUM_TYPES];
0137 atomic_t res_tot_count;
0138 atomic_t res_cur_count;
0139
0140 struct dentry *dlm_debugfs_subroot;
0141
0142
0143 struct kref dlm_refs;
0144 enum dlm_ctxt_state dlm_state;
0145 unsigned int num_joins;
0146
0147 struct o2hb_callback_func dlm_hb_up;
0148 struct o2hb_callback_func dlm_hb_down;
0149 struct task_struct *dlm_thread_task;
0150 struct task_struct *dlm_reco_thread_task;
0151 struct workqueue_struct *dlm_worker;
0152 wait_queue_head_t dlm_thread_wq;
0153 wait_queue_head_t dlm_reco_thread_wq;
0154 wait_queue_head_t ast_wq;
0155 wait_queue_head_t migration_wq;
0156
0157 struct work_struct dispatched_work;
0158 struct list_head work_list;
0159 spinlock_t work_lock;
0160 struct list_head dlm_domain_handlers;
0161 struct list_head dlm_eviction_callbacks;
0162
0163
0164
0165 struct dlm_protocol_version fs_locking_proto;
0166
0167 struct dlm_protocol_version dlm_locking_proto;
0168 };
0169
0170 static inline struct hlist_head *dlm_lockres_hash(struct dlm_ctxt *dlm, unsigned i)
0171 {
0172 return dlm->lockres_hash[(i / DLM_BUCKETS_PER_PAGE) % DLM_HASH_PAGES] + (i % DLM_BUCKETS_PER_PAGE);
0173 }
0174
0175 static inline struct hlist_head *dlm_master_hash(struct dlm_ctxt *dlm,
0176 unsigned i)
0177 {
0178 return dlm->master_hash[(i / DLM_BUCKETS_PER_PAGE) % DLM_HASH_PAGES] +
0179 (i % DLM_BUCKETS_PER_PAGE);
0180 }
0181
0182
0183
0184
0185
0186 void dlm_dispatch_work(struct work_struct *work);
0187
0188 struct dlm_lock_resource;
0189 struct dlm_work_item;
0190
0191 typedef void (dlm_workfunc_t)(struct dlm_work_item *, void *);
0192
0193 struct dlm_request_all_locks_priv
0194 {
0195 u8 reco_master;
0196 u8 dead_node;
0197 };
0198
0199 struct dlm_mig_lockres_priv
0200 {
0201 struct dlm_lock_resource *lockres;
0202 u8 real_master;
0203 u8 extra_ref;
0204 };
0205
0206 struct dlm_assert_master_priv
0207 {
0208 struct dlm_lock_resource *lockres;
0209 u8 request_from;
0210 u32 flags;
0211 unsigned ignore_higher:1;
0212 };
0213
0214 struct dlm_deref_lockres_priv
0215 {
0216 struct dlm_lock_resource *deref_res;
0217 u8 deref_node;
0218 };
0219
0220 struct dlm_work_item
0221 {
0222 struct list_head list;
0223 dlm_workfunc_t *func;
0224 struct dlm_ctxt *dlm;
0225 void *data;
0226 union {
0227 struct dlm_request_all_locks_priv ral;
0228 struct dlm_mig_lockres_priv ml;
0229 struct dlm_assert_master_priv am;
0230 struct dlm_deref_lockres_priv dl;
0231 } u;
0232 };
0233
0234 static inline void dlm_init_work_item(struct dlm_ctxt *dlm,
0235 struct dlm_work_item *i,
0236 dlm_workfunc_t *f, void *data)
0237 {
0238 memset(i, 0, sizeof(*i));
0239 i->func = f;
0240 INIT_LIST_HEAD(&i->list);
0241 i->data = data;
0242 i->dlm = dlm;
0243 }
0244
0245
0246
0247 static inline void __dlm_set_joining_node(struct dlm_ctxt *dlm,
0248 u8 node)
0249 {
0250 assert_spin_locked(&dlm->spinlock);
0251
0252 dlm->joining_node = node;
0253 wake_up(&dlm->dlm_join_events);
0254 }
0255
0256 #define DLM_LOCK_RES_UNINITED 0x00000001
0257 #define DLM_LOCK_RES_RECOVERING 0x00000002
0258 #define DLM_LOCK_RES_READY 0x00000004
0259 #define DLM_LOCK_RES_DIRTY 0x00000008
0260 #define DLM_LOCK_RES_IN_PROGRESS 0x00000010
0261 #define DLM_LOCK_RES_MIGRATING 0x00000020
0262 #define DLM_LOCK_RES_DROPPING_REF 0x00000040
0263 #define DLM_LOCK_RES_BLOCK_DIRTY 0x00001000
0264 #define DLM_LOCK_RES_SETREF_INPROG 0x00002000
0265 #define DLM_LOCK_RES_RECOVERY_WAITING 0x00004000
0266
0267
0268 #define DLM_NODE_DEATH_WAIT_MAX (5 * 1000)
0269
0270 #define DLM_PURGE_INTERVAL_MS (8 * 1000)
0271
0272 struct dlm_lock_resource
0273 {
0274
0275
0276 struct hlist_node hash_node;
0277 struct qstr lockname;
0278 struct kref refs;
0279
0280
0281
0282
0283
0284
0285
0286 struct list_head granted;
0287 struct list_head converting;
0288 struct list_head blocked;
0289 struct list_head purge;
0290
0291
0292
0293
0294
0295 struct list_head dirty;
0296 struct list_head recovering;
0297
0298
0299 struct list_head tracking;
0300
0301
0302
0303 unsigned long last_used;
0304
0305 struct dlm_ctxt *dlm;
0306
0307 unsigned migration_pending:1;
0308 atomic_t asts_reserved;
0309 spinlock_t spinlock;
0310 wait_queue_head_t wq;
0311 u8 owner;
0312 u16 state;
0313 char lvb[DLM_LVB_LEN];
0314 unsigned int inflight_locks;
0315 unsigned int inflight_assert_workers;
0316 unsigned long refmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
0317 };
0318
0319 struct dlm_migratable_lock
0320 {
0321 __be64 cookie;
0322
0323
0324
0325 __be16 pad1;
0326 u8 list;
0327 u8 flags;
0328
0329 s8 type;
0330 s8 convert_type;
0331 s8 highest_blocked;
0332 u8 node;
0333 };
0334
0335 struct dlm_lock
0336 {
0337 struct dlm_migratable_lock ml;
0338
0339 struct list_head list;
0340 struct list_head ast_list;
0341 struct list_head bast_list;
0342 struct dlm_lock_resource *lockres;
0343 spinlock_t spinlock;
0344 struct kref lock_refs;
0345
0346
0347 dlm_astlockfunc_t *ast;
0348 dlm_bastlockfunc_t *bast;
0349 void *astdata;
0350 struct dlm_lockstatus *lksb;
0351 unsigned ast_pending:1,
0352 bast_pending:1,
0353 convert_pending:1,
0354 lock_pending:1,
0355 cancel_pending:1,
0356 unlock_pending:1,
0357 lksb_kernel_allocated:1;
0358 };
0359
0360 enum dlm_lockres_list {
0361 DLM_GRANTED_LIST = 0,
0362 DLM_CONVERTING_LIST = 1,
0363 DLM_BLOCKED_LIST = 2,
0364 };
0365
0366 static inline int dlm_lvb_is_empty(char *lvb)
0367 {
0368 int i;
0369 for (i=0; i<DLM_LVB_LEN; i++)
0370 if (lvb[i])
0371 return 0;
0372 return 1;
0373 }
0374
0375 static inline char *dlm_list_in_text(enum dlm_lockres_list idx)
0376 {
0377 if (idx == DLM_GRANTED_LIST)
0378 return "granted";
0379 else if (idx == DLM_CONVERTING_LIST)
0380 return "converting";
0381 else if (idx == DLM_BLOCKED_LIST)
0382 return "blocked";
0383 else
0384 return "unknown";
0385 }
0386
0387 static inline struct list_head *
0388 dlm_list_idx_to_ptr(struct dlm_lock_resource *res, enum dlm_lockres_list idx)
0389 {
0390 struct list_head *ret = NULL;
0391 if (idx == DLM_GRANTED_LIST)
0392 ret = &res->granted;
0393 else if (idx == DLM_CONVERTING_LIST)
0394 ret = &res->converting;
0395 else if (idx == DLM_BLOCKED_LIST)
0396 ret = &res->blocked;
0397 else
0398 BUG();
0399 return ret;
0400 }
0401
0402
0403
0404
0405 struct dlm_node_iter
0406 {
0407 unsigned long node_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
0408 int curnode;
0409 };
0410
0411
0412 enum {
0413 DLM_MASTER_REQUEST_MSG = 500,
0414 DLM_UNUSED_MSG1 = 501,
0415 DLM_ASSERT_MASTER_MSG = 502,
0416 DLM_CREATE_LOCK_MSG = 503,
0417 DLM_CONVERT_LOCK_MSG = 504,
0418 DLM_PROXY_AST_MSG = 505,
0419 DLM_UNLOCK_LOCK_MSG = 506,
0420 DLM_DEREF_LOCKRES_MSG = 507,
0421 DLM_MIGRATE_REQUEST_MSG = 508,
0422 DLM_MIG_LOCKRES_MSG = 509,
0423 DLM_QUERY_JOIN_MSG = 510,
0424 DLM_ASSERT_JOINED_MSG = 511,
0425 DLM_CANCEL_JOIN_MSG = 512,
0426 DLM_EXIT_DOMAIN_MSG = 513,
0427 DLM_MASTER_REQUERY_MSG = 514,
0428 DLM_LOCK_REQUEST_MSG = 515,
0429 DLM_RECO_DATA_DONE_MSG = 516,
0430 DLM_BEGIN_RECO_MSG = 517,
0431 DLM_FINALIZE_RECO_MSG = 518,
0432 DLM_QUERY_REGION = 519,
0433 DLM_QUERY_NODEINFO = 520,
0434 DLM_BEGIN_EXIT_DOMAIN_MSG = 521,
0435 DLM_DEREF_LOCKRES_DONE = 522,
0436 };
0437
0438 struct dlm_reco_node_data
0439 {
0440 int state;
0441 u8 node_num;
0442 struct list_head list;
0443 };
0444
0445 enum {
0446 DLM_RECO_NODE_DATA_DEAD = -1,
0447 DLM_RECO_NODE_DATA_INIT = 0,
0448 DLM_RECO_NODE_DATA_REQUESTING = 1,
0449 DLM_RECO_NODE_DATA_REQUESTED = 2,
0450 DLM_RECO_NODE_DATA_RECEIVING = 3,
0451 DLM_RECO_NODE_DATA_DONE = 4,
0452 DLM_RECO_NODE_DATA_FINALIZE_SENT = 5,
0453 };
0454
0455
0456 enum {
0457 DLM_MASTER_RESP_NO = 0,
0458 DLM_MASTER_RESP_YES = 1,
0459 DLM_MASTER_RESP_MAYBE = 2,
0460 DLM_MASTER_RESP_ERROR = 3,
0461 };
0462
0463
0464 struct dlm_master_request
0465 {
0466 u8 node_idx;
0467 u8 namelen;
0468 __be16 pad1;
0469 __be32 flags;
0470
0471 u8 name[O2NM_MAX_NAME_LEN];
0472 };
0473
0474 #define DLM_ASSERT_RESPONSE_REASSERT 0x00000001
0475 #define DLM_ASSERT_RESPONSE_MASTERY_REF 0x00000002
0476
0477 #define DLM_ASSERT_MASTER_MLE_CLEANUP 0x00000001
0478 #define DLM_ASSERT_MASTER_REQUERY 0x00000002
0479 #define DLM_ASSERT_MASTER_FINISH_MIGRATION 0x00000004
0480 struct dlm_assert_master
0481 {
0482 u8 node_idx;
0483 u8 namelen;
0484 __be16 pad1;
0485 __be32 flags;
0486
0487 u8 name[O2NM_MAX_NAME_LEN];
0488 };
0489
0490 #define DLM_MIGRATE_RESPONSE_MASTERY_REF 0x00000001
0491
0492 struct dlm_migrate_request
0493 {
0494 u8 master;
0495 u8 new_master;
0496 u8 namelen;
0497 u8 pad1;
0498 __be32 pad2;
0499 u8 name[O2NM_MAX_NAME_LEN];
0500 };
0501
0502 struct dlm_master_requery
0503 {
0504 u8 pad1;
0505 u8 pad2;
0506 u8 node_idx;
0507 u8 namelen;
0508 __be32 pad3;
0509 u8 name[O2NM_MAX_NAME_LEN];
0510 };
0511
0512 #define DLM_MRES_RECOVERY 0x01
0513 #define DLM_MRES_MIGRATION 0x02
0514 #define DLM_MRES_ALL_DONE 0x04
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546 #define DLM_MAX_MIGRATABLE_LOCKS 240
0547
0548 struct dlm_migratable_lockres
0549 {
0550 u8 master;
0551 u8 lockname_len;
0552 u8 num_locks;
0553 u8 flags;
0554 __be32 total_locks;
0555 __be64 mig_cookie;
0556
0557
0558 u8 lockname[DLM_LOCKID_NAME_MAX];
0559
0560 u8 lvb[DLM_LVB_LEN];
0561
0562 struct dlm_migratable_lock ml[];
0563 };
0564 #define DLM_MIG_LOCKRES_MAX_LEN \
0565 (sizeof(struct dlm_migratable_lockres) + \
0566 (sizeof(struct dlm_migratable_lock) * \
0567 DLM_MAX_MIGRATABLE_LOCKS) )
0568
0569
0570
0571 #define DLM_MIG_LOCKRES_RESERVED (O2NET_MAX_PAYLOAD_BYTES - \
0572 DLM_MIG_LOCKRES_MAX_LEN)
0573
0574 struct dlm_create_lock
0575 {
0576 __be64 cookie;
0577
0578 __be32 flags;
0579 u8 pad1;
0580 u8 node_idx;
0581 s8 requested_type;
0582 u8 namelen;
0583
0584 u8 name[O2NM_MAX_NAME_LEN];
0585 };
0586
0587 struct dlm_convert_lock
0588 {
0589 __be64 cookie;
0590
0591 __be32 flags;
0592 u8 pad1;
0593 u8 node_idx;
0594 s8 requested_type;
0595 u8 namelen;
0596
0597 u8 name[O2NM_MAX_NAME_LEN];
0598
0599 s8 lvb[];
0600 };
0601 #define DLM_CONVERT_LOCK_MAX_LEN (sizeof(struct dlm_convert_lock)+DLM_LVB_LEN)
0602
0603 struct dlm_unlock_lock
0604 {
0605 __be64 cookie;
0606
0607 __be32 flags;
0608 __be16 pad1;
0609 u8 node_idx;
0610 u8 namelen;
0611
0612 u8 name[O2NM_MAX_NAME_LEN];
0613
0614 s8 lvb[];
0615 };
0616 #define DLM_UNLOCK_LOCK_MAX_LEN (sizeof(struct dlm_unlock_lock)+DLM_LVB_LEN)
0617
0618 struct dlm_proxy_ast
0619 {
0620 __be64 cookie;
0621
0622 __be32 flags;
0623 u8 node_idx;
0624 u8 type;
0625 u8 blocked_type;
0626 u8 namelen;
0627
0628 u8 name[O2NM_MAX_NAME_LEN];
0629
0630 s8 lvb[];
0631 };
0632 #define DLM_PROXY_AST_MAX_LEN (sizeof(struct dlm_proxy_ast)+DLM_LVB_LEN)
0633
0634 #define DLM_MOD_KEY (0x666c6172)
0635 enum dlm_query_join_response_code {
0636 JOIN_DISALLOW = 0,
0637 JOIN_OK = 1,
0638 JOIN_OK_NO_MAP = 2,
0639 JOIN_PROTOCOL_MISMATCH = 3,
0640 };
0641
0642 struct dlm_query_join_packet {
0643 u8 code;
0644
0645 u8 dlm_minor;
0646
0647 u8 fs_minor;
0648
0649 u8 reserved;
0650 };
0651
0652 union dlm_query_join_response {
0653 __be32 intval;
0654 struct dlm_query_join_packet packet;
0655 };
0656
0657 struct dlm_lock_request
0658 {
0659 u8 node_idx;
0660 u8 dead_node;
0661 __be16 pad1;
0662 __be32 pad2;
0663 };
0664
0665 struct dlm_reco_data_done
0666 {
0667 u8 node_idx;
0668 u8 dead_node;
0669 __be16 pad1;
0670 __be32 pad2;
0671
0672
0673
0674
0675 u8 reco_lvb[DLM_LVB_LEN];
0676 };
0677
0678 struct dlm_begin_reco
0679 {
0680 u8 node_idx;
0681 u8 dead_node;
0682 __be16 pad1;
0683 __be32 pad2;
0684 };
0685
0686 struct dlm_query_join_request
0687 {
0688 u8 node_idx;
0689 u8 pad1[2];
0690 u8 name_len;
0691 struct dlm_protocol_version dlm_proto;
0692 struct dlm_protocol_version fs_proto;
0693 u8 domain[O2NM_MAX_NAME_LEN];
0694 u8 node_map[BITS_TO_BYTES(O2NM_MAX_NODES)];
0695 };
0696
0697 struct dlm_assert_joined
0698 {
0699 u8 node_idx;
0700 u8 pad1[2];
0701 u8 name_len;
0702 u8 domain[O2NM_MAX_NAME_LEN];
0703 };
0704
0705 struct dlm_cancel_join
0706 {
0707 u8 node_idx;
0708 u8 pad1[2];
0709 u8 name_len;
0710 u8 domain[O2NM_MAX_NAME_LEN];
0711 };
0712
0713 struct dlm_query_region {
0714 u8 qr_node;
0715 u8 qr_numregions;
0716 u8 qr_namelen;
0717 u8 pad1;
0718 u8 qr_domain[O2NM_MAX_NAME_LEN];
0719 u8 qr_regions[O2HB_MAX_REGION_NAME_LEN * O2NM_MAX_REGIONS];
0720 };
0721
0722 struct dlm_node_info {
0723 u8 ni_nodenum;
0724 u8 pad1;
0725 __be16 ni_ipv4_port;
0726 __be32 ni_ipv4_address;
0727 };
0728
0729 struct dlm_query_nodeinfo {
0730 u8 qn_nodenum;
0731 u8 qn_numnodes;
0732 u8 qn_namelen;
0733 u8 pad1;
0734 u8 qn_domain[O2NM_MAX_NAME_LEN];
0735 struct dlm_node_info qn_nodes[O2NM_MAX_NODES];
0736 };
0737
0738 struct dlm_exit_domain
0739 {
0740 u8 node_idx;
0741 u8 pad1[3];
0742 };
0743
0744 struct dlm_finalize_reco
0745 {
0746 u8 node_idx;
0747 u8 dead_node;
0748 u8 flags;
0749 u8 pad1;
0750 __be32 pad2;
0751 };
0752
0753 struct dlm_deref_lockres
0754 {
0755 u32 pad1;
0756 u16 pad2;
0757 u8 node_idx;
0758 u8 namelen;
0759
0760 u8 name[O2NM_MAX_NAME_LEN];
0761 };
0762
0763 enum {
0764 DLM_DEREF_RESPONSE_DONE = 0,
0765 DLM_DEREF_RESPONSE_INPROG = 1,
0766 };
0767
0768 struct dlm_deref_lockres_done {
0769 u32 pad1;
0770 u16 pad2;
0771 u8 node_idx;
0772 u8 namelen;
0773
0774 u8 name[O2NM_MAX_NAME_LEN];
0775 };
0776
0777 static inline enum dlm_status
0778 __dlm_lockres_state_to_status(struct dlm_lock_resource *res)
0779 {
0780 enum dlm_status status = DLM_NORMAL;
0781
0782 assert_spin_locked(&res->spinlock);
0783
0784 if (res->state & (DLM_LOCK_RES_RECOVERING|
0785 DLM_LOCK_RES_RECOVERY_WAITING))
0786 status = DLM_RECOVERING;
0787 else if (res->state & DLM_LOCK_RES_MIGRATING)
0788 status = DLM_MIGRATING;
0789 else if (res->state & DLM_LOCK_RES_IN_PROGRESS)
0790 status = DLM_FORWARD;
0791
0792 return status;
0793 }
0794
0795 static inline u8 dlm_get_lock_cookie_node(u64 cookie)
0796 {
0797 u8 ret;
0798 cookie >>= 56;
0799 ret = (u8)(cookie & 0xffULL);
0800 return ret;
0801 }
0802
0803 static inline unsigned long long dlm_get_lock_cookie_seq(u64 cookie)
0804 {
0805 unsigned long long ret;
0806 ret = ((unsigned long long)cookie) & 0x00ffffffffffffffULL;
0807 return ret;
0808 }
0809
0810 struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie,
0811 struct dlm_lockstatus *lksb);
0812 void dlm_lock_get(struct dlm_lock *lock);
0813 void dlm_lock_put(struct dlm_lock *lock);
0814
0815 void dlm_lock_attach_lockres(struct dlm_lock *lock,
0816 struct dlm_lock_resource *res);
0817
0818 int dlm_create_lock_handler(struct o2net_msg *msg, u32 len, void *data,
0819 void **ret_data);
0820 int dlm_convert_lock_handler(struct o2net_msg *msg, u32 len, void *data,
0821 void **ret_data);
0822 int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data,
0823 void **ret_data);
0824
0825 void dlm_revert_pending_convert(struct dlm_lock_resource *res,
0826 struct dlm_lock *lock);
0827 void dlm_revert_pending_lock(struct dlm_lock_resource *res,
0828 struct dlm_lock *lock);
0829
0830 int dlm_unlock_lock_handler(struct o2net_msg *msg, u32 len, void *data,
0831 void **ret_data);
0832 void dlm_commit_pending_cancel(struct dlm_lock_resource *res,
0833 struct dlm_lock *lock);
0834 void dlm_commit_pending_unlock(struct dlm_lock_resource *res,
0835 struct dlm_lock *lock);
0836
0837 int dlm_launch_thread(struct dlm_ctxt *dlm);
0838 void dlm_complete_thread(struct dlm_ctxt *dlm);
0839 int dlm_launch_recovery_thread(struct dlm_ctxt *dlm);
0840 void dlm_complete_recovery_thread(struct dlm_ctxt *dlm);
0841 void dlm_wait_for_recovery(struct dlm_ctxt *dlm);
0842 void dlm_kick_recovery_thread(struct dlm_ctxt *dlm);
0843 int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node);
0844 void dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout);
0845 void dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout);
0846
0847 void dlm_put(struct dlm_ctxt *dlm);
0848 struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm);
0849 int dlm_domain_fully_joined(struct dlm_ctxt *dlm);
0850
0851 void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
0852 struct dlm_lock_resource *res);
0853 void dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
0854 struct dlm_lock_resource *res);
0855 static inline void dlm_lockres_get(struct dlm_lock_resource *res)
0856 {
0857
0858
0859 kref_get(&res->refs);
0860 }
0861 void dlm_lockres_put(struct dlm_lock_resource *res);
0862 void __dlm_unhash_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
0863 void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
0864 struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm,
0865 const char *name,
0866 unsigned int len,
0867 unsigned int hash);
0868 struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm,
0869 const char *name,
0870 unsigned int len,
0871 unsigned int hash);
0872 struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm,
0873 const char *name,
0874 unsigned int len);
0875
0876 int dlm_is_host_down(int errno);
0877
0878 struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
0879 const char *lockid,
0880 int namelen,
0881 int flags);
0882 struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
0883 const char *name,
0884 unsigned int namelen);
0885
0886 void dlm_lockres_set_refmap_bit(struct dlm_ctxt *dlm,
0887 struct dlm_lock_resource *res, int bit);
0888 void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm,
0889 struct dlm_lock_resource *res, int bit);
0890
0891 void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
0892 struct dlm_lock_resource *res);
0893 void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
0894 struct dlm_lock_resource *res);
0895
0896 void __dlm_lockres_grab_inflight_worker(struct dlm_ctxt *dlm,
0897 struct dlm_lock_resource *res);
0898
0899 void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
0900 void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
0901 void __dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
0902 void dlm_do_local_ast(struct dlm_ctxt *dlm,
0903 struct dlm_lock_resource *res,
0904 struct dlm_lock *lock);
0905 int dlm_do_remote_ast(struct dlm_ctxt *dlm,
0906 struct dlm_lock_resource *res,
0907 struct dlm_lock *lock);
0908 void dlm_do_local_bast(struct dlm_ctxt *dlm,
0909 struct dlm_lock_resource *res,
0910 struct dlm_lock *lock,
0911 int blocked_type);
0912 int dlm_send_proxy_ast_msg(struct dlm_ctxt *dlm,
0913 struct dlm_lock_resource *res,
0914 struct dlm_lock *lock,
0915 int msg_type,
0916 int blocked_type, int flags);
0917 static inline int dlm_send_proxy_bast(struct dlm_ctxt *dlm,
0918 struct dlm_lock_resource *res,
0919 struct dlm_lock *lock,
0920 int blocked_type)
0921 {
0922 return dlm_send_proxy_ast_msg(dlm, res, lock, DLM_BAST,
0923 blocked_type, 0);
0924 }
0925
0926 static inline int dlm_send_proxy_ast(struct dlm_ctxt *dlm,
0927 struct dlm_lock_resource *res,
0928 struct dlm_lock *lock,
0929 int flags)
0930 {
0931 return dlm_send_proxy_ast_msg(dlm, res, lock, DLM_AST,
0932 0, flags);
0933 }
0934
0935 void dlm_print_one_lock_resource(struct dlm_lock_resource *res);
0936 void __dlm_print_one_lock_resource(struct dlm_lock_resource *res);
0937
0938 void dlm_kick_thread(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
0939 void __dlm_dirty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
0940
0941
0942 void dlm_hb_node_down_cb(struct o2nm_node *node, int idx, void *data);
0943 void dlm_hb_node_up_cb(struct o2nm_node *node, int idx, void *data);
0944
0945 int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
0946 int dlm_finish_migration(struct dlm_ctxt *dlm,
0947 struct dlm_lock_resource *res,
0948 u8 old_master);
0949 void dlm_lockres_release_ast(struct dlm_ctxt *dlm,
0950 struct dlm_lock_resource *res);
0951 void __dlm_lockres_reserve_ast(struct dlm_lock_resource *res);
0952
0953 int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data,
0954 void **ret_data);
0955 int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
0956 void **ret_data);
0957 void dlm_assert_master_post_handler(int status, void *data, void *ret_data);
0958 int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
0959 void **ret_data);
0960 int dlm_deref_lockres_done_handler(struct o2net_msg *msg, u32 len, void *data,
0961 void **ret_data);
0962 int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data,
0963 void **ret_data);
0964 int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
0965 void **ret_data);
0966 int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data,
0967 void **ret_data);
0968 int dlm_request_all_locks_handler(struct o2net_msg *msg, u32 len, void *data,
0969 void **ret_data);
0970 int dlm_reco_data_done_handler(struct o2net_msg *msg, u32 len, void *data,
0971 void **ret_data);
0972 int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data,
0973 void **ret_data);
0974 int dlm_finalize_reco_handler(struct o2net_msg *msg, u32 len, void *data,
0975 void **ret_data);
0976 int dlm_do_master_requery(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
0977 u8 nodenum, u8 *real_master);
0978
0979 void __dlm_do_purge_lockres(struct dlm_ctxt *dlm,
0980 struct dlm_lock_resource *res);
0981
0982 int dlm_dispatch_assert_master(struct dlm_ctxt *dlm,
0983 struct dlm_lock_resource *res,
0984 int ignore_higher,
0985 u8 request_from,
0986 u32 flags);
0987
0988
0989 int dlm_send_one_lockres(struct dlm_ctxt *dlm,
0990 struct dlm_lock_resource *res,
0991 struct dlm_migratable_lockres *mres,
0992 u8 send_to,
0993 u8 flags);
0994 void dlm_move_lockres_to_recovery_list(struct dlm_ctxt *dlm,
0995 struct dlm_lock_resource *res);
0996
0997
0998 void __dlm_wait_on_lockres_flags(struct dlm_lock_resource *res, int flags);
0999
1000
1001 static inline void __dlm_wait_on_lockres(struct dlm_lock_resource *res)
1002 {
1003 __dlm_wait_on_lockres_flags(res, (DLM_LOCK_RES_IN_PROGRESS|
1004 DLM_LOCK_RES_RECOVERING|
1005 DLM_LOCK_RES_RECOVERY_WAITING|
1006 DLM_LOCK_RES_MIGRATING));
1007 }
1008
1009 void __dlm_unlink_mle(struct dlm_ctxt *dlm, struct dlm_master_list_entry *mle);
1010 void __dlm_insert_mle(struct dlm_ctxt *dlm, struct dlm_master_list_entry *mle);
1011
1012
1013 int dlm_init_master_caches(void);
1014 void dlm_destroy_master_caches(void);
1015
1016 int dlm_init_lock_cache(void);
1017 void dlm_destroy_lock_cache(void);
1018
1019 int dlm_init_mle_cache(void);
1020 void dlm_destroy_mle_cache(void);
1021
1022 void dlm_hb_event_notify_attached(struct dlm_ctxt *dlm, int idx, int node_up);
1023 int dlm_drop_lockres_ref(struct dlm_ctxt *dlm,
1024 struct dlm_lock_resource *res);
1025 void dlm_clean_master_list(struct dlm_ctxt *dlm,
1026 u8 dead_node);
1027 void dlm_force_free_mles(struct dlm_ctxt *dlm);
1028 int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock);
1029 int __dlm_lockres_has_locks(struct dlm_lock_resource *res);
1030 int __dlm_lockres_unused(struct dlm_lock_resource *res);
1031
1032 static inline const char * dlm_lock_mode_name(int mode)
1033 {
1034 switch (mode) {
1035 case LKM_EXMODE:
1036 return "EX";
1037 case LKM_PRMODE:
1038 return "PR";
1039 case LKM_NLMODE:
1040 return "NL";
1041 }
1042 return "UNKNOWN";
1043 }
1044
1045
1046 static inline int dlm_lock_compatible(int existing, int request)
1047 {
1048
1049 if (request == LKM_NLMODE ||
1050 existing == LKM_NLMODE)
1051 return 1;
1052
1053
1054 if (request == LKM_EXMODE)
1055 return 0;
1056
1057
1058 if (existing == LKM_PRMODE)
1059 return 1;
1060
1061 return 0;
1062 }
1063
1064 static inline int dlm_lock_on_list(struct list_head *head,
1065 struct dlm_lock *lock)
1066 {
1067 struct dlm_lock *tmplock;
1068
1069 list_for_each_entry(tmplock, head, list) {
1070 if (tmplock == lock)
1071 return 1;
1072 }
1073 return 0;
1074 }
1075
1076
1077 static inline enum dlm_status dlm_err_to_dlm_status(int err)
1078 {
1079 enum dlm_status ret;
1080 if (err == -ENOMEM)
1081 ret = DLM_SYSERR;
1082 else if (err == -ETIMEDOUT || o2net_link_down(err, NULL))
1083 ret = DLM_NOLOCKMGR;
1084 else if (err == -EINVAL)
1085 ret = DLM_BADPARAM;
1086 else if (err == -ENAMETOOLONG)
1087 ret = DLM_IVBUFLEN;
1088 else
1089 ret = DLM_BADARGS;
1090 return ret;
1091 }
1092
1093
1094 static inline void dlm_node_iter_init(unsigned long *map,
1095 struct dlm_node_iter *iter)
1096 {
1097 memcpy(iter->node_map, map, sizeof(iter->node_map));
1098 iter->curnode = -1;
1099 }
1100
1101 static inline int dlm_node_iter_next(struct dlm_node_iter *iter)
1102 {
1103 int bit;
1104 bit = find_next_bit(iter->node_map, O2NM_MAX_NODES, iter->curnode+1);
1105 if (bit >= O2NM_MAX_NODES) {
1106 iter->curnode = O2NM_MAX_NODES;
1107 return -ENOENT;
1108 }
1109 iter->curnode = bit;
1110 return bit;
1111 }
1112
1113 static inline void dlm_set_lockres_owner(struct dlm_ctxt *dlm,
1114 struct dlm_lock_resource *res,
1115 u8 owner)
1116 {
1117 assert_spin_locked(&res->spinlock);
1118
1119 res->owner = owner;
1120 }
1121
1122 static inline void dlm_change_lockres_owner(struct dlm_ctxt *dlm,
1123 struct dlm_lock_resource *res,
1124 u8 owner)
1125 {
1126 assert_spin_locked(&res->spinlock);
1127
1128 if (owner != res->owner)
1129 dlm_set_lockres_owner(dlm, res, owner);
1130 }
1131
1132 #endif