Whamcloud - gitweb
LU-4269 ldlm: Hold lock when clearing flag 46/9346/3
authorLi Xi <pkuelelixi@gmail.com>
Wed, 8 Jan 2014 09:13:16 +0000 (17:13 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 24 Feb 2014 18:58:50 +0000 (18:58 +0000)
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 <lixi@ddn.com>
Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Signed-off-by: Bob Glossman <bob.glossman@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
Change-Id: I6f449ba0e03b936435ffa8a1b158a4987c636862
Reviewed-on: http://review.whamcloud.com/9346
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Bobi Jam <bobijam@gmail.com>
lustre/include/lustre_dlm_flags.h
lustre/ldlm/ldlm_lock.c
lustre/ldlm/ldlm_request.c

index 855e18f..d5005c3 100644 (file)
 #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
index 21661ed..1ca91fe 100644 (file)
@@ -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++;
 }
 
 /**
index 1aa451b..5dc364b 100644 (file)
@@ -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);