Whamcloud - gitweb
LU-3027 lov: to not modify lov lock when sublock is canceled
[fs/lustre-release.git] / lustre / lov / lov_lock.c
index 85958ec..547bdca 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2013, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -147,7 +147,7 @@ static struct cl_lock *lov_sublock_alloc(const struct lu_env *env,
         LASSERT(idx < lck->lls_nr);
         ENTRY;
 
-        OBD_SLAB_ALLOC_PTR_GFP(link, lov_lock_link_kmem, CFS_ALLOC_IO);
+       OBD_SLAB_ALLOC_PTR_GFP(link, lov_lock_link_kmem, __GFP_IO);
         if (link != NULL) {
                 struct lov_sublock_env *subenv;
                 struct lov_lock_sub  *lls;
@@ -652,8 +652,19 @@ static int lov_lock_enqueue(const struct lu_env *env,
                                                                    sublock);
                                         break;
                                 case CLS_CACHED:
+                                       cl_lock_get(sublock);
+                                        /* take recursive mutex of sublock */
+                                        cl_lock_mutex_get(env, sublock);
+                                       /* need to release all locks in closure
+                                        * otherwise it may deadlock. LU-2683.*/
+                                        lov_sublock_unlock(env, sub, closure,
+                                                           subenv);
+                                       /* sublock and parent are held. */
                                         rc = lov_sublock_release(env, lck, i,
                                                                  1, rc);
+                                       cl_lock_mutex_put(env, sublock);
+                                       cl_lock_put(env, sublock);
+                                       break;
                                 default:
                                         lov_sublock_unlock(env, sub, closure,
                                                            subenv);
@@ -1012,6 +1023,9 @@ static int lov_lock_fits_into(const struct lu_env *env,
        if (need->cld_enq_flags != lov->lls_orig.cld_enq_flags)
                return 0;
 
+       if (lov->lls_ever_canceled)
+               return 0;
+
         if (need->cld_mode == CLM_GROUP)
                 /*
                  * always allow to match group lock.
@@ -1182,7 +1196,7 @@ int lov_lock_init_raid0(const struct lu_env *env, struct cl_object *obj,
         int result;
 
         ENTRY;
-        OBD_SLAB_ALLOC_PTR_GFP(lck, lov_lock_kmem, CFS_ALLOC_IO);
+       OBD_SLAB_ALLOC_PTR_GFP(lck, lov_lock_kmem, __GFP_IO);
         if (lck != NULL) {
                 cl_lock_slice_add(lock, &lck->lls_cl, obj, &lov_lock_ops);
                 result = lov_lock_sub_init(env, lck, io);
@@ -1205,6 +1219,7 @@ static int lov_empty_lock_print(const struct lu_env *env, void *cookie,
        return 0;
 }
 
+/* XXX: more methods will be added later. */
 static const struct cl_lock_operations lov_empty_lock_ops = {
        .clo_fini  = lov_empty_lock_fini,
        .clo_print = lov_empty_lock_print
@@ -1217,7 +1232,7 @@ int lov_lock_init_empty(const struct lu_env *env, struct cl_object *obj,
        int result = -ENOMEM;
 
        ENTRY;
-       OBD_SLAB_ALLOC_PTR_GFP(lck, lov_lock_kmem, CFS_ALLOC_IO);
+       OBD_SLAB_ALLOC_PTR_GFP(lck, lov_lock_kmem, __GFP_IO);
        if (lck != NULL) {
                cl_lock_slice_add(lock, &lck->lls_cl, obj, &lov_empty_lock_ops);
                lck->lls_orig = lock->cll_descr;