diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/dlm/userdlm.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/fs/ocfs2/dlm/userdlm.c b/fs/ocfs2/dlm/userdlm.c index c3764f4744ee..bac4615965f6 100644 --- a/fs/ocfs2/dlm/userdlm.c +++ b/fs/ocfs2/dlm/userdlm.c | |||
@@ -268,13 +268,26 @@ static void user_dlm_unblock_lock(void *opaque) | |||
268 | 268 | ||
269 | spin_lock(&lockres->l_lock); | 269 | spin_lock(&lockres->l_lock); |
270 | 270 | ||
271 | BUG_ON(!(lockres->l_flags & USER_LOCK_BLOCKED)); | 271 | mlog_bug_on_msg(!(lockres->l_flags & USER_LOCK_QUEUED), |
272 | BUG_ON(!(lockres->l_flags & USER_LOCK_QUEUED)); | 272 | "Lockres %s, flags 0x%x\n", |
273 | lockres->l_name, lockres->l_flags); | ||
273 | 274 | ||
274 | /* notice that we don't clear USER_LOCK_BLOCKED here. That's | 275 | /* notice that we don't clear USER_LOCK_BLOCKED here. If it's |
275 | * for user_ast to do. */ | 276 | * set, we want user_ast clear it. */ |
276 | lockres->l_flags &= ~USER_LOCK_QUEUED; | 277 | lockres->l_flags &= ~USER_LOCK_QUEUED; |
277 | 278 | ||
279 | /* It's valid to get here and no longer be blocked - if we get | ||
280 | * several basts in a row, we might be queued by the first | ||
281 | * one, the unblock thread might run and clear the queued | ||
282 | * flag, and finally we might get another bast which re-queues | ||
283 | * us before our ast for the downconvert is called. */ | ||
284 | if (!(lockres->l_flags & USER_LOCK_BLOCKED)) { | ||
285 | mlog(0, "Lockres %s, flags 0x%x: queued but not blocking\n", | ||
286 | lockres->l_name, lockres->l_flags); | ||
287 | spin_unlock(&lockres->l_lock); | ||
288 | goto drop_ref; | ||
289 | } | ||
290 | |||
278 | if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { | 291 | if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { |
279 | mlog(0, "lock is in teardown so we do nothing\n"); | 292 | mlog(0, "lock is in teardown so we do nothing\n"); |
280 | spin_unlock(&lockres->l_lock); | 293 | spin_unlock(&lockres->l_lock); |