Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f62e960 authored by Sunil Mushran's avatar Sunil Mushran Committed by Joel Becker
Browse files

ocfs2/dlm: dlm_is_lockres_migrateable() returns boolean



Patch cleans up the gunk added by commit 388c4bcb.
dlm_is_lockres_migrateable() now returns 1 if lockresource is deemed
migrateable and 0 if not.

Signed-off-by: default avatarSunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: default avatarJoel Becker <jlbec@evilplan.org>
parent 10fca35f
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -401,6 +401,18 @@ static inline int dlm_lvb_is_empty(char *lvb)
	return 1;
}

static inline char *dlm_list_in_text(enum dlm_lockres_list idx)
{
	if (idx == DLM_GRANTED_LIST)
		return "granted";
	else if (idx == DLM_CONVERTING_LIST)
		return "converting";
	else if (idx == DLM_BLOCKED_LIST)
		return "blocked";
	else
		return "unknown";
}

static inline struct list_head *
dlm_list_idx_to_ptr(struct dlm_lock_resource *res, enum dlm_lockres_list idx)
{
+51 −84
Original line number Diff line number Diff line
@@ -2339,65 +2339,55 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)
	dlm_lockres_put(res);
}

/* Checks whether the lockres can be migrated. Returns 0 if yes, < 0
 * if not. If 0, numlocks is set to the number of locks in the lockres.
/*
 * A migrateable resource is one that is :
 * 1. locally mastered, and,
 * 2. zero local locks, and,
 * 3. one or more non-local locks, or, one or more references
 * Returns 1 if yes, 0 if not.
 */
static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
				      struct dlm_lock_resource *res,
				      int *numlocks,
				      int *hasrefs)
				      struct dlm_lock_resource *res)
{
	int ret;
	int i;
	int count = 0;
	enum dlm_lockres_list idx;
	int nonlocal = 0, node_ref;
	struct list_head *queue;
	struct dlm_lock *lock;
	u64 cookie;

	assert_spin_locked(&res->spinlock);

	*numlocks = 0;
	*hasrefs = 0;

