Whamcloud - gitweb
LU-1187 mdt: add sanity check for rename and link
authorwangdi <di.wang@whamcloud.com>
Sun, 21 Oct 2012 10:49:02 +0000 (03:49 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Sun, 3 Feb 2013 00:11:58 +0000 (19:11 -0500)
Add sanity check for rename/link, so remote rename/link
will return EXDEV.

Signed-off-by: wang di <di.wang@whamcloud.com>
Change-Id: I841c8ffaa74b162fcca5cd1661c383215350cccc
Reviewed-on: http://review.whamcloud.com/4348
Tested-by: Hudson
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/mdd/mdd_dir.c
lustre/mdt/mdt_reint.c

index c5f65e8..de42a5c 100644 (file)
@@ -165,16 +165,17 @@ static int mdd_is_parent(const struct lu_env *env,
                         GOTO(out, rc = 1);
                 if (parent)
                         mdd_object_put(env, parent);
-                parent = mdd_object_find(env, mdd, pfid);
-
-                /* cross-ref parent */
-                if (parent == NULL) {
-                        if (pf != NULL)
-                                *pf = *pfid;
-                        GOTO(out, rc = -EREMOTE);
-                } else if (IS_ERR(parent))
-                        GOTO(out, rc = PTR_ERR(parent));
-                p1 = parent;
+
+               parent = mdd_object_find(env, mdd, pfid);
+               if (IS_ERR(parent)) {
+                       GOTO(out, rc = PTR_ERR(parent));
+               } else if (mdd_object_exists(parent) < 0) {
+                       /*FIXME: Because of the restriction of rename in Phase I.
+                        * If the parent is remote, we just assumed lf is not the
+                        * parent of P1 for now */
+                       GOTO(out, rc = 0);
+               }
+               p1 = parent;
         }
         EXIT;
 out:
index 171ee3e..8e362f7 100644 (file)
@@ -892,6 +892,13 @@ static int mdt_reint_link(struct mdt_thread_info *info,
         if (IS_ERR(ms))
                 GOTO(out_unlock_parent, rc = PTR_ERR(ms));
 
+       if (mdt_object_exists(ms) < 0) {
+               mdt_object_put(info->mti_env, ms);
+               CERROR("Target directory "DFID" is on another MDT\n",
+                       PFID(rr->rr_fid1));
+               GOTO(out_unlock_parent, rc = -EXDEV);
+       }
+
         rc = mdt_object_lock(info, ms, lhs, MDS_INODELOCK_UPDATE,
                             MDT_CROSS_LOCK);
         if (rc != 0) {
@@ -1141,7 +1148,12 @@ static int mdt_reint_rename(struct mdt_thread_info *info,
                                 GOTO(out_put_target, rc);
                         /* get and save correct version after locking */
                         mdt_version_get_save(info, mtgtdir, 1);
-                }
+               } else if (rc < 0) {
+                       CERROR("Source dir "DFID" target dir "DFID
+                              "on different MDTs\n", PFID(rr->rr_fid1),
+                              PFID(rr->rr_fid2));
+                       GOTO(out_put_target, rc = -EXDEV);
+               }
         }
 
         /* step 3: find & lock the old object. */
@@ -1155,9 +1167,14 @@ static int mdt_reint_rename(struct mdt_thread_info *info,
         if (lu_fid_eq(old_fid, rr->rr_fid1) || lu_fid_eq(old_fid, rr->rr_fid2))
                 GOTO(out_unlock_target, rc = -EINVAL);
 
-        mold = mdt_object_find(info->mti_env, info->mti_mdt, old_fid);
-        if (IS_ERR(mold))
-                GOTO(out_unlock_target, rc = PTR_ERR(mold));
+       mold = mdt_object_find(info->mti_env, info->mti_mdt, old_fid);
+       if (IS_ERR(mold))
+               GOTO(out_unlock_target, rc = PTR_ERR(mold));
+       if (mdt_object_exists(mold) < 0) {
+               mdt_object_put(info->mti_env, mold);
+               CERROR("Source child "DFID" is on another MDT\n", PFID(old_fid));
+               GOTO(out_unlock_target, rc = -EXDEV);
+       }
 
        if (mdt_object_obf(mold)) {
                mdt_object_put(info->mti_env, mold);
@@ -1203,6 +1220,13 @@ static int mdt_reint_rename(struct mdt_thread_info *info,
                        GOTO(out_unlock_old, rc = -EPERM);
                }
 
+               if (mdt_object_exists(mnew) < 0) {
+                       mdt_object_put(info->mti_env, mnew);
+                       CERROR("Source child "DFID" is on another MDT\n",
+                              PFID(new_fid));
+                       GOTO(out_unlock_old, rc = -EXDEV);
+               }
+
                 rc = mdt_object_lock(info, mnew, lh_newp,
                                      MDS_INODELOCK_FULL, MDT_CROSS_LOCK);
                 if (rc != 0) {