From f4ea4017b4d6a420146b2959f9feb11866858b4a Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Fri, 15 Sep 2017 19:23:58 +0000 Subject: [PATCH] LU-9997 ldlm: check lock cancellation in ldlm_cli_cancel() In that case, the assert for 'list_empty(&lock->l_bl_ast)' will fail because the lock is already in a cancel list. This patch checks if the lock is already being canceled in prior. Signed-off-by: Jinshan Xiong Change-Id: I04b9df789cf3b3b5e6dd61a647376307f9975f4a Reviewed-on: https://review.whamcloud.com/29080 Reviewed-by: Andreas Dilger Reviewed-by: Bobi Jam Tested-by: Jenkins Tested-by: Maloo --- lustre/ldlm/ldlm_internal.h | 13 +++++++++++++ lustre/ldlm/ldlm_lock.c | 13 ------------- lustre/ldlm/ldlm_request.c | 11 +++++++++-- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/lustre/ldlm/ldlm_internal.h b/lustre/ldlm/ldlm_internal.h index e798997..062f12c 100644 --- a/lustre/ldlm/ldlm_internal.h +++ b/lustre/ldlm/ldlm_internal.h @@ -362,6 +362,19 @@ static inline int is_granted_or_cancelled(struct ldlm_lock *lock) return ret; } +static inline bool is_bl_done(struct ldlm_lock *lock) +{ + bool bl_done = true; + + if (!ldlm_is_bl_done(lock)) { + lock_res_and_lock(lock); + bl_done = ldlm_is_bl_done(lock); + unlock_res_and_lock(lock); + } + + return bl_done; +} + typedef void (*ldlm_policy_wire_to_local_t)(const union ldlm_wire_policy_data *, union ldlm_policy_data *); typedef void (*ldlm_policy_local_to_wire_t)(const union ldlm_policy_data *, diff --git a/lustre/ldlm/ldlm_lock.c b/lustre/ldlm/ldlm_lock.c index b7ec3df..93e7960 100644 --- a/lustre/ldlm/ldlm_lock.c +++ b/lustre/ldlm/ldlm_lock.c @@ -2301,19 +2301,6 @@ void ldlm_reprocess_recovery_done(struct ldlm_namespace *ns) EXIT; } -static bool is_bl_done(struct ldlm_lock *lock) -{ - bool bl_done = true; - - if (!ldlm_is_bl_done(lock)) { - lock_res_and_lock(lock); - bl_done = ldlm_is_bl_done(lock); - unlock_res_and_lock(lock); - } - - return bl_done; -} - /** * Helper function to call blocking AST for LDLM lock \a lock in a * "cancelling" mode. diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index 859568d..d1d068f 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -1392,8 +1392,15 @@ int ldlm_cli_cancel(const struct lustre_handle *lockh, lock_res_and_lock(lock); /* Lock is being canceled and the caller doesn't want to wait */ - if (ldlm_is_canceling(lock) && (cancel_flags & LCF_ASYNC)) { - unlock_res_and_lock(lock); + if (ldlm_is_canceling(lock)) { + if (cancel_flags & LCF_ASYNC) { + unlock_res_and_lock(lock); + } else { + struct l_wait_info lwi = { 0 }; + + unlock_res_and_lock(lock); + l_wait_event(lock->l_waitq, is_bl_done(lock), &lwi); + } LDLM_LOCK_RELEASE(lock); RETURN(0); } -- 1.8.3.1