Commit 30bee898 authored by Xue jiufei's avatar Xue jiufei Committed by Linus Torvalds

ocfs2/dlm: fix a race between purge and migration

We found a race between purge and migration when doing code review.
Node A put lockres to purgelist before receiving the migrate message
from node B which is the master.  Node A call dlm_mig_lockres_handler to
handle this message.

  >>>>>> race window, dlm_run_purge_list may run and send
         deref message to master, waiting the response
  res->state |= DLM_LOCK_RES_MIGRATING;
  dlm_mig_lockres_handler returns

  >>>>>> dlm_thread receives the response from master for the deref
  message and triggers the BUG because the lockres has the state
  DLM_LOCK_RES_MIGRATING with the following message:

dlm_purge_lockres:209 ERROR: 6633EB681FA7474A9C280A4E1A836F0F: res
M0000000000000000030c0300000000 in use after deref
Signed-off-by: default avatarJiufei Xue <>
Reviewed-by: default avatarJoseph Qi <>
Reviewed-by: default avatarYiwen Jiang <>
Cc: Mark Fasheh <>
Cc: Joel Becker <>
Signed-off-by: default avatarAndrew Morton <>
Signed-off-by: default avatarLinus Torvalds <>
parent a84ac334
......@@ -1373,6 +1373,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
char *buf = NULL;
struct dlm_work_item *item = NULL;
struct dlm_lock_resource *res = NULL;
unsigned int hash;
if (!dlm_grab(dlm))
return -EINVAL;
......@@ -1400,7 +1401,10 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
/* lookup the lock to see if we have a secondary queue for this
* already... just add the locks in and this will have its owner
* and RECOVERY flag changed when it completes. */
res = dlm_lookup_lockres(dlm, mres->lockname, mres->lockname_len);
hash = dlm_lockid_hash(mres->lockname, mres->lockname_len);
res = __dlm_lookup_lockres(dlm, mres->lockname, mres->lockname_len,
if (res) {
/* this will get a ref on res */
/* mark it as recovering/migrating and hash it */
......@@ -1421,13 +1425,16 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data,
mres->lockname_len, mres->lockname);
ret = -EFAULT;
goto leave;
} else {
/* need to allocate, just like if it was
* mastered here normally */
res = dlm_new_lockres(dlm, mres->lockname, mres->lockname_len);
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