	ret = -EINVAL;
	if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
		mlog(0, "cannot migrate lockres with unknown owner!\n");
		goto leave;
	}

	if (res->owner != dlm->node_num) {
		mlog(0, "cannot migrate lockres this node doesn't own!\n");
		goto leave;
	}
	if (res->owner != dlm->node_num)
		return 0;

	ret = 0;
	queue = &res->granted;
	for (i = 0; i < 3; i++) {
        for (idx = DLM_GRANTED_LIST; idx <= DLM_BLOCKED_LIST; idx++) {
		queue = dlm_list_idx_to_ptr(res, idx);
		list_for_each_entry(lock, queue, list) {
			++count;
			if (lock->ml.node == dlm->node_num) {
				mlog(0, "found a lock owned by this node still "
				     "on the %s queue!  will not migrate this "
				     "lockres\n", (i == 0 ? "granted" :
						   (i == 1 ? "converting" :
						    "blocked")));
				ret = -ENOTEMPTY;
				goto leave;
			if (lock->ml.node != dlm->node_num) {
				nonlocal++;
				continue;
			}
			cookie = be64_to_cpu(lock->ml.cookie);
			mlog(0, "%s: Not migrateable res %.*s, lock %u:%llu on "
			     "%s list\n", dlm->name, res->lockname.len,
			     res->lockname.name,
			     dlm_get_lock_cookie_node(cookie),
			     dlm_get_lock_cookie_seq(cookie),
			     dlm_list_in_text(idx));
			return 0;
		}
		queue++;
	}

	*numlocks = count;

	count = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
	if (count < O2NM_MAX_NODES)
		*hasrefs = 1;
	if (!nonlocal) {
		node_ref = find_next_bit(res->refmap, O2NM_MAX_NODES, 0);
		if (node_ref >= O2NM_MAX_NODES)
			return 0;
	}

	mlog(0, "%s: res %.*s, Migrateable, locks %d, refs %d\n", dlm->name,
	     res->lockname.len, res->lockname.name, *numlocks, *hasrefs);
	mlog(0, "%s: res %.*s, Migrateable\n", dlm->name, res->lockname.len,
	     res->lockname.name);

leave:
	return ret;
	return 1;
}

/*
@@ -2416,7 +2406,6 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
	const char *name;
	unsigned int namelen;
	int mle_added = 0;
	int numlocks, hasrefs;
	int wake = 0;

	if (!dlm_grab(dlm))
@@ -2427,19 +2416,13 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,

	mlog(0, "%s: Migrating %.*s to %u\n", dlm->name, namelen, name, target);

	/*
	 * ensure this lockres is a proper candidate for migration
	 */
	/* Ensure this lockres is a proper candidate for migration */
	spin_lock(&res->spinlock);
	ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs);
	if (ret < 0) {
		spin_unlock(&res->spinlock);
		goto leave;
	}
	ret = dlm_is_lockres_migrateable(dlm, res);
	spin_unlock(&res->spinlock);

	/* no work to do */
	if (numlocks == 0 && !hasrefs)
	/* No work to do */
	if (!ret)
		goto leave;

	/*
@@ -2658,44 +2641,35 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,

	dlm_put(dlm);

	mlog(0, "returning %d\n", ret);
	mlog(0, "%s: Migrating %.*s to %u, returns %d\n", dlm->name, namelen,
	     name, target, ret);
	return ret;
}

#define DLM_MIGRATION_RETRY_MS  100

/* Should be called only after beginning the domain leave process.
/*
 * Should be called only after beginning the domain leave process.
 * There should not be any remaining locks on nonlocal lock resources,
 * and there should be no local locks left on locally mastered resources.
 *
 * Called with the dlm spinlock held, may drop it to do migration, but
 * will re-acquire before exit.
 *
 * Returns: 1 if dlm->spinlock was dropped/retaken, 0 if never dropped */
 * Returns: 1 if dlm->spinlock was dropped/retaken, 0 if never dropped
 */
int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
{
	int ret;
	int mig, ret;
	int lock_dropped = 0;
	int numlocks, hasrefs;

	spin_lock(&res->spinlock);
	if (res->owner != dlm->node_num) {
		if (!__dlm_lockres_unused(res)) {
			mlog(ML_ERROR, "%s:%.*s: this node is not master, "
			     "trying to free this but locks remain\n",
			     dlm->name, res->lockname.len, res->lockname.name);
		}
		spin_unlock(&res->spinlock);
		goto leave;
	}
	assert_spin_locked(&dlm->spinlock);

	/* No need to migrate a lockres having no locks */
	ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs);
	if (ret >= 0 && numlocks == 0 && !hasrefs) {
	spin_lock(&res->spinlock);
	mig = dlm_is_lockres_migrateable(dlm, res);
	spin_unlock(&res->spinlock);
	if (!mig)
		goto leave;
	}
	spin_unlock(&res->spinlock);

	/* Wheee! Migrate lockres here! Will sleep so drop spinlock. */
	spin_unlock(&dlm->spinlock);
@@ -2704,15 +2678,8 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
		ret = dlm_migrate_lockres(dlm, res, O2NM_MAX_NODES);
		if (ret >= 0)
			break;
		if (ret == -ENOTEMPTY) {
			mlog(ML_ERROR, "lockres %.*s still has local locks!\n",
		mlog(0, "%s: res %.*s, Migrate failed, retrying\n", dlm->name,
		     res->lockname.len, res->lockname.name);
			BUG();
		}

		mlog(0, "lockres %.*s: migrate failed, "
		     "retrying\n", res->lockname.len,
		     res->lockname.name);
		msleep(DLM_MIGRATION_RETRY_MS);
	}
	spin_lock(&dlm->spinlock);