From f3fedc4c816777e9ff65ca9b423c33c0920d2dd6 Mon Sep 17 00:00:00 2001 From: Rahul Deshmukh Date: Fri, 29 Aug 2014 17:21:59 -0700 Subject: [PATCH] LU-5144 mdt: rename vs link deadlock it may happen that tgt child for rename is a directory, which is used as tgt dir for link in parallel, as the result rename locks src child, tgt child what may deadlock with tgt dir, src file locking of link. As not dir cannot replace dir, check it before locking the tgt child. Lustre-commit: b2c2cfc24fa461b3e54cd204a697eeee9a89d49c Lustre-change: http://review.whamcloud.com/10570/ Test-Parameters: alwaysuploadlogs \ envdefinitions=SLOW=yes,ENABLE_QUOTA=yes,ONLY=55 \ ossjob=lustre-b2_4 mdsjob=lustre-b2_4 ossbuildno=73 mdsbuildno=73 \ testlist=sanityn Signed-off-by: Vitaly Fertman Signed-off-by: Rahul Deshmukh Change-Id: I09e96b132d9069d4818e8dc2628c903eff38e53d Reviewed-on: http://review.whamcloud.com/10918 Reviewed-by: James Simmons Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/mdt/mdt_reint.c | 10 ++++++++++ lustre/tests/sanityn.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index f1590d3..efb9d99 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -942,6 +942,8 @@ static int mdt_reint_link(struct mdt_thread_info *info, if (rc) GOTO(out_unlock_parent, rc); + OBD_FAIL_TIMEOUT(OBD_FAIL_MDS_RENAME3, 5); + /* step 2: find & lock the source */ lhs = &info->mti_lh[MDT_LH_CHILD]; mdt_lock_reg_init(lhs, LCK_EX); @@ -1401,6 +1403,14 @@ static int mdt_reint_rename(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); + /* Check if @msrcdir is subdir of @mnew, before locking child * to avoid reverse locking. */ rc = mdt_is_subdir_internal(info, msrcdir, new_fid); diff --git a/lustre/tests/sanityn.sh b/lustre/tests/sanityn.sh index ec6eb3f..01ad843 100644 --- a/lustre/tests/sanityn.sh +++ b/lustre/tests/sanityn.sh @@ -2535,6 +2535,37 @@ test_55c() { } run_test 55c "rename vs unlink orphan target dir" +test_55d() { + local server_version=$(lustre_version_code $SINGLEMDS) + + [[ $server_version -gt $(version_code 2.5.58) ]] || + [[ $server_version -gt $(version_code 2.5.3) && + $server_version -lt $(version_code 2.5.50) ]] || + { skip "Need MDS version at least 2.5.59 or 2.5.4"; return; } + + touch $DIR/f1 + +#define OBD_FAIL_MDS_RENAME3 0x155 + do_facet mds $LCTL set_param fail_loc=0x155 + mv $DIR/f1 $DIR/d1 & + PID1=$! + sleep 2 + + # while rename is sleeping, create d2, but as a directory + mkdir -p $DIR2/d1 || error "(1) mkdir failed" + + # link in reverse locking order + ln $DIR2/f1 $DIR2/d1/ + + wait $PID1 && error "(2) mv succeeded" + lctl dk > ../log1 + ls -la $DIR/ + ls -la $DIR/d1 + + rm -rf $DIR/d1 +} +run_test 55d "rename file vs link" + test_60() { [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.3.0) ]] || { skip "Need MDS version at least 2.3.0"; return; } -- 1.8.3.1