Пример #1
0
static int dlm_purge_lockres(struct dlm_ctxt *dlm,
			     struct dlm_lock_resource *res)
{
	int master;
	int ret = 0;

	spin_lock(&res->spinlock);
	if (!__dlm_lockres_unused(res)) {
		spin_unlock(&res->spinlock);
		mlog(0, "%s:%.*s: tried to purge but not unused\n",
		     dlm->name, res->lockname.len, res->lockname.name);
		return -ENOTEMPTY;
	}
	master = (res->owner == dlm->node_num);
	if (!master)
		res->state |= DLM_LOCK_RES_DROPPING_REF;
	spin_unlock(&res->spinlock);

	mlog(0, "purging lockres %.*s, master = %d\n", res->lockname.len,
	     res->lockname.name, master);

	if (!master) {
		spin_lock(&res->spinlock);
		/* This ensures that clear refmap is sent after the set */
		__dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG);
		spin_unlock(&res->spinlock);
		/* drop spinlock to do messaging, retake below */
		spin_unlock(&dlm->spinlock);
		/* clear our bit from the master's refmap, ignore errors */
		ret = dlm_drop_lockres_ref(dlm, res);
		if (ret < 0) {
			mlog_errno(ret);
			if (!dlm_is_host_down(ret))
				BUG();
		}
		mlog(0, "%s:%.*s: dlm_deref_lockres returned %d\n",
		     dlm->name, res->lockname.len, res->lockname.name, ret);
		spin_lock(&dlm->spinlock);
	}

	if (!list_empty(&res->purge)) {
		mlog(0, "removing lockres %.*s:%p from purgelist, "
		     "master = %d\n", res->lockname.len, res->lockname.name,
		     res, master);
		list_del_init(&res->purge);
		dlm_lockres_put(res);
		dlm->purge_count--;
	}
	__dlm_unhash_lockres(res);

	/* lockres is not in the hash now.  drop the flag and wake up
	 * any processes waiting in dlm_get_lock_resource. */
	if (!master) {
		spin_lock(&res->spinlock);
		res->state &= ~DLM_LOCK_RES_DROPPING_REF;
		spin_unlock(&res->spinlock);
		wake_up(&res->wq);
	}
	return 0;
}
static void dlm_purge_lockres(struct dlm_ctxt *dlm,
			     struct dlm_lock_resource *res)
{
	int master;
	int ret = 0;

	assert_spin_locked(&dlm->spinlock);
	assert_spin_locked(&res->spinlock);

	master = (res->owner == dlm->node_num);

	mlog(0, "%s: Purging res %.*s, master %d\n", dlm->name,
	     res->lockname.len, res->lockname.name, master);

	if (!master) {
		res->state |= DLM_LOCK_RES_DROPPING_REF;
		
		spin_unlock(&res->spinlock);
		spin_unlock(&dlm->spinlock);

		spin_lock(&res->spinlock);
		
		__dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG);
		spin_unlock(&res->spinlock);

		
		ret = dlm_drop_lockres_ref(dlm, res);
		if (ret < 0) {
			if (!dlm_is_host_down(ret))
				BUG();
		}
		spin_lock(&dlm->spinlock);
		spin_lock(&res->spinlock);
	}

	if (!list_empty(&res->purge)) {
		mlog(0, "%s: Removing res %.*s from purgelist, master %d\n",
		     dlm->name, res->lockname.len, res->lockname.name, master);
		list_del_init(&res->purge);
		dlm_lockres_put(res);
		dlm->purge_count--;
	}

	if (!__dlm_lockres_unused(res)) {
		mlog(ML_ERROR, "%s: res %.*s in use after deref\n",
		     dlm->name, res->lockname.len, res->lockname.name);
		__dlm_print_one_lock_resource(res);
		BUG();
	}

	__dlm_unhash_lockres(dlm, res);

	if (!master) {
		res->state &= ~DLM_LOCK_RES_DROPPING_REF;
		spin_unlock(&res->spinlock);
		wake_up(&res->wq);
	} else
		spin_unlock(&res->spinlock);
}
Пример #3
0
static void dlm_purge_lockres(struct dlm_ctxt *dlm,
			     struct dlm_lock_resource *res)
{
	int master;
	int ret = 0;

	assert_spin_locked(&dlm->spinlock);
	assert_spin_locked(&res->spinlock);

	master = (res->owner == dlm->node_num);

	mlog(0, "%s: Purging res %.*s, master %d\n", dlm->name,
	     res->lockname.len, res->lockname.name, master);

	if (!master) {
		res->state |= DLM_LOCK_RES_DROPPING_REF;
		/* drop spinlock...  retake below */
		spin_unlock(&res->spinlock);
		spin_unlock(&dlm->spinlock);

		spin_lock(&res->spinlock);
		/* This ensures that clear refmap is sent after the set */
		__dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG);
		spin_unlock(&res->spinlock);

		/* clear our bit from the master's refmap, ignore errors */
		ret = dlm_drop_lockres_ref(dlm, res);
		if (ret < 0) {
			if (!dlm_is_host_down(ret))
				BUG();
		}
		spin_lock(&dlm->spinlock);
		spin_lock(&res->spinlock);
	}

	if (!list_empty(&res->purge)) {
		mlog(0, "%s: Removing res %.*s from purgelist, master %d\n",
		     dlm->name, res->lockname.len, res->lockname.name, master);
		list_del_init(&res->purge);
		dlm_lockres_put(res);
		dlm->purge_count--;
	}

	if (!__dlm_lockres_unused(res)) {
		mlog(ML_ERROR, "%s: res %.*s in use after deref\n",
		     dlm->name, res->lockname.len, res->lockname.name);
		__dlm_print_one_lock_resource(res);
		BUG();
	}

	__dlm_unhash_lockres(dlm, res);

	/* lockres is not in the hash now.  drop the flag and wake up
	 * any processes waiting in dlm_get_lock_resource. */
	if (!master) {
		res->state &= ~DLM_LOCK_RES_DROPPING_REF;
		spin_unlock(&res->spinlock);
		wake_up(&res->wq);
	} else
		spin_unlock(&res->spinlock);
}