ocfs2/dlm: wait until DLM_LOCK_RES_SETREF_INPROG is cleared in dlm_deref_lockres_worker
PATCH 1/1 ocfs2/dlm: wait until DLM_LOCK_RES_SETREF_INPROG is cleared in dlm_deref_lockres_worker
commit f3f854648de6("ocfs2_dlm: Ensure correct ordering of set/clear refmap bit on lockres") still exists a race which can't ensure the ordering is exactly correct.
Node1 Node2 Node3
umount, migrate
lockres to Node2
migrate finished,
send migrate request
to Node3
received migrate request, create a migration_mle, respond to Node2.
set DLM_LOCK_RES_SETREF_INPROG
and send assert master to
Node3
delete migration_mle in assert_master_handler, Node3 umount without response dlm_thread purge this lockres, send drop deref message to Node2
found the flag of DLM_LOCK_RES_SETREF_INPROG
is set, dispatch
dlm_deref_lockres_worker to
clear refmap, but in function of dlm_deref_lockres_worker,
only if node in refmap it wait DLM_LOCK_RES_SETREF_INPROG
to be cleared. So worker is
done successfully
purge lockres, send assert master response to Node1, and finish umount
set Node3 in refmap, and it
won't be cleared forever, thus
lead to umount hung
so wait until DLM_LOCK_RES_SETREF_INPROG is cleared in dlm_deref_lockres_worker.
--- fs/ocfs2/dlm/dlmmaster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ocfs2/dlm/dlmmaster.c +1 -1
@@ -2388,8 +2388,8 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)spin_lock (&res->spinlock);BUG_ON (res->state &DLM_LOCK_RES_DROPPING_REF ); +__dlm_wait_on_lockres_flags (res,DLM_LOCK_RES_SETREF_INPROG );if (test_bit (node, res->refmap)) { -__dlm_wait_on_lockres_flags (res,DLM_LOCK_RES_SETREF_INPROG );dlm_lockres_clear_refmap_bit (dlm, res, node); cleared =1 ; }
Signature · 1 line
1.8.4.3
PATCH 1/1 ocfs2/dlm: wait until DLM_LOCK_RES_SETREF_INPROG is cleared in dlm_deref_lockres_worker
Quoted 40 lines · jiangyiwen
commit
f3f854648de6("ocfs2_dlm: Ensure correct ordering of set/clear refmap bit on lockres")still exists a race which can't ensure the ordering is exactly correct.Node1 Node2 Node3
umount, migrate
lockres to Node2
migrate finished,
send migrate request
to Node3
received migrate request, create amigration_mle, respond to Node2.
setDLM_LOCK_RES_SETREF_INPROG
and send assert master to
Node3
deletemigration_mleinassert_master_handler, Node3 umount without responsedlm_threadpurge this lockres, send drop deref message to Node2
found the flag ofDLM_LOCK_RES_SETREF_INPROG
is set, dispatch
dlm_deref_lockres_workerto
clear refmap, but in function ofdlm_deref_lockres_worker,
only if node in refmap it waitDLM_LOCK_RES_SETREF_INPROG
to be cleared. So worker is
done successfullypurge lockres, send assert master response to Node1, and finish umount
set Node3 in refmap, and it
won't be cleared forever, thus
lead to umount hung
Quoted 5 lines
so wait until
DLM_LOCK_RES_SETREF_INPROGis cleared indlm_deref_lockres_worker.Signed-off-by Yiwen Jiang <[email protected]>Reviewed-by Joseph Qi <[email protected]>
Looks good.
Quoted 19 lines
--- fs/ocfs2/dlm/dlmmaster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)fs/ocfs2/dlm/dlmmaster.c +1
-1@@ -2388,8 +2388,8 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data)spin_lock (&res->spinlock);BUG_ON (res->state &DLM_LOCK_RES_DROPPING_REF ); +__dlm_wait_on_lockres_flags (res,DLM_LOCK_RES_SETREF_INPROG );if (test_bit (node, res->refmap)) { -__dlm_wait_on_lockres_flags (res,DLM_LOCK_RES_SETREF_INPROG );dlm_lockres_clear_refmap_bit (dlm, res, node); cleared =1 ; }