Whamcloud - gitweb
LU-4471 mdd: mdd_unlink: do trans_start after sanity check 27/8827/11
authorPatrick Farrell <paf@cray.com>
Wed, 22 Jan 2014 19:04:26 +0000 (13:04 -0600)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 25 Feb 2014 20:32:07 +0000 (20:32 +0000)
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 <paf@cray.com>
Change-Id: I08882b682b9f0016577214821efec4759ee5c184
Reviewed-on: http://review.whamcloud.com/8827
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
lustre/mdd/mdd_dir.c
lustre/tests/sanity.sh

index b993174..d6bf64b 100644 (file)
@@ -1500,6 +1500,19 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj,
        if (rc)
                RETURN(rc);
 
        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));
        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 (rc)
                GOTO(stop, rc);
 
-       if (likely(mdd_cobj != NULL)) {
+       if (likely(mdd_cobj != NULL))
                mdd_write_lock(env, mdd_cobj, MOR_TGT_CHILD);
 
                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));
        if (likely(no_name == 0)) {
                rc = __mdd_index_delete(env, mdd_pobj, name, is_dir, handle,
                                        mdd_object_capa(env, mdd_pobj));
index 4a0ebee..5f5e8b2 100644 (file)
@@ -193,6 +193,24 @@ test_3() {
 }
 run_test 3 "mkdir; touch; rmdir; check dir ====================="
 
 }
 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"
 test_5() {
        test_mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
        test_mkdir $DIR/$tdir/d2 || error "mkdir $tdir/d2 failed"