From 441a52fcb989609f8736a5571337661180439644 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Mon, 28 Oct 2013 22:15:03 -0400 Subject: [PATCH] LU-4152 mdt: Don't enqueue two locks on the same resource Due to mechanics of ldlm internals, enqueueing two different ibits lock on the same resource is deadlock prone. As such change mdt_object_open_lock to release open lock if it becomes necessary to get exclusive layout lock (to create objects). It's ok to release the open lock right away as it's never guaranteed to be issued anyway. Change-Id: Ib669e68323ea72c75a0a8bea289d8bea079309b0 Signed-off-by: Oleg Drokin Reviewed-on: http://review.whamcloud.com/8083 Tested-by: Jenkins Reviewed-by: Patrick Farrell Reviewed-by: Jinshan Xiong Tested-by: Maloo --- lustre/mdt/mdt_open.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index 7f987c7..b35ee89 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -1277,6 +1277,15 @@ static int mdt_object_open_lock(struct mdt_thread_info *info, ", open_flags = "LPO64"\n", PFID(mdt_object_fid(obj)), open_flags); + /* We cannot enqueue another lock for the same resource we + * already have a lock for, due to mechanics of waiting list + * iterating in ldlm, see LU-3601. + * As such we'll drop the open lock we just got above here, + * it's ok not to have this open lock as it's main purpose is to + * flush unused cached client open handles. */ + if (lustre_handle_is_used(&lhc->mlh_reg_lh)) + mdt_object_unlock(info, obj, lhc, 1); + LASSERT(!try_layout); mdt_lock_handle_init(ll); mdt_lock_reg_init(ll, LCK_EX); @@ -1366,12 +1375,13 @@ static void mdt_object_open_unlock(struct mdt_thread_info *info, rc = 1; } - if (rc != 0) { + if (rc != 0 || !lustre_handle_is_used(&lhc->mlh_reg_lh)) { struct ldlm_reply *ldlm_rep; ldlm_rep = req_capsule_server_get(info->mti_pill, &RMF_DLM_REP); mdt_clear_disposition(info, ldlm_rep, DISP_OPEN_LOCK); - mdt_object_unlock(info, obj, lhc, 1); + if (lustre_handle_is_used(&lhc->mlh_reg_lh)) + mdt_object_unlock(info, obj, lhc, 1); } RETURN_EXIT; } -- 1.8.3.1