Whamcloud - gitweb
LU-1214 ptlrpc: removes client lu_target.h/target.c dependency
[fs/lustre-release.git] / lustre / lov / lovsub_lock.c
index 6b96896..f15662a 100644 (file)
  * GPL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Whamcloud, Inc.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -42,7 +44,9 @@
 
 #include "lov_cl_internal.h"
 
-/** \addtogroup lov lov @{ */
+/** \addtogroup lov
+ *  @{
+ */
 
 /*****************************************************************************
  *
@@ -57,7 +61,7 @@ static void lovsub_lock_fini(const struct lu_env *env,
 
         ENTRY;
         lsl = cl2lovsub_lock(slice);
-        LASSERT(list_empty(&lsl->lss_parents));
+        LASSERT(cfs_list_empty(&lsl->lss_parents));
         OBD_SLAB_FREE_PTR(lsl, lovsub_lock_kmem);
         EXIT;
 }
@@ -86,28 +90,6 @@ static void lovsub_parent_unlock(const struct lu_env *env, struct lov_lock *lov)
         EXIT;
 }
 
-static void lovsub_lock_state_one(const struct lu_env *env,
-                                  const struct lovsub_lock *lovsub,
-                                  struct lov_lock *lov)
-{
-        struct cl_lock       *parent;
-        const struct cl_lock *child;
-
-        ENTRY;
-        parent = lov->lls_cl.cls_lock;
-        child  = lovsub->lss_cl.cls_lock;
-
-        if (lovsub->lss_active != parent) {
-                lovsub_parent_lock(env, lov);
-                if (child->cll_error != 0)
-                        cl_lock_error(env, parent, child->cll_error);
-                else
-                        cl_lock_signal(env, parent);
-                lovsub_parent_unlock(env, lov);
-        }
-        EXIT;
-}
-
 /**
  * Implements cl_lock_operations::clo_state() method for lovsub layer, which
  * method is called whenever sub-lock state changes. Propagates state change
@@ -119,23 +101,20 @@ static void lovsub_lock_state(const struct lu_env *env,
 {
         struct lovsub_lock   *sub = cl2lovsub_lock(slice);
         struct lov_lock_link *scan;
-        struct lov_lock_link *temp;
 
         LASSERT(cl_lock_is_mutexed(slice->cls_lock));
         ENTRY;
 
-        /*
-         * Use _safe() version, because
-         *
-         *     lovsub_lock_state_one()
-         *       ->cl_lock_error()
-         *         ->cl_lock_delete()
-         *           ->lov_lock_delete()
-         *
-         * can unlink parent from the parent list.
-         */
-        list_for_each_entry_safe(scan, temp, &sub->lss_parents, lll_list)
-                lovsub_lock_state_one(env, sub, scan->lll_super);
+        cfs_list_for_each_entry(scan, &sub->lss_parents, lll_list) {
+                struct lov_lock *lov    = scan->lll_super;
+                struct cl_lock  *parent = lov->lls_cl.cls_lock;
+
+                if (sub->lss_active != parent) {
+                        lovsub_parent_lock(env, lov);
+                        cl_lock_signal(env, parent);
+                        lovsub_parent_unlock(env, lov);
+                }
+        }
         EXIT;
 }
 
@@ -154,7 +133,7 @@ static unsigned long lovsub_lock_weigh(const struct lu_env *env,
 
         LASSERT(cl_lock_is_mutexed(slice->cls_lock));
 
-        if (!list_empty(&lock->lss_parents)) {
+        if (!cfs_list_empty(&lock->lss_parents)) {
                 /*
                  * It is not clear whether all parents have to be asked and
                  * their estimations summed, or it is enough to ask one. For
@@ -190,9 +169,6 @@ static void lovsub_lock_descr_map(const struct cl_lock_descr *in,
         start = in->cld_start;
         end   = in->cld_end;
 
-        /*
-         * XXX join file support.
-         */
         if (lsm->lsm_stripe_count > 1) {
                 size = cl_index(lov2cl(obj), lsm->lsm_stripe_size);
                 skip = (lsm->lsm_stripe_count - 1) * size;
@@ -231,7 +207,6 @@ int lov_sublock_modify(const struct lu_env *env, struct lov_lock *lov,
                        const struct cl_lock_descr *d, int idx)
 {
         struct cl_lock       *parent;
-        struct cl_lock       *child;
         struct lovsub_object *subobj;
         struct cl_lock_descr *pd;
         struct cl_lock_descr *parent_descr;
@@ -241,12 +216,12 @@ int lov_sublock_modify(const struct lu_env *env, struct lov_lock *lov,
         parent_descr = &parent->cll_descr;
         LASSERT(cl_lock_mode_match(d->cld_mode, parent_descr->cld_mode));
 
-        child  = sublock->lss_cl.cls_lock;
         subobj = cl2lovsub(sublock->lss_cl.cls_obj);
         pd     = &lov_env_info(env)->lti_ldescr;
 
         pd->cld_obj  = parent_descr->cld_obj;
         pd->cld_mode = parent_descr->cld_mode;
+        pd->cld_gid  = parent_descr->cld_gid;
         lovsub_lock_descr_map(d, subobj->lso_super, subobj->lso_index, pd);
         lov->lls_sub[idx].sub_got = *d;
         /*
@@ -273,7 +248,7 @@ static int lovsub_lock_modify(const struct lu_env *env,
 
         LASSERT(cl_lock_mode_match(d->cld_mode,
                                    s->cls_lock->cll_descr.cld_mode));
-        list_for_each_entry(scan, &lock->lss_parents, lll_list) {
+        cfs_list_for_each_entry(scan, &lock->lss_parents, lll_list) {
                 int rc;
 
                 lov = scan->lll_super;
@@ -300,7 +275,7 @@ static int lovsub_lock_closure(const struct lu_env *env,
         sub    = cl2lovsub_lock(slice);
         result = 0;
 
-        list_for_each_entry(scan, &sub->lss_parents, lll_list) {
+        cfs_list_for_each_entry(scan, &sub->lss_parents, lll_list) {
                 parent = scan->lll_super->lls_cl.cls_lock;
                 result = cl_lock_closure_build(env, parent, closure);
                 if (result != 0)
@@ -316,21 +291,21 @@ static int lovsub_lock_closure(const struct lu_env *env,
 static int lovsub_lock_delete_one(const struct lu_env *env,
                                   struct cl_lock *child, struct lov_lock *lov)
 {
-        struct cl_lock       *parent;
+        struct cl_lock *parent;
         int             result;
         ENTRY;
 
-        parent  = lov->lls_cl.cls_lock;
-        result = 0;
+        parent = lov->lls_cl.cls_lock;
+        if (parent->cll_error)
+                RETURN(0);
 
+        result = 0;
         switch (parent->cll_state) {
-        case CLS_NEW:
         case CLS_QUEUING:
-        case CLS_ENQUEUED:
         case CLS_FREEING:
                 cl_lock_signal(env, parent);
                 break;
-        case CLS_UNLOCKING:
+        case CLS_INTRANSIT:
                 /*
                  * Here lies a problem: a sub-lock is canceled while top-lock
                  * is being unlocked. Top-lock cannot be moved into CLS_NEW
@@ -342,13 +317,14 @@ static int lovsub_lock_delete_one(const struct lu_env *env,
                  * to be reused immediately). Nor can we wait for top-lock
                  * state to change, because this can be synchronous to the
                  * current thread.
-                         *
+                 *
                  * We know for sure that lov_lock_unuse() will be called at
                  * least one more time to finish un-using, so leave a mark on
                  * the top-lock, that will be seen by the next call to
                  * lov_lock_unuse().
                  */
-                lov->lls_unuse_race = 1;
+                if (cl_lock_is_intransit(parent))
+                        lov->lls_cancel_race = 1;
                 break;
         case CLS_CACHED:
                 /*
@@ -359,6 +335,8 @@ static int lovsub_lock_delete_one(const struct lu_env *env,
                  * enqueues missing sub-lock.
                  */
                 cl_lock_state_set(env, parent, CLS_NEW);
+                /* fall through */
+        case CLS_NEW:
                 /*
                  * if last sub-lock is canceled, destroy the top-lock (which
                  * is now `empty') proactively.
@@ -398,10 +376,13 @@ static int lovsub_lock_delete_one(const struct lu_env *env,
                         }
                 }
                 break;
+        case CLS_ENQUEUED:
         case CLS_HELD:
+                CL_LOCK_DEBUG(D_ERROR, env, parent, "Delete CLS_HELD lock\n");
         default:
-                CERROR("Impossible state: %i\n", parent->cll_state);
+                CERROR("Impossible state: %d\n", parent->cll_state);
                 LBUG();
+                break;
         }
 
         RETURN(result);
@@ -436,8 +417,8 @@ static void lovsub_lock_delete(const struct lu_env *env,
                 struct lov_lock_sub  *subdata;
 
                 restart = 0;
-                list_for_each_entry_safe(scan, temp,
-                                         &sub->lss_parents, lll_list) {
+                cfs_list_for_each_entry_safe(scan, temp,
+                                             &sub->lss_parents, lll_list) {
                         lov     = scan->lll_super;
                         subdata = &lov->lls_sub[scan->lll_idx];
                         lovsub_parent_lock(env, lov);
@@ -462,7 +443,7 @@ static int lovsub_lock_print(const struct lu_env *env, void *cookie,
         struct lov_lock      *lov;
         struct lov_lock_link *scan;
 
-        list_for_each_entry(scan, &sub->lss_parents, lll_list) {
+        cfs_list_for_each_entry(scan, &sub->lss_parents, lll_list) {
                 lov = scan->lll_super;
                 (*p)(env, cookie, "[%d %p ", scan->lll_idx, lov);
                 if (lov != NULL)