Whamcloud - gitweb
LU-4659 mdd: rename forgets updating target linkea 09/10409/2
authorLai Siyao <lai.siyao@intel.com>
Mon, 24 Feb 2014 10:13:35 +0000 (18:13 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 27 May 2014 15:44:16 +0000 (15:44 +0000)
MDD rename forgets updating target LinkEA if target is not unlinked,
which will cause LinkEA inconsistency.

Lustre-commit: 2d6315fbeab3c815efa3ea7b953ff34e6f3fa3fc
Lustre-change: http://review.whamcloud.com/9745

Signed-off-by: Lai Siyao <lai.siyao@intel.com>
Signed-off-by: Bob Glossman <bob.glossman@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
Change-Id: I348c58e4a11e7b0ba31befef8922dfe47cee755c
Reviewed-on: http://review.whamcloud.com/10409
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
lustre/mdd/mdd_dir.c
lustre/mdd/mdd_internal.h
lustre/tests/sanity.sh

index a8a0caa..33a4d1c 100644 (file)
@@ -1293,16 +1293,22 @@ int mdd_declare_finish_unlink(const struct lu_env *env,
        int     rc;
 
        rc = orph_declare_index_insert(env, obj, mdd_object_type(obj), handle);
-       if (rc)
+       if (rc != 0)
+               return rc;
+
+       rc = mdo_declare_destroy(env, obj, handle);
+       if (rc != 0)
                return rc;
 
-       return mdo_declare_destroy(env, obj, handle);
+       return mdd_declare_links_del(env, obj, handle);
 }
 
 /* caller should take a lock before calling */
 int mdd_finish_unlink(const struct lu_env *env,
-                      struct mdd_object *obj, struct md_attr *ma,
-                      struct thandle *th)
+                     struct mdd_object *obj, struct md_attr *ma,
+                     const struct mdd_object *pobj,
+                     const struct lu_name *lname,
+                     struct thandle *th)
 {
        int rc = 0;
         int is_dir = S_ISDIR(ma->ma_attr.la_mode);
@@ -1330,8 +1336,11 @@ int mdd_finish_unlink(const struct lu_env *env,
                                         obj->mod_count);
                 } else {
                        rc = mdo_destroy(env, obj, th);
-                }
-        }
+               }
+       } else if (!is_dir) {
+               /* old files may not have link ea; ignore errors */
+               mdd_links_del(env, obj, mdo2fid(pobj), lname, th);
+       }
 
         RETURN(rc);
 }
@@ -1394,10 +1403,6 @@ static int mdd_declare_unlink(const struct lu_env *env, struct mdd_device *mdd,
                if (rc)
                        return rc;
 
-               rc = mdd_declare_links_del(env, c, handle);
-               if (rc != 0)
-                       return rc;
-
                /* FIXME: need changelog for remove entry */
                rc = mdd_declare_changelog_store(env, mdd, name, handle);
        }
@@ -1552,17 +1557,13 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj,
        /* XXX: this transfer to ma will be removed with LOD/OSP */
        ma->ma_attr = *cattr;
        ma->ma_valid |= MA_INODE;
-       rc = mdd_finish_unlink(env, mdd_cobj, ma, handle);
+       rc = mdd_finish_unlink(env, mdd_cobj, ma, mdd_pobj, lname, handle);
 
        /* fetch updated nlink */
        if (rc == 0)
                rc = mdd_la_get(env, mdd_cobj, cattr,
                                mdd_object_capa(env, mdd_cobj));
 
-       if (!is_dir)
-               /* old files may not have link ea; ignore errors */
-               mdd_links_del(env, mdd_cobj, mdo2fid(mdd_pobj), lname, handle);
-
        /* if object is removed then we can't get its attrs, use last get */
        if (cattr->la_nlink == 0) {
                ma->ma_attr = *cattr;
@@ -2428,10 +2429,6 @@ static int mdd_declare_rename(const struct lu_env *env,
                if (rc)
                        return rc;
 
-               rc = mdd_declare_links_del(env, mdd_tobj, handle);
-               if (rc)
-                       return rc;
-
                rc = mdd_declare_finish_unlink(env, mdd_tobj, ma, handle);
                if (rc)
                        return rc;
@@ -2613,7 +2610,8 @@ static int mdd_rename(const struct lu_env *env,
                /* XXX: this transfer to ma will be removed with LOD/OSP */
                ma->ma_attr = *tg_attr;
                ma->ma_valid |= MA_INODE;
-               rc = mdd_finish_unlink(env, mdd_tobj, ma, handle);
+               rc = mdd_finish_unlink(env, mdd_tobj, ma, mdd_tpobj, ltname,
+                                      handle);
                if (rc != 0) {
                        CERROR("%s: Failed to unlink tobj "
                                DFID": rc = %d\n",
index 4f5d0a6..3353641 100644 (file)
@@ -269,7 +269,8 @@ int mdd_may_delete(const struct lu_env *env, struct mdd_object *pobj,
 int mdd_unlink_sanity_check(const struct lu_env *env, struct mdd_object *pobj,
                            struct mdd_object *cobj, struct lu_attr *cattr);
 int mdd_finish_unlink(const struct lu_env *env, struct mdd_object *obj,
-                      struct md_attr *ma, struct thandle *th);
+                     struct md_attr *ma, const struct mdd_object *pobj,
+                     const struct lu_name *lname, struct thandle *th);
 
 int mdd_link_sanity_check(const struct lu_env *env, struct mdd_object *tgt_obj,
                           const struct lu_name *lname, struct mdd_object *src_obj);
index f90252f..97178c5 100644 (file)
@@ -12050,6 +12050,22 @@ test_236() {
 }
 run_test 236 "Layout swap on open unlinked file"
 
+# LU-4659 linkea consistency
+test_238() {
+       touch $DIR/$tfile
+       ln $DIR/$tfile $DIR/$tfile.lnk
+       touch $DIR/$tfile.new
+       mv $DIR/$tfile.new $DIR/$tfile
+       local fid1=$(lfs path2fid $DIR/$tfile)
+       local fid2=$(lfs path2fid $DIR/$tfile.lnk)
+       local path1=$(lfs fid2path $FSNAME $fid1)
+       [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
+       local path2=$(lfs fid2path $FSNAME $fid2)
+       [ $tfile.lnk == $path2 ] ||
+               error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
+       rm -f $DIR/$tfile*
+}
+run_test 238 "Verify linkea consistency"
 #
 # tests that do cleanup/setup should be run at the end
 #