From 5b8b66ee9205fa7076ce0da0d8685e8ef98a261f Mon Sep 17 00:00:00 2001 From: Vitaly Fertman Date: Fri, 15 Aug 2014 15:09:39 +0400 Subject: [PATCH] LU-5496 ldlm: granting the same lock twice on recovery the previous fix was not correct, check for resend before removing from resource, otherwise conflicts can be granted in parallel. also, some minor cleanups. Signed-off-by: Vitaly Fertman Change-Id: I461608878d40d6bba4e23179a7379de835d526c3 Reviewed-by: Andriy Skulysh Reviewed-by: Alexander Boyko Tested-by: Alexander Lezhoev Xyratex-bug-id: MRP-1944 Reviewed-on: http://review.whamcloud.com/11469 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin Reviewed-by: Bobi Jam --- lustre/ldlm/ldlm_lock.c | 5 +++-- lustre/mdt/mdt_reint.c | 4 ++++ lustre/tests/sanityn.sh | 14 +++++--------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lustre/ldlm/ldlm_lock.c b/lustre/ldlm/ldlm_lock.c index 8d4a39a..588a8a9 100644 --- a/lustre/ldlm/ldlm_lock.c +++ b/lustre/ldlm/ldlm_lock.c @@ -1661,6 +1661,9 @@ ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns, } } + if (*flags & LDLM_FL_RESENT) + RETURN(ELDLM_OK); + /* For a replaying lock, it might be already in granted list. So * unlinking the lock will cause the interval node to be freed, we * have to allocate the interval node early otherwise we can't regrant @@ -1717,8 +1720,6 @@ ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *ns, ldlm_grant_lock(lock, NULL); GOTO(out, rc = ELDLM_OK); #ifdef HAVE_SERVER_SUPPORT - } else if (*flags & LDLM_FL_RESENT) { - GOTO(out, rc = ELDLM_OK); } else if (*flags & LDLM_FL_REPLAY) { if (*flags & LDLM_FL_BLOCK_CONV) { ldlm_resource_add_lock(res, &res->lr_converting, lock); diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 063ddd3..d2c36c2 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -1863,6 +1863,10 @@ static int mdt_reint_rename_internal(struct mdt_thread_info *info, GOTO(out_put_new, rc = -EXDEV); } + /* Before locking the target dir, check we do not replace + * a dir with a non-dir, otherwise it may deadlock with + * link op which tries to create a link in this dir + * back to this non-dir. */ if (S_ISDIR(lu_object_attr(&mnew->mot_obj)) && !S_ISDIR(lu_object_attr(&mold->mot_obj))) GOTO(out_put_new, rc = -EISDIR); diff --git a/lustre/tests/sanityn.sh b/lustre/tests/sanityn.sh index 6edb104..adbc37b 100644 --- a/lustre/tests/sanityn.sh +++ b/lustre/tests/sanityn.sh @@ -2496,22 +2496,18 @@ test_55d() #define OBD_FAIL_MDS_RENAME3 0x155 do_facet mds $LCTL set_param fail_loc=0x155 - mv $DIR/f1 $DIR/d1 & + mv $DIR/f1 $DIR/$tdir & PID1=$! sleep 2 - # while rename is sleeping, create d2, but as a directory - mkdir -p $DIR2/d1 || error "(1) mkdir failed" + # while rename is sleeping, create $tdir, but as a directory + mkdir -p $DIR2/$tdir || error "(1) mkdir failed" # link in reverse locking order - ln $DIR2/f1 $DIR2/d1/ + ln $DIR2/f1 $DIR2/$tdir/ wait $PID1 && error "(2) mv succeeded" - lctl dk > ../log1 - ls -la $DIR/ - ls -la $DIR/d1 - - rm -rf $DIR/d1 + rm -rf $DIR/f1 } run_test 55d "rename file vs link" -- 1.8.3.1