From: Patrick Farrell Date: Wed, 22 Jan 2014 19:04:26 +0000 (-0600) Subject: LU-4471 mdd: mdd_unlink: do trans_start after sanity check X-Git-Tag: 2.5.57~74 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=1f55f2a9071d5e7db4042b959723086dee1c379a LU-4471 mdd: mdd_unlink: do trans_start after sanity check Currently, mdd_trans_start is called before mdd_unlink_sanity_check. This means a remote directory which has files in it can be removed on MDT0 before the sanity check on MDT1 finds the files and errors, which orphans the files on MDT1. This patch moves the sanity check before mdd_trans_create and mdd_trans_start. Signed-off-by: Patrick Farrell Change-Id: I08882b682b9f0016577214821efec4759ee5c184 Reviewed-on: http://review.whamcloud.com/8827 Reviewed-by: Andreas Dilger Reviewed-by: Fan Yong Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Alex Zhuravlev --- diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index b993174..d6bf64b 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -1500,6 +1500,19 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, if (rc) RETURN(rc); + if (likely(mdd_cobj != NULL)) { + /* fetch cattr */ + rc = mdd_la_get(env, mdd_cobj, cattr, BYPASS_CAPA); + if (rc) + RETURN(rc); + + is_dir = S_ISDIR(cattr->la_mode); + } + + rc = mdd_unlink_sanity_check(env, mdd_pobj, pattr, mdd_cobj, cattr); + if (rc) + RETURN(rc); + handle = mdd_trans_create(env, mdd); if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); @@ -1513,21 +1526,9 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, if (rc) GOTO(stop, rc); - if (likely(mdd_cobj != NULL)) { + if (likely(mdd_cobj != NULL)) mdd_write_lock(env, mdd_cobj, MOR_TGT_CHILD); - /* fetch cattr */ - rc = mdd_la_get(env, mdd_cobj, cattr, BYPASS_CAPA); - if (rc) - GOTO(cleanup, rc); - - is_dir = S_ISDIR(cattr->la_mode); - } - - rc = mdd_unlink_sanity_check(env, mdd_pobj, pattr, mdd_cobj, cattr); - if (rc) - GOTO(cleanup, rc); - if (likely(no_name == 0)) { rc = __mdd_index_delete(env, mdd_pobj, name, is_dir, handle, mdd_object_capa(env, mdd_pobj)); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 4a0ebee..5f5e8b2 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -193,6 +193,24 @@ test_3() { } run_test 3 "mkdir; touch; rmdir; check dir =====================" +# LU-4471 - failed rmdir on remote directories still removes directory on MDT0 +test_4() { + local MDTIDX=1 + local remote_dir=remote_dir + + test_mkdir $DIR/$remote_dir || + error "Create remote directory failed" + + touch $DIR/$remote_dir/$tfile || + error "Create file under remote directory failed" + + rmdir $DIR/$remote_dir && + error "Expect error removing in-use dir $DIR/$remote_dir" + + test -d $DIR/$remote_dir || error "Remote directory disappeared" +} +run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)" + test_5() { test_mkdir -p $DIR/$tdir || error "mkdir $tdir failed" test_mkdir $DIR/$tdir/d2 || error "mkdir $tdir/d2 failed"