diff options
-rw-r--r-- | fs/ocfs2/dlm/dlmunlock.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index e78657742bd8..3883633e82eb 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c | |||
@@ -90,7 +90,8 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, | |||
90 | enum dlm_status status; | 90 | enum dlm_status status; |
91 | int actions = 0; | 91 | int actions = 0; |
92 | int in_use; | 92 | int in_use; |
93 | u8 owner; | 93 | u8 owner; |
94 | int recovery_wait = 0; | ||
94 | 95 | ||
95 | mlog(0, "master_node = %d, valblk = %d\n", master_node, | 96 | mlog(0, "master_node = %d, valblk = %d\n", master_node, |
96 | flags & LKM_VALBLK); | 97 | flags & LKM_VALBLK); |
@@ -193,9 +194,12 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, | |||
193 | } | 194 | } |
194 | if (flags & LKM_CANCEL) | 195 | if (flags & LKM_CANCEL) |
195 | lock->cancel_pending = 0; | 196 | lock->cancel_pending = 0; |
196 | else | 197 | else { |
197 | lock->unlock_pending = 0; | 198 | if (!lock->unlock_pending) |
198 | 199 | recovery_wait = 1; | |
200 | else | ||
201 | lock->unlock_pending = 0; | ||
202 | } | ||
199 | } | 203 | } |
200 | 204 | ||
201 | /* get an extra ref on lock. if we are just switching | 205 | /* get an extra ref on lock. if we are just switching |
@@ -229,6 +233,17 @@ leave: | |||
229 | spin_unlock(&res->spinlock); | 233 | spin_unlock(&res->spinlock); |
230 | wake_up(&res->wq); | 234 | wake_up(&res->wq); |
231 | 235 | ||
236 | if (recovery_wait) { | ||
237 | spin_lock(&res->spinlock); | ||
238 | /* Unlock request will directly succeed after owner dies, | ||
239 | * and the lock is already removed from grant list. We have to | ||
240 | * wait for RECOVERING done or we miss the chance to purge it | ||
241 | * since the removement is much faster than RECOVERING proc. | ||
242 | */ | ||
243 | __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_RECOVERING); | ||
244 | spin_unlock(&res->spinlock); | ||
245 | } | ||
246 | |||
232 | /* let the caller's final dlm_lock_put handle the actual kfree */ | 247 | /* let the caller's final dlm_lock_put handle the actual kfree */ |
233 | if (actions & DLM_UNLOCK_FREE_LOCK) { | 248 | if (actions & DLM_UNLOCK_FREE_LOCK) { |
234 | /* this should always be coupled with list removal */ | 249 | /* this should always be coupled with list removal */ |