static void dlm_shuffle_lists(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) { struct dlm_lock *lock, *target; struct list_head *iter; struct list_head *head; int can_grant = 1; //mlog(0, "res->lockname.len=%d\n", res->lockname.len); //mlog(0, "res->lockname.name=%p\n", res->lockname.name); //mlog(0, "shuffle res %.*s\n", res->lockname.len, // res->lockname.name); /* because this function is called with the lockres * spinlock, and because we know that it is not migrating/ * recovering/in-progress, it is fine to reserve asts and * basts right before queueing them all throughout */ assert_spin_locked(&dlm->ast_lock); assert_spin_locked(&res->spinlock); BUG_ON((res->state & (DLM_LOCK_RES_MIGRATING| DLM_LOCK_RES_RECOVERING| DLM_LOCK_RES_IN_PROGRESS))); converting: if (list_empty(&res->converting)) goto blocked; mlog(0, "res %.*s has locks on a convert queue\n", res->lockname.len, res->lockname.name); target = list_entry(res->converting.next, struct dlm_lock, list); if (target->ml.convert_type == LKM_IVMODE) { mlog(ML_ERROR, "%.*s: converting a lock with no " "convert_type!\n", res->lockname.len, res->lockname.name); BUG(); } head = &res->granted; list_for_each(iter, head) { lock = list_entry(iter, struct dlm_lock, list); if (lock==target) continue; if (!dlm_lock_compatible(lock->ml.type, target->ml.convert_type)) { can_grant = 0; /* queue the BAST if not already */ if (lock->ml.highest_blocked == LKM_IVMODE) { __dlm_lockres_reserve_ast(res); __dlm_queue_bast(dlm, lock); } /* update the highest_blocked if needed */ if (lock->ml.highest_blocked < target->ml.convert_type) lock->ml.highest_blocked = target->ml.convert_type; } }
static void dlm_shuffle_lists(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) { struct dlm_lock *lock, *target; struct list_head *iter; struct list_head *head; int can_grant = 1; assert_spin_locked(&dlm->ast_lock); assert_spin_locked(&res->spinlock); BUG_ON((res->state & (DLM_LOCK_RES_MIGRATING| DLM_LOCK_RES_RECOVERING| DLM_LOCK_RES_IN_PROGRESS))); converting: if (list_empty(&res->converting)) goto blocked; mlog(0, "%s: res %.*s has locks on the convert queue\n", dlm->name, res->lockname.len, res->lockname.name); target = list_entry(res->converting.next, struct dlm_lock, list); if (target->ml.convert_type == LKM_IVMODE) { mlog(ML_ERROR, "%s: res %.*s converting lock to invalid mode\n", dlm->name, res->lockname.len, res->lockname.name); BUG(); } head = &res->granted; list_for_each(iter, head) { lock = list_entry(iter, struct dlm_lock, list); if (lock==target) continue; if (!dlm_lock_compatible(lock->ml.type, target->ml.convert_type)) { can_grant = 0; if (lock->ml.highest_blocked == LKM_IVMODE) { __dlm_lockres_reserve_ast(res); __dlm_queue_bast(dlm, lock); } if (lock->ml.highest_blocked < target->ml.convert_type) lock->ml.highest_blocked = target->ml.convert_type; } }