Commit 14741472 authored by Srinivas Eeda's avatar Srinivas Eeda Committed by Joel Becker

ocfs2: Fix a race in o2dlm lockres mastery

In o2dlm, the master of a lock resource keeps a map of all interested
nodes.  This prevents the master from purging the resource before an
interested node can create a lock.

A race between the mastery thread and the mastery handler allowed an
interested node to discover who the master is without informing the
master directly.  This is easily fixed by holding the dlm spinlock a
little longer in the mastery handler.
Signed-off-by: default avatarSrinivas Eeda <srinivas.eeda@oracle.com>
Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
parent b54c2ca4
...@@ -1875,7 +1875,6 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data, ...@@ -1875,7 +1875,6 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
ok: ok:
spin_unlock(&res->spinlock); spin_unlock(&res->spinlock);
} }
spin_unlock(&dlm->spinlock);
// mlog(0, "woo! got an assert_master from node %u!\n", // mlog(0, "woo! got an assert_master from node %u!\n",
// assert->node_idx); // assert->node_idx);
...@@ -1926,7 +1925,6 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data, ...@@ -1926,7 +1925,6 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
/* master is known, detach if not already detached. /* master is known, detach if not already detached.
* ensures that only one assert_master call will happen * ensures that only one assert_master call will happen
* on this mle. */ * on this mle. */
spin_lock(&dlm->spinlock);
spin_lock(&dlm->master_lock); spin_lock(&dlm->master_lock);
rr = atomic_read(&mle->mle_refs.refcount); rr = atomic_read(&mle->mle_refs.refcount);
...@@ -1959,7 +1957,6 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data, ...@@ -1959,7 +1957,6 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
__dlm_put_mle(mle); __dlm_put_mle(mle);
} }
spin_unlock(&dlm->master_lock); spin_unlock(&dlm->master_lock);
spin_unlock(&dlm->spinlock);
} else if (res) { } else if (res) {
if (res->owner != assert->node_idx) { if (res->owner != assert->node_idx) {
mlog(0, "assert_master from %u, but current " mlog(0, "assert_master from %u, but current "
...@@ -1967,6 +1964,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data, ...@@ -1967,6 +1964,7 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data,
res->owner, namelen, name); res->owner, namelen, name);
} }
} }
spin_unlock(&dlm->spinlock);
done: done:
ret = 0; ret = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment