staging/lustre/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() Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-1602 Lustre-change: http://review.whamcloud.com/3277 Signed-off-by: Andriy Skulysh <Andriy_Skulysh@xyratex.com> Reviewed-by: Vitaly Fertman <vitaly_fertman@xyratex.com> Reviewed-by: Bruce Korb <bruce_korb@xyratex.com> Reviewed-by: Keith Mannthey <keith.mannthey@intel.com> Reviewed-by: Oleg Drokin <oleg.drokin@intel.com> Signed-off-by: Peng Tao <tao.peng@emc.com> Signed-off-by: Andreas Dilger <andreas.dilger@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
251c4317b3
commit
3fa08ae702
1 changed files with 10 additions and 6 deletions
|
@ -198,6 +198,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;
|
||||
|
@ -329,18 +330,21 @@ ldlm_process_flock_lock(struct ldlm_lock *req, __u64 *flags, int first_enq,
|
|||
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);
|
||||
|
|
Loading…
Reference in a new issue