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
{
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;
- }
+ 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;
}