Whamcloud - gitweb
Don't update to the kms value for a lock that is just in the process of
authoradilger <adilger>
Mon, 5 Apr 2004 18:14:48 +0000 (18:14 +0000)
committeradilger <adilger>
Mon, 5 Apr 2004 18:14:48 +0000 (18:14 +0000)
being cancelled.
b=3057
r=phil

lustre/ChangeLog
lustre/include/linux/lustre_dlm.h
lustre/ldlm/ldlm_extent.c

index 598fba1..4dce98a 100644 (file)
@@ -9,6 +9,7 @@ tbd  Cluster File Systems, Inc. <info@clusterfs.com>
        - 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)
 
index d85d7a1..d5b1f76 100644 (file)
@@ -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
index 1d02d63..85ba8e6 100644 (file)
@@ -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;