From: Andriy Skulysh Date: Mon, 21 Jan 2013 21:15:23 +0000 (+0200) Subject: LU-1602 ldlm: Fix flock deadlock detection race X-Git-Tag: 2.4.51~3 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=bbe7043202fa9750369e7f027f1b96393b49b1dc LU-1602 ldlm: Fix flock deadlock detection race Deadlock isn't detected if 2 threads are trying to grant 2 locks which deadlock on each other. They call ldlm_flock_deadlock() simultaneously and deadlock ins't detected. The soulition is to add lock to blocking list before calling ldlm_flock_deadlock() Xyratex-bug-id: MRP-412 Signed-off-by: Andriy Skulysh Reviewed-by: Vitaly Fertman Reviewed-by: Bruce Korb Change-Id: I437c8b40a58de14bbac3da39d98d0f03d0f2e064 Reviewed-on: http://review.whamcloud.com/3277 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Keith Mannthey Reviewed-by: Oleg Drokin --- diff --git a/lustre/ldlm/ldlm_flock.c b/lustre/ldlm/ldlm_flock.c index c880dc0..5b40b3e 100644 --- a/lustre/ldlm/ldlm_flock.c +++ b/lustre/ldlm/ldlm_flock.c @@ -203,6 +203,7 @@ ldlm_flock_deadlock(struct ldlm_lock *req, struct ldlm_lock *bl_lock) if (lock == NULL) break; + LASSERT(req != lock); flock = &lock->l_policy_data.l_flock; LASSERT(flock->owner == bl_owner); bl_owner = flock->blocking_owner; @@ -334,18 +335,21 @@ reprocess: RETURN(LDLM_ITER_STOP); } - if (ldlm_flock_deadlock(req, lock)) { - ldlm_flock_destroy(req, mode, *flags); - *err = -EDEADLK; - RETURN(LDLM_ITER_STOP); - } - + /* add lock to blocking list before deadlock + * check to prevent race */ rc = ldlm_flock_blocking_link(req, lock); if (rc) { ldlm_flock_destroy(req, mode, *flags); *err = rc; RETURN(LDLM_ITER_STOP); } + if (ldlm_flock_deadlock(req, lock)) { + ldlm_flock_blocking_unlink(req); + ldlm_flock_destroy(req, mode, *flags); + *err = -EDEADLK; + RETURN(LDLM_ITER_STOP); + } + ldlm_resource_add_lock(res, &res->lr_waiting, req); *flags |= LDLM_FL_BLOCK_GRANTED; RETURN(LDLM_ITER_STOP);