示例#1
0
/**
 * Core of osc_dlm_blocking_ast() logic.
 */
static void osc_lock_blocking(const struct lu_env *env,
			      struct ldlm_lock *dlmlock,
			      struct osc_lock *olck, int blocking)
{
	struct cl_lock *lock = olck->ols_cl.cls_lock;

	LASSERT(olck->ols_lock == dlmlock);
	CLASSERT(OLS_BLOCKED < OLS_CANCELLED);
	LASSERT(!osc_lock_is_lockless(olck));

	/*
	 * Lock might be still addref-ed here, if e.g., blocking ast
	 * is sent for a failed lock.
	 */
	osc_lock_unhold(olck);

	if (blocking && olck->ols_state < OLS_BLOCKED)
		/*
		 * Move osc_lock into OLS_BLOCKED before canceling the lock,
		 * because it recursively re-enters osc_lock_blocking(), with
		 * the state set to OLS_CANCELLED.
		 */
		olck->ols_state = OLS_BLOCKED;
	/*
	 * cancel and destroy lock at least once no matter how blocking ast is
	 * entered (see comment above osc_ldlm_blocking_ast() for use
	 * cases). cl_lock_cancel() and cl_lock_delete() are idempotent.
	 */
	cl_lock_cancel(env, lock);
	cl_lock_delete(env, lock);
}
示例#2
0
/**
 * Invariant that has to be true all of the time.
 */
static int osc_lock_invariant(struct osc_lock *ols)
{
	struct ldlm_lock *lock	= osc_handle_ptr(&ols->ols_handle);
	struct ldlm_lock *olock       = ols->ols_lock;
	int	       handle_used = lustre_handle_is_used(&ols->ols_handle);

	return
		ergo(osc_lock_is_lockless(ols),
		     ols->ols_locklessable && ols->ols_lock == NULL)  ||
		(ergo(olock != NULL, handle_used) &&
		 ergo(olock != NULL,
		      olock->l_handle.h_cookie == ols->ols_handle.cookie) &&
		 /*
		  * Check that ->ols_handle and ->ols_lock are consistent, but
		  * take into account that they are set at the different time.
		  */
		 ergo(handle_used,
		      ergo(lock != NULL && olock != NULL, lock == olock) &&
		      ergo(lock == NULL, olock == NULL)) &&
		 ergo(ols->ols_state == OLS_CANCELLED,
		      olock == NULL && !handle_used) &&
		 /*
		  * DLM lock is destroyed only after we have seen cancellation
		  * ast.
		  */
		 ergo(olock != NULL && ols->ols_state < OLS_CANCELLED,
		      !olock->l_destroyed) &&
		 ergo(ols->ols_state == OLS_GRANTED,
		      olock != NULL &&
		      olock->l_req_mode == olock->l_granted_mode &&
		      ols->ols_hold));
}
示例#3
0
/**
 * Invariant that has to be true all of the time.
 */
static int osc_lock_invariant(struct osc_lock *ols)
{
	struct ldlm_lock *lock = osc_handle_ptr(&ols->ols_handle);
	struct ldlm_lock *olock = ols->ols_lock;
	int handle_used = lustre_handle_is_used(&ols->ols_handle);

	if (ergo(osc_lock_is_lockless(ols),
		 ols->ols_locklessable && ols->ols_lock == NULL))
		return 1;

	/*
	 * If all the following "ergo"s are true, return 1, otherwise 0
	 */
	if (!ergo(olock != NULL, handle_used))
		return 0;

	if (!ergo(olock != NULL,
		   olock->l_handle.h_cookie == ols->ols_handle.cookie))
		return 0;

	if (!ergo(handle_used,
		   ergo(lock != NULL && olock != NULL, lock == olock) &&
		   ergo(lock == NULL, olock == NULL)))
		return 0;
	/*
	 * Check that ->ols_handle and ->ols_lock are consistent, but
	 * take into account that they are set at the different time.
	 */
	if (!ergo(ols->ols_state == OLS_CANCELLED,
		   olock == NULL && !handle_used))
		return 0;
	/*
	 * DLM lock is destroyed only after we have seen cancellation
	 * ast.
	 */
	if (!ergo(olock != NULL && ols->ols_state < OLS_CANCELLED,
		   ((olock->l_flags & LDLM_FL_DESTROYED) == 0)))
		return 0;

	if (!ergo(ols->ols_state == OLS_GRANTED,
		   olock != NULL &&
		   olock->l_req_mode == olock->l_granted_mode &&
		   ols->ols_hold))
		return 0;
	return 1;
}