From 61a0f7a3212dbabc104226b49725b20b20e1530f Mon Sep 17 00:00:00 2001 From: adilger Date: Mon, 5 Apr 2004 18:14:48 +0000 Subject: [PATCH] Don't update to the kms value for a lock that is just in the process of being cancelled. b=3057 r=phil --- lustre/ChangeLog | 1 + lustre/include/linux/lustre_dlm.h | 8 ++++++++ lustre/ldlm/ldlm_extent.c | 8 +++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 598fba1..4dce98a 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -9,6 +9,7 @@ tbd Cluster File Systems, Inc. - handle intent open/close of special files properly (1557) - mount MDS with errors=remount-ro, like obdfilter (2009) - initialize lock handle to avoid ASSERT on error cleanup (3057) + - don't use cancelling-locks' kms values (2947) * miscellania - allow default OST striping configuration per directory (1414) diff --git a/lustre/include/linux/lustre_dlm.h b/lustre/include/linux/lustre_dlm.h index d85d7a1..d5b1f76 100644 --- a/lustre/include/linux/lustre_dlm.h +++ b/lustre/include/linux/lustre_dlm.h @@ -87,6 +87,14 @@ typedef enum { * pretty high-risk, though, and would need a lot more testing. */ #define LDLM_FL_CAN_MATCH 0x100000 +/* A lock contributes to the kms calculation until it has finished the part + * of it's cancelation that performs write back on its dirty pages. It + * can remain on the granted list during this whole time. Threads racing + * to update the kms after performing their writeback need to know to + * exclude each others locks from the calculation as they walk the granted + * list. */ +#define LDLM_FL_KMS_IGNORE 0x200000 + /* The blocking callback is overloaded to perform two functions. These flags * indicate which operation should be performed. */ #define LDLM_CB_BLOCKING 1 diff --git a/lustre/ldlm/ldlm_extent.c b/lustre/ldlm/ldlm_extent.c index 1d02d63..85ba8e6 100644 --- a/lustre/ldlm/ldlm_extent.c +++ b/lustre/ldlm/ldlm_extent.c @@ -262,12 +262,18 @@ __u64 ldlm_extent_shift_kms(struct ldlm_lock *lock, __u64 old_kms) __u64 kms = 0; ENTRY; + /* don't let another thread in ldlm_extent_shift_kms race in + * just after we finish and take our lock into account in its + * calculation of the kms */ + lock->l_flags |= LDLM_FL_KMS_IGNORE; + l_lock(&res->lr_namespace->ns_lock); list_for_each(tmp, &res->lr_granted) { lck = list_entry(tmp, struct ldlm_lock, l_res_link); - if (lock == lck) + if (lck->l_flags & LDLM_FL_KMS_IGNORE) continue; + if (lck->l_policy_data.l_extent.end >= old_kms) GOTO(out, kms = old_kms); kms = lck->l_policy_data.l_extent.end + 1; -- 1.8.3.1