aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/dlm/dlmthread.c
diff options
context:
space:
mode:
authorKurt Hackel <kurt.hackel@oracle.com>2007-01-05 18:00:17 -0500
committerMark Fasheh <mark.fasheh@oracle.com>2007-02-07 15:00:57 -0500
commitddc09c8ddac8d0f170ba8caa8128801f358dccff (patch)
treebba638e3017266b87e165eb0312d0671164f8917 /fs/ocfs2/dlm/dlmthread.c
parentfaf0ec9f13defb57f4269ecb22ed86f2874ee89a (diff)
ocfs2_dlm: Fixes race between migrate and dirty
dlmthread was removing lockres' from the dirty list and resetting the dirty flag before shuffling the list. This patch retains the dirty state flag until the lists are shuffled. Signed-off-by: Kurt Hackel <kurt.hackel@oracle.com> Signed-off-by: Sunil Mushran <Sunil.Mushran@oracle.com> Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/dlm/dlmthread.c')
-rw-r--r--fs/ocfs2/dlm/dlmthread.c30
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)
95int __dlm_lockres_unused(struct dlm_lock_resource *res) 95int __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);