Whamcloud - gitweb
LU-4870 lfsck: lock old MDT-object in migrating
[fs/lustre-release.git] / lustre / lfsck / lfsck_layout.c
index 02dc24a..e150328 100644 (file)
@@ -3087,6 +3087,7 @@ static int lfsck_layout_check_parent(const struct lu_env *env,
        struct dt_object                *tobj;
        struct lov_mds_md_v1            *lmm;
        struct lov_ost_data_v1          *objs;
+       struct lustre_handle             lh     = { 0 };
        int                              rc;
        int                              i;
        __u32                            magic;
@@ -3120,7 +3121,6 @@ static int lfsck_layout_check_parent(const struct lu_env *env,
        if (IS_ERR(tobj))
                RETURN(PTR_ERR(tobj));
 
-       dt_read_lock(env, tobj, 0);
        if (dt_object_exists(tobj) == 0 ||
            lfsck_is_dead_obj(tobj))
                GOTO(out, rc = LLIT_UNMATCHED_PAIR);
@@ -3170,16 +3170,60 @@ static int lfsck_layout_check_parent(const struct lu_env *env,
                }
 
                if (lu_fid_eq(cfid, tfid)) {
-                       *lov_ea = *buf;
+                       rc = lfsck_ibits_lock(env, com->lc_lfsck, tobj, &lh,
+                                             MDS_INODELOCK_UPDATE |
+                                             MDS_INODELOCK_LAYOUT |
+                                             MDS_INODELOCK_XATTR,
+                                             LCK_EX);
+                       if (rc != 0)
+                               GOTO(out, rc);
+
+                       dt_read_lock(env, tobj, 0);
+
+                       /* For local MDT-object, re-check existence
+                        * after taken the lock. */
+                       if (!dt_object_remote(tobj)) {
+                               if (dt_object_exists(tobj) == 0 ||
+                                   lfsck_is_dead_obj(tobj)) {
+                                       rc = LLIT_UNMATCHED_PAIR;
+                               } else {
+                                       *lov_ea = *buf;
+                                       rc = LLIT_MULTIPLE_REFERENCED;
+                               }
+
+                               GOTO(unlock, rc);
+                       }
+
+                       /* For migration case, the new MDT-object and old
+                        * MDT-object may reference the same OST-object at
+                        * some migration internal time.
+                        *
+                        * For remote MDT-object, the local MDT may not know
+                        * whether it has been removed or not.  Try checking
+                        * for a non-existent xattr to check if this object
+                        * has been been removed or not. */
+                       rc = dt_xattr_get(env, tobj, &LU_BUF_NULL,
+                                         XATTR_NAME_DUMMY, BYPASS_CAPA);
+                       if (unlikely(rc == -ENOENT || rc >= 0)) {
+                               rc = LLIT_UNMATCHED_PAIR;
+                       } else if (rc == -ENODATA) {
+                               *lov_ea = *buf;
+                               rc = LLIT_MULTIPLE_REFERENCED;
+                       }
 
-                       GOTO(out, rc = LLIT_MULTIPLE_REFERENCED);
+                       GOTO(unlock, rc);
                }
        }
 
        GOTO(out, rc = LLIT_UNMATCHED_PAIR);
 
+unlock:
+       if (lustre_handle_is_used(&lh)) {
+               dt_read_unlock(env, tobj);
+               lfsck_ibits_unlock(&lh, LCK_EX);
+       }
+
 out:
-       dt_read_unlock(env, tobj);
        lfsck_object_put(env, tobj);
 
        return rc;