diff options
Diffstat (limited to 'fs/ocfs2/dlm/dlmthread.c')
-rw-r--r-- | fs/ocfs2/dlm/dlmthread.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index baa99979904c..3b94e4dec351 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
@@ -95,7 +95,7 @@ int __dlm_lockres_has_locks(struct dlm_lock_resource *res) | |||
95 | int __dlm_lockres_unused(struct dlm_lock_resource *res) | 95 | int __dlm_lockres_unused(struct dlm_lock_resource *res) |
96 | { | 96 | { |
97 | if (!__dlm_lockres_has_locks(res) && | 97 | if (!__dlm_lockres_has_locks(res) && |
98 | list_empty(&res->dirty)) { | 98 | (list_empty(&res->dirty) && !(res->state & DLM_LOCK_RES_DIRTY))) { |
99 | /* try not to scan the bitmap unless the first two | 99 | /* try not to scan the bitmap unless the first two |
100 | * conditions are already true */ | 100 | * conditions are already true */ |
101 | int bit = find_next_bit(res->refmap, O2NM_MAX_NODES, 0); | 101 | int bit = find_next_bit(res->refmap, O2NM_MAX_NODES, 0); |
@@ -455,12 +455,17 @@ void __dlm_dirty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) | |||
455 | assert_spin_locked(&res->spinlock); | 455 | assert_spin_locked(&res->spinlock); |
456 | 456 | ||
457 | /* don't shuffle secondary queues */ | 457 | /* don't shuffle secondary queues */ |
458 | if ((res->owner == dlm->node_num) && | 458 | if ((res->owner == dlm->node_num)) { |
459 | !(res->state & DLM_LOCK_RES_DIRTY)) { | 459 | if (res->state & (DLM_LOCK_RES_MIGRATING | |
460 | /* ref for dirty_list */ | 460 | DLM_LOCK_RES_BLOCK_DIRTY)) |
461 | dlm_lockres_get(res); | 461 | return; |
462 | list_add_tail(&res->dirty, &dlm->dirty_list); | 462 | |
463 | res->state |= DLM_LOCK_RES_DIRTY; | 463 | if (list_empty(&res->dirty)) { |
464 | /* ref for dirty_list */ | ||
465 | dlm_lockres_get(res); | ||
466 | list_add_tail(&res->dirty, &dlm->dirty_list); | ||
467 | res->state |= DLM_LOCK_RES_DIRTY; | ||
468 | } | ||
464 | } | 469 | } |
465 | } | 470 | } |
466 | 471 | ||
@@ -639,7 +644,7 @@ static int dlm_thread(void *data) | |||
639 | dlm_lockres_get(res); | 644 | dlm_lockres_get(res); |
640 | 645 | ||
641 | spin_lock(&res->spinlock); | 646 | spin_lock(&res->spinlock); |
642 | res->state &= ~DLM_LOCK_RES_DIRTY; | 647 | /* We clear the DLM_LOCK_RES_DIRTY state once we shuffle lists below */ |
643 | list_del_init(&res->dirty); | 648 | list_del_init(&res->dirty); |
644 | spin_unlock(&res->spinlock); | 649 | spin_unlock(&res->spinlock); |
645 | spin_unlock(&dlm->spinlock); | 650 | spin_unlock(&dlm->spinlock); |
@@ -663,10 +668,11 @@ static int dlm_thread(void *data) | |||
663 | /* it is now ok to move lockreses in these states | 668 | /* it is now ok to move lockreses in these states |
664 | * to the dirty list, assuming that they will only be | 669 | * to the dirty list, assuming that they will only be |
665 | * dirty for a short while. */ | 670 | * dirty for a short while. */ |
671 | BUG_ON(res->state & DLM_LOCK_RES_MIGRATING); | ||
666 | if (res->state & (DLM_LOCK_RES_IN_PROGRESS | | 672 | if (res->state & (DLM_LOCK_RES_IN_PROGRESS | |
667 | DLM_LOCK_RES_MIGRATING | | ||
668 | DLM_LOCK_RES_RECOVERING)) { | 673 | DLM_LOCK_RES_RECOVERING)) { |
669 | /* move it to the tail and keep going */ | 674 | /* move it to the tail and keep going */ |
675 | res->state &= ~DLM_LOCK_RES_DIRTY; | ||
670 | spin_unlock(&res->spinlock); | 676 | spin_unlock(&res->spinlock); |
671 | mlog(0, "delaying list shuffling for in-" | 677 | mlog(0, "delaying list shuffling for in-" |
672 | "progress lockres %.*s, state=%d\n", | 678 | "progress lockres %.*s, state=%d\n", |
@@ -687,6 +693,7 @@ static int dlm_thread(void *data) | |||
687 | 693 | ||
688 | /* called while holding lockres lock */ | 694 | /* called while holding lockres lock */ |
689 | dlm_shuffle_lists(dlm, res); | 695 | dlm_shuffle_lists(dlm, res); |
696 | res->state &= ~DLM_LOCK_RES_DIRTY; | ||
690 | spin_unlock(&res->spinlock); | 697 | spin_unlock(&res->spinlock); |
691 | 698 | ||
692 | dlm_lockres_calc_usage(dlm, res); | 699 | dlm_lockres_calc_usage(dlm, res); |
@@ -697,11 +704,8 @@ in_progress: | |||
697 | /* if the lock was in-progress, stick | 704 | /* if the lock was in-progress, stick |
698 | * it on the back of the list */ | 705 | * it on the back of the list */ |
699 | if (delay) { | 706 | if (delay) { |
700 | /* ref for dirty_list */ | ||
701 | dlm_lockres_get(res); | ||
702 | spin_lock(&res->spinlock); | 707 | spin_lock(&res->spinlock); |
703 | list_add_tail(&res->dirty, &dlm->dirty_list); | 708 | __dlm_dirty_lockres(dlm, res); |
704 | res->state |= DLM_LOCK_RES_DIRTY; | ||
705 | spin_unlock(&res->spinlock); | 709 | spin_unlock(&res->spinlock); |
706 | } | 710 | } |
707 | dlm_lockres_put(res); | 711 | dlm_lockres_put(res); |