X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Flov%2Flovsub_lock.c;h=a0f3406621b9e444fcc891f584ce6ff2c07221ae;hb=9f7e47cfc7f0346ac2eb0ab45c8dff058c271fa1;hp=48d788ae8cc860ecf9937bd6d025b5c86960e9f8;hpb=15385c3b934b511a1452327c701fbb6adad71416;p=fs%2Flustre-release.git diff --git a/lustre/lov/lovsub_lock.c b/lustre/lov/lovsub_lock.c index 48d788a..a0f3406 100644 --- a/lustre/lov/lovsub_lock.c +++ b/lustre/lov/lovsub_lock.c @@ -26,7 +26,7 @@ * 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. */ /* @@ -42,7 +42,9 @@ #include "lov_cl_internal.h" -/** \addtogroup lov lov @{ */ +/** \addtogroup lov + * @{ + */ /***************************************************************************** * @@ -57,7 +59,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,40 +88,6 @@ static void lovsub_parent_unlock(const struct lu_env *env, struct lov_lock *lov) EXIT; } -static int lovsub_lock_state_one(const struct lu_env *env, - const struct lovsub_lock *lovsub, - struct lov_lock *lov) -{ - struct cl_lock *parent; - struct cl_lock *child; - int restart = 0; - - 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 && parent->cll_error == 0) { - /* - * This is a deadlock case: - * cl_lock_error(for the parent lock) - * -> cl_lock_delete - * -> lov_lock_delete - * -> cl_lock_enclosure - * -> cl_lock_mutex_try(for the child lock) - */ - cl_lock_mutex_put(env, child); - cl_lock_error(env, parent, child->cll_error); - restart = 1; - } else { - cl_lock_signal(env, parent); - } - lovsub_parent_unlock(env, lov); - } - RETURN(restart); -} - /** * Implements cl_lock_operations::clo_state() method for lovsub layer, which * method is called whenever sub-lock state changes. Propagates state change @@ -131,22 +99,20 @@ static void lovsub_lock_state(const struct lu_env *env, { struct lovsub_lock *sub = cl2lovsub_lock(slice); struct lov_lock_link *scan; - int restart = 0; LASSERT(cl_lock_is_mutexed(slice->cls_lock)); ENTRY; - do { - restart = 0; - list_for_each_entry(scan, &sub->lss_parents, lll_list) { - restart = lovsub_lock_state_one(env, sub, - scan->lll_super); - if (restart) { - cl_lock_mutex_get(env, slice->cls_lock); - break; - } + 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); } - } while(restart); + } EXIT; } @@ -165,7 +131,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 @@ -201,9 +167,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; @@ -285,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; @@ -312,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) @@ -328,13 +291,15 @@ 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: @@ -342,7 +307,7 @@ static int lovsub_lock_delete_one(const struct lu_env *env, 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 @@ -354,13 +319,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: /* @@ -411,9 +377,11 @@ static int lovsub_lock_delete_one(const struct lu_env *env, } break; case CLS_HELD: + CL_LOCK_DEBUG(D_ERROR, env, parent, "Delete CLS_HELD lock\n"); default: CERROR("Impossible state: %i\n", parent->cll_state); LBUG(); + break; } RETURN(result); @@ -448,8 +416,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); @@ -474,7 +442,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)