From: Li Xi Date: Wed, 8 Jan 2014 09:13:16 +0000 (+0800) Subject: LU-4269 ldlm: Hold lock when clearing flag X-Git-Tag: 2.5.1-RC1~9 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=refs%2Fchanges%2F46%2F9346%2F3;p=fs%2Flustre-release.git LU-4269 ldlm: Hold lock when clearing flag This patch moves lock's skip flag clearing from lru-delete to lru-add code to prevent clearing lock's flag without resource lock proection. Lustre-commit: 98c2e6b446166ba8f89e60a0d4f38683b920f506 Lustre-change: http://review.whamcloud.com/8772 Signed-off-by: Li Xi Signed-off-by: Bobi Jam Signed-off-by: Bob Glossman Reviewed-by: Andreas Dilger Reviewed-by: Jinshan Xiong Reviewed-by: Oleg Drokin Change-Id: I6f449ba0e03b936435ffa8a1b158a4987c636862 Reviewed-on: http://review.whamcloud.com/9346 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Bobi Jam --- diff --git a/lustre/include/lustre_dlm_flags.h b/lustre/include/lustre_dlm_flags.h index 855e18f..d5005c3 100644 --- a/lustre/include/lustre_dlm_flags.h +++ b/lustre/include/lustre_dlm_flags.h @@ -374,10 +374,10 @@ #define LDLM_TEST_FLAG(_l, _b) (((_l)->l_flags & (_b)) != 0) /** set a ldlm_lock flag bit */ -#define LDLM_SET_FLAG(_l, _b) (((_l)->l_flags |= (_b)) +#define LDLM_SET_FLAG(_l, _b) ((_l)->l_flags |= (_b)) /** clear a ldlm_lock flag bit */ -#define LDLM_CLEAR_FLAG(_l, _b) (((_l)->l_flags &= ~(_b)) +#define LDLM_CLEAR_FLAG(_l, _b) ((_l)->l_flags &= ~(_b)) /** Mask of flags inherited from parent lock when doing intents. */ #define LDLM_INHERIT_FLAGS LDLM_FL_INHERIT_MASK diff --git a/lustre/ldlm/ldlm_lock.c b/lustre/ldlm/ldlm_lock.c index 21661ed..1ca91fe 100644 --- a/lustre/ldlm/ldlm_lock.c +++ b/lustre/ldlm/ldlm_lock.c @@ -250,19 +250,17 @@ EXPORT_SYMBOL(ldlm_lock_put); */ int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock) { - int rc = 0; - if (!cfs_list_empty(&lock->l_lru)) { - struct ldlm_namespace *ns = ldlm_lock_to_ns(lock); - - LASSERT(lock->l_resource->lr_type != LDLM_FLOCK); - cfs_list_del_init(&lock->l_lru); - if (lock->l_flags & LDLM_FL_SKIPPED) - lock->l_flags &= ~LDLM_FL_SKIPPED; - LASSERT(ns->ns_nr_unused > 0); - ns->ns_nr_unused--; - rc = 1; - } - return rc; + int rc = 0; + if (!cfs_list_empty(&lock->l_lru)) { + struct ldlm_namespace *ns = ldlm_lock_to_ns(lock); + + LASSERT(lock->l_resource->lr_type != LDLM_FLOCK); + cfs_list_del_init(&lock->l_lru); + LASSERT(ns->ns_nr_unused > 0); + ns->ns_nr_unused--; + rc = 1; + } + return rc; } /** @@ -291,14 +289,15 @@ int ldlm_lock_remove_from_lru(struct ldlm_lock *lock) */ void ldlm_lock_add_to_lru_nolock(struct ldlm_lock *lock) { - struct ldlm_namespace *ns = ldlm_lock_to_ns(lock); + struct ldlm_namespace *ns = ldlm_lock_to_ns(lock); - lock->l_last_used = cfs_time_current(); - LASSERT(cfs_list_empty(&lock->l_lru)); - LASSERT(lock->l_resource->lr_type != LDLM_FLOCK); - cfs_list_add_tail(&lock->l_lru, &ns->ns_unused_list); - LASSERT(ns->ns_nr_unused >= 0); - ns->ns_nr_unused++; + lock->l_last_used = cfs_time_current(); + LASSERT(cfs_list_empty(&lock->l_lru)); + LASSERT(lock->l_resource->lr_type != LDLM_FLOCK); + cfs_list_add_tail(&lock->l_lru, &ns->ns_unused_list); + ldlm_clear_skipped(lock); + LASSERT(ns->ns_nr_unused >= 0); + ns->ns_nr_unused++; } /** diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index 1aa451b..5dc364b 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -1663,20 +1663,20 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, cfs_list_t *cancels, /* No locks which got blocking requests. */ LASSERT(!(lock->l_flags & LDLM_FL_BL_AST)); - if (flags & LDLM_CANCEL_NO_WAIT && - lock->l_flags & LDLM_FL_SKIPPED) - /* already processed */ - continue; + if (flags & LDLM_CANCEL_NO_WAIT && + ldlm_is_skipped(lock)) + /* already processed */ + continue; /* Somebody is already doing CANCEL. No need for this * lock in LRU, do not traverse it again. */ if (!(lock->l_flags & LDLM_FL_CANCELING)) break; - ldlm_lock_remove_from_lru_nolock(lock); - } - if (&lock->l_lru == &ns->ns_unused_list) - break; + ldlm_lock_remove_from_lru_nolock(lock); + } + if (&lock->l_lru == &ns->ns_unused_list) + break; LDLM_LOCK_GET(lock); spin_unlock(&ns->ns_lock);