aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2')
-rw-r--r--fs/ocfs2/dlm/dlmlock.c12
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c47
-rw-r--r--fs/ocfs2/dlm/dlmthread.c12
3 files changed, 32 insertions, 39 deletions
diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c
index c7f3e22bda1e..3ef2c1adfb8f 100644
--- a/fs/ocfs2/dlm/dlmlock.c
+++ b/fs/ocfs2/dlm/dlmlock.c
@@ -183,10 +183,6 @@ static enum dlm_status dlmlock_master(struct dlm_ctxt *dlm,
183 kick_thread = 1; 183 kick_thread = 1;
184 } 184 }
185 } 185 }
186 /* reduce the inflight count, this may result in the lockres
187 * being purged below during calc_usage */
188 if (lock->ml.node == dlm->node_num)
189 dlm_lockres_drop_inflight_ref(dlm, res);
190 186
191 spin_unlock(&res->spinlock); 187 spin_unlock(&res->spinlock);
192 wake_up(&res->wq); 188 wake_up(&res->wq);
@@ -737,6 +733,14 @@ retry_lock:
737 } 733 }
738 } 734 }
739 735
736 /* Inflight taken in dlm_get_lock_resource() is dropped here */
737 spin_lock(&res->spinlock);
738 dlm_lockres_drop_inflight_ref(dlm, res);
739 spin_unlock(&res->spinlock);
740
741 dlm_lockres_calc_usage(dlm, res);
742 dlm_kick_thread(dlm, res);
743
740 if (status != DLM_NORMAL) { 744 if (status != DLM_NORMAL) {
741 lock->lksb->flags &= ~DLM_LKSB_GET_LVB; 745 lock->lksb->flags &= ~DLM_LKSB_GET_LVB;
742 if (status != DLM_NOTQUEUED) 746 if (status != DLM_NOTQUEUED)
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 11e446ffb67a..005261c333b0 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -659,11 +659,8 @@ void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
659{ 659{
660 assert_spin_locked(&res->spinlock); 660 assert_spin_locked(&res->spinlock);
661 661
662 if (!test_bit(dlm->node_num, res->refmap)) {
663 BUG_ON(res->inflight_locks != 0);
664 dlm_lockres_set_refmap_bit(dlm, res, dlm->node_num);
665 }
666 res->inflight_locks++; 662 res->inflight_locks++;
663
667 mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name, 664 mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name,
668 res->lockname.len, res->lockname.name, res->inflight_locks, 665 res->lockname.len, res->lockname.name, res->inflight_locks,
669 __builtin_return_address(0)); 666 __builtin_return_address(0));
@@ -677,12 +674,11 @@ void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
677 BUG_ON(res->inflight_locks == 0); 674 BUG_ON(res->inflight_locks == 0);
678 675
679 res->inflight_locks--; 676 res->inflight_locks--;
677
680 mlog(0, "%s: res %.*s, inflight--: now %u, %ps()\n", dlm->name, 678 mlog(0, "%s: res %.*s, inflight--: now %u, %ps()\n", dlm->name,
681 res->lockname.len, res->lockname.name, res->inflight_locks, 679 res->lockname.len, res->lockname.name, res->inflight_locks,
682 __builtin_return_address(0)); 680 __builtin_return_address(0));
683 681
684 if (res->inflight_locks == 0)
685 dlm_lockres_clear_refmap_bit(dlm, res, dlm->node_num);
686 wake_up(&res->wq); 682 wake_up(&res->wq);
687} 683}
688 684
@@ -716,7 +712,6 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
716 unsigned int hash; 712 unsigned int hash;
717 int tries = 0; 713 int tries = 0;
718 int bit, wait_on_recovery = 0; 714 int bit, wait_on_recovery = 0;
719 int drop_inflight_if_nonlocal = 0;
720 715
721 BUG_ON(!lockid); 716 BUG_ON(!lockid);
722 717
@@ -728,36 +723,33 @@ lookup:
728 spin_lock(&dlm->spinlock); 723 spin_lock(&dlm->spinlock);
729 tmpres = __dlm_lookup_lockres_full(dlm, lockid, namelen, hash); 724 tmpres = __dlm_lookup_lockres_full(dlm, lockid, namelen, hash);
730 if (tmpres) { 725 if (tmpres) {
731 int dropping_ref = 0;
732
733 spin_unlock(&dlm->spinlock); 726 spin_unlock(&dlm->spinlock);
734
735 spin_lock(&tmpres->spinlock); 727 spin_lock(&tmpres->spinlock);
736 /* We wait for the other thread that is mastering the resource */ 728 /* Wait on the thread that is mastering the resource */
737 if (tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN) { 729 if (tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
738 __dlm_wait_on_lockres(tmpres); 730 __dlm_wait_on_lockres(tmpres);
739 BUG_ON(tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN); 731 BUG_ON(tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN);
732 spin_unlock(&tmpres->spinlock);
733 dlm_lockres_put(tmpres);
734 tmpres = NULL;
735 goto lookup;
740 } 736 }
741 737
742 if (tmpres->owner == dlm->node_num) { 738 /* Wait on the resource purge to complete before continuing */
743 BUG_ON(tmpres->state & DLM_LOCK_RES_DROPPING_REF); 739 if (tmpres->state & DLM_LOCK_RES_DROPPING_REF) {
744 dlm_lockres_grab_inflight_ref(dlm, tmpres); 740 BUG_ON(tmpres->owner == dlm->node_num);
745 } else if (tmpres->state & DLM_LOCK_RES_DROPPING_REF) 741 __dlm_wait_on_lockres_flags(tmpres,
746 dropping_ref = 1; 742 DLM_LOCK_RES_DROPPING_REF);
747 spin_unlock(&tmpres->spinlock);
748
749 /* wait until done messaging the master, drop our ref to allow
750 * the lockres to be purged, start over. */
751 if (dropping_ref) {
752 spin_lock(&tmpres->spinlock);
753 __dlm_wait_on_lockres_flags(tmpres, DLM_LOCK_RES_DROPPING_REF);
754 spin_unlock(&tmpres->spinlock); 743 spin_unlock(&tmpres->spinlock);
755 dlm_lockres_put(tmpres); 744 dlm_lockres_put(tmpres);
756 tmpres = NULL; 745 tmpres = NULL;
757 goto lookup; 746 goto lookup;
758 } 747 }
759 748
760 mlog(0, "found in hash!\n"); 749 /* Grab inflight ref to pin the resource */
750 dlm_lockres_grab_inflight_ref(dlm, tmpres);
751
752 spin_unlock(&tmpres->spinlock);
761 if (res) 753 if (res)
762 dlm_lockres_put(res); 754 dlm_lockres_put(res);
763 res = tmpres; 755 res = tmpres;
@@ -863,14 +855,11 @@ lookup:
863 /* finally add the lockres to its hash bucket */ 855 /* finally add the lockres to its hash bucket */
864 __dlm_insert_lockres(dlm, res); 856 __dlm_insert_lockres(dlm, res);
865 857
858 /* Grab inflight ref to pin the resource */
866 spin_lock(&res->spinlock); 859 spin_lock(&res->spinlock);
867 dlm_lockres_grab_inflight_ref(dlm, res); 860 dlm_lockres_grab_inflight_ref(dlm, res);
868 spin_unlock(&res->spinlock); 861 spin_unlock(&res->spinlock);
869 862
870 /* if this node does not become the master make sure to drop
871 * this inflight reference below */
872 drop_inflight_if_nonlocal = 1;
873
874 /* get an extra ref on the mle in case this is a BLOCK 863 /* get an extra ref on the mle in case this is a BLOCK
875 * if so, the creator of the BLOCK may try to put the last 864 * if so, the creator of the BLOCK may try to put the last
876 * ref at this time in the assert master handler, so we 865 * ref at this time in the assert master handler, so we
@@ -973,8 +962,6 @@ wait:
973 962
974wake_waiters: 963wake_waiters:
975 spin_lock(&res->spinlock); 964 spin_lock(&res->spinlock);
976 if (res->owner != dlm->node_num && drop_inflight_if_nonlocal)
977 dlm_lockres_drop_inflight_ref(dlm, res);
978 res->state &= ~DLM_LOCK_RES_IN_PROGRESS; 965 res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
979 spin_unlock(&res->spinlock); 966 spin_unlock(&res->spinlock);
980 wake_up(&res->wq); 967 wake_up(&res->wq);
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c
index 4eff65e7e59e..e73c833fc2a1 100644
--- a/fs/ocfs2/dlm/dlmthread.c
+++ b/fs/ocfs2/dlm/dlmthread.c
@@ -94,24 +94,26 @@ int __dlm_lockres_unused(struct dlm_lock_resource *res)
94{ 94{
95 int bit; 95 int bit;
96 96
97 assert_spin_locked(&res->spinlock);
98
97 if (__dlm_lockres_has_locks(res)) 99 if (__dlm_lockres_has_locks(res))
98 return 0; 100 return 0;
99 101
102 /* Locks are in the process of being created */
103 if (res->inflight_locks)
104 return 0;
105
100 if (!list_empty(&res->dirty) || res->state & DLM_LOCK_RES_DIRTY) 106 if (!list_empty(&res->dirty) || res->state & DLM_LOCK_RES_DIRTY)
101 return 0; 107 return 0;
102 108
103 if (res->state & DLM_LOCK_RES_RECOVERING) 109 if (res->state & DLM_LOCK_RES_RECOVERING)
104 return 0; 110 return 0;
105 111
112 /* Another node has this resource with this node as the master */
106 bit = find_next_bit(res->refmap, O2NM_MAX_NODES, 0); 113 bit = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
107 if (bit < O2NM_MAX_NODES) 114 if (bit < O2NM_MAX_NODES)
108 return 0; 115 return 0;
109 116
110 /*
111 * since the bit for dlm->node_num is not set, inflight_locks better
112 * be zero
113 */
114 BUG_ON(res->inflight_locks != 0);
115 return 1; 117 return 1;
116} 118}
117 119