28 #include <linux/module.h>
30 #include <linux/types.h>
33 #include <linux/sysctl.h>
34 #include <linux/random.h>
36 #include <linux/socket.h>
51 #define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_THREAD)
54 static int dlm_thread(
void *
data);
57 #define dlm_lock_is_remote(dlm, lock) ((lock)->ml.node != (dlm)->node_num)
70 if (res->
state & flags) {
82 if (list_empty(&res->
granted) &&
131 if (list_empty(&res->
purge)) {
132 mlog(0,
"%s: Adding res %.*s to purge list\n",
136 dlm_lockres_get(res);
140 }
else if (!list_empty(&res->
purge)) {
141 mlog(0,
"%s: Removing res %.*s from purge list\n",
144 list_del_init(&res->
purge);
162 static void dlm_purge_lockres(
struct dlm_ctxt *
dlm,
173 mlog(0,
"%s: Purging res %.*s, master %d\n", dlm->
name,
197 if (!list_empty(&res->
purge)) {
198 mlog(0,
"%s: Removing res %.*s from purgelist, master %d\n",
200 list_del_init(&res->
purge);
224 static void dlm_run_purge_list(
struct dlm_ctxt *dlm,
227 unsigned int run_max,
unused;
228 unsigned long purge_jiffies;
234 while(run_max && !list_empty(&dlm->
purge_list)) {
247 if (!purge_now &&
time_after(purge_jiffies, jiffies)) {
263 mlog(0,
"%s: res %.*s is in use or being remastered, "
264 "used %d, state %d\n", dlm->
name,
266 !unused, lockres->
state);
272 dlm_lockres_get(lockres);
274 dlm_purge_lockres(dlm, lockres);
285 static void dlm_shuffle_lists(
struct dlm_ctxt *dlm,
308 mlog(0,
"%s: res %.*s has locks on the convert queue\n", dlm->
name,
313 mlog(
ML_ERROR,
"%s: res %.*s converting lock to invalid mode\n",
322 if (!dlm_lock_compatible(lock->
ml.type,
323 target->
ml.convert_type)) {
331 if (lock->
ml.highest_blocked < target->
ml.convert_type)
332 lock->
ml.highest_blocked =
333 target->
ml.convert_type;
341 if (!dlm_lock_compatible(lock->
ml.type,
342 target->
ml.convert_type)) {
348 if (lock->
ml.highest_blocked < target->
ml.convert_type)
349 lock->
ml.highest_blocked =
350 target->
ml.convert_type;
359 mlog(0,
"%s: res %.*s, AST for Converting lock %u:%llu, type "
365 target->
ml.convert_type, target->
ml.node);
367 target->
ml.type = target->
ml.convert_type;
392 if (!dlm_lock_compatible(lock->
ml.type, target->
ml.type)) {
398 if (lock->
ml.highest_blocked < target->
ml.type)
399 lock->
ml.highest_blocked = target->
ml.type;
408 if (!dlm_lock_compatible(lock->
ml.type, target->
ml.type)) {
414 if (lock->
ml.highest_blocked < target->
ml.type)
415 lock->
ml.highest_blocked = target->
ml.type;
425 mlog(0,
"%s: res %.*s, AST for Blocked lock %u:%llu, type %d, "
430 target->
ml.type, target->
ml.node);
474 if (list_empty(&res->
dirty)) {
476 dlm_lockres_get(res);
490 mlog(0,
"Starting dlm_thread...\n");
511 static int dlm_dirty_list_empty(
struct dlm_ctxt *dlm)
522 static void dlm_flush_asts(
struct dlm_ctxt *dlm)
536 mlog(0,
"%s: res %.*s, Flush AST for lock %u:%llu, type %d, "
541 lock->
ml.type, lock->
ml.node);
562 mlog(0,
"%s: res %.*s, AST queued while flushing last "
586 hi = lock->
ml.highest_blocked;
595 mlog(0,
"%s: res %.*s, Flush BAST for lock %u:%llu, "
596 "blocked %d, node %u\n",
603 ret = dlm_send_proxy_bast(dlm, res, lock, hi);
614 mlog(0,
"%s: res %.*s, BAST queued while flushing last "
630 #define DLM_THREAD_TIMEOUT_MS (4 * 1000)
631 #define DLM_THREAD_MAX_DIRTY 100
632 #define DLM_THREAD_MAX_ASTS 10
634 static int dlm_thread(
void *
data)
640 mlog(0,
"dlm thread running for %s...\n", dlm->
name);
667 dlm_lockres_get(res);
671 list_del_init(&res->
dirty);
685 " dirty %d\n", dlm->
name,
703 mlog(0,
"%s: res %.*s, inprogress, delay list "
704 "shuffle, state %d\n", dlm->
name,
717 dlm_shuffle_lists(dlm, res);
739 mlog(0,
"%s: Throttling dlm thread\n",
755 !dlm_dirty_list_empty(dlm) ||
760 mlog(0,
"quitting DLM thread\n");