From 64fb5f52a2d5a1e6a7e24ffff8fd7d60007a351e 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 a95cef8..4e4a2c3 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -1276,6 +1276,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); @@ -1365,12 +1374,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