diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2006-03-29 19:49:13 -0500 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2006-04-07 20:39:43 -0400 |
commit | 2cd9888590c52ac7592e3607d0a3174ccd57ef86 (patch) | |
tree | 3f8ddf8bb0bb4cf1532707d613412cb98ffd9823 | |
parent | f43e6918c0e3906fd4483316f6a1a07bba615908 (diff) |
ocfs2: test and set teardown flag early in user_dlm_destroy_lock()
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
-rw-r--r-- | fs/ocfs2/dlm/userdlm.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/ocfs2/dlm/userdlm.c b/fs/ocfs2/dlm/userdlm.c index 808ec0527c75..74ca4e5f9765 100644 --- a/fs/ocfs2/dlm/userdlm.c +++ b/fs/ocfs2/dlm/userdlm.c | |||
@@ -237,9 +237,13 @@ static void user_unlock_ast(void *opaque, enum dlm_status status) | |||
237 | mlog(ML_ERROR, "Dlm returns status %d\n", status); | 237 | mlog(ML_ERROR, "Dlm returns status %d\n", status); |
238 | 238 | ||
239 | spin_lock(&lockres->l_lock); | 239 | spin_lock(&lockres->l_lock); |
240 | if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) | 240 | /* The teardown flag gets set early during the unlock process, |
241 | * so test the cancel flag to make sure that this ast isn't | ||
242 | * for a concurrent cancel. */ | ||
243 | if (lockres->l_flags & USER_LOCK_IN_TEARDOWN | ||
244 | && !(lockres->l_flags & USER_LOCK_IN_CANCEL)) { | ||
241 | lockres->l_level = LKM_IVMODE; | 245 | lockres->l_level = LKM_IVMODE; |
242 | else if (status == DLM_CANCELGRANT) { | 246 | } else if (status == DLM_CANCELGRANT) { |
243 | mlog(0, "Lock %s, cancel fails, flags 0x%x\n", | 247 | mlog(0, "Lock %s, cancel fails, flags 0x%x\n", |
244 | lockres->l_name, lockres->l_flags); | 248 | lockres->l_name, lockres->l_flags); |
245 | /* We tried to cancel a convert request, but it was | 249 | /* We tried to cancel a convert request, but it was |
@@ -608,6 +612,14 @@ int user_dlm_destroy_lock(struct user_lock_res *lockres) | |||
608 | mlog(0, "asked to destroy %s\n", lockres->l_name); | 612 | mlog(0, "asked to destroy %s\n", lockres->l_name); |
609 | 613 | ||
610 | spin_lock(&lockres->l_lock); | 614 | spin_lock(&lockres->l_lock); |
615 | if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { | ||
616 | mlog(0, "Lock is already torn down\n"); | ||
617 | spin_unlock(&lockres->l_lock); | ||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | lockres->l_flags |= USER_LOCK_IN_TEARDOWN; | ||
622 | |||
611 | while (lockres->l_flags & USER_LOCK_BUSY) { | 623 | while (lockres->l_flags & USER_LOCK_BUSY) { |
612 | spin_unlock(&lockres->l_lock); | 624 | spin_unlock(&lockres->l_lock); |
613 | 625 | ||
@@ -633,7 +645,6 @@ int user_dlm_destroy_lock(struct user_lock_res *lockres) | |||
633 | 645 | ||
634 | lockres->l_flags &= ~USER_LOCK_ATTACHED; | 646 | lockres->l_flags &= ~USER_LOCK_ATTACHED; |
635 | lockres->l_flags |= USER_LOCK_BUSY; | 647 | lockres->l_flags |= USER_LOCK_BUSY; |
636 | lockres->l_flags |= USER_LOCK_IN_TEARDOWN; | ||
637 | spin_unlock(&lockres->l_lock); | 648 | spin_unlock(&lockres->l_lock); |
638 | 649 | ||
639 | mlog(0, "unlocking lockres %s\n", lockres->l_name); | 650 | mlog(0, "unlocking lockres %s\n", lockres->l_name); |