Ejemplo n.º 1
0
void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
{
	BUG_ON(!dlm);
	BUG_ON(!lock);

	spin_lock(&dlm->ast_lock);
	__dlm_queue_bast(dlm, lock);
	spin_unlock(&dlm->ast_lock);
}
Ejemplo n.º 2
0
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;
		}
	}