Whamcloud - gitweb
LU-13124 scrub: check for multiple linked file
[fs/lustre-release.git] / lustre / lfsck / lfsck_layout.c
index aad367c..e11968e 100644 (file)
@@ -96,9 +96,9 @@ struct lfsck_layout_slave_async_args {
        struct lfsck_layout_slave_target *llsaa_llst;
 };
 
-static inline bool lfsck_comp_extent_aligned(__u64 size)
+static inline bool lfsck_comp_extent_aligned(__u64 border, __u32 size)
 {
-        return (size & (LOV_MIN_STRIPE_SIZE - 1)) == 0;
+       return (border & (size - 1)) == 0;
 }
 
 static inline void
@@ -209,7 +209,7 @@ static void lfsck_layout_assistant_req_fini(const struct lu_env *env,
                                            struct lfsck_assistant_req *lar)
 {
        struct lfsck_layout_req *llr =
-                       container_of0(lar, struct lfsck_layout_req, llr_lar);
+               container_of(lar, struct lfsck_layout_req, llr_lar);
 
        lfsck_object_put(env, llr->llr_child);
        lfsck_assistant_object_put(env, lar->lar_parent);
@@ -329,10 +329,13 @@ out:
 
 static int lfsck_layout_verify_header_v1v3(struct dt_object *obj,
                                           struct lov_mds_md_v1 *lmm,
-                                          __u64 start, __u32 comp_id)
+                                          __u64 start, __u64 end,
+                                          __u32 comp_id,
+                                          bool ext, bool *dom)
 {
        __u32 magic;
        __u32 pattern;
+       __u32 size;
 
        magic = le32_to_cpu(lmm->lmm_magic);
        /* If magic crashed, keep it there. Sometime later, during OST-object
@@ -346,7 +349,7 @@ static int lfsck_layout_verify_header_v1v3(struct dt_object *obj,
                else
                        rc = -EINVAL;
 
-               CDEBUG(D_LFSCK, "%s LOV EA magic %u for the file "DFID"\n",
+               CDEBUG(D_LFSCK, "%s LOV EA magic 0x%X for the file "DFID"\n",
                       rc == -EINVAL ? "Unknown" : "Unsupported",
                       magic, PFID(lfsck_dto2fid(obj)));
 
@@ -354,10 +357,11 @@ static int lfsck_layout_verify_header_v1v3(struct dt_object *obj,
        }
 
        pattern = le32_to_cpu(lmm->lmm_pattern);
+       *dom = !!(lov_pattern(pattern) == LOV_PATTERN_MDT);
 
-#if 0
        /* XXX: DoM file verification will be supportted via LU-11081. */
        if (lov_pattern(pattern) == LOV_PATTERN_MDT) {
+#if 0
                if (start != 0) {
                        CDEBUG(D_LFSCK, "The DoM entry for "DFID" is not "
                               "the first component in the mirror %x/%llu\n",
@@ -365,10 +369,8 @@ static int lfsck_layout_verify_header_v1v3(struct dt_object *obj,
 
                        return -EINVAL;
                }
-       }
 #endif
-
-       if (!lov_pattern_supported_normal_comp(lov_pattern(pattern))) {
+       } else if (!lov_pattern_supported_normal_comp(lov_pattern(pattern))) {
                CDEBUG(D_LFSCK, "Unsupported LOV EA pattern %u for the file "
                       DFID" in the component %x\n",
                       pattern, PFID(lfsck_dto2fid(obj)), comp_id);
@@ -376,6 +378,17 @@ static int lfsck_layout_verify_header_v1v3(struct dt_object *obj,
                return -EOPNOTSUPP;
        }
 
+       size = le32_to_cpu(lmm->lmm_stripe_size);
+       if (!ext && end != LUSTRE_EOF && start != end &&
+           !lfsck_comp_extent_aligned(end, size)){
+               CDEBUG(D_LFSCK, "not aligned border in PFL extent range "
+                      "[%llu - %llu) stripesize %u for the file "DFID
+                      " at idx %d\n", start, end, size,
+                      PFID(lfsck_dto2fid(obj)), comp_id);
+
+               return -EINVAL;
+       }
+
        return 0;
 }
 
@@ -403,10 +416,13 @@ static int lfsck_layout_verify_header_foreign(struct dt_object *obj,
 static int lfsck_layout_verify_header(struct dt_object *obj,
                                      struct lov_mds_md_v1 *lmm, size_t len)
 {
+       bool p_dom = false;
        int rc = 0;
 
-       if (le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC_COMP_V1) {
+       if (le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC_COMP_V1 ||
+           le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC_SEL) {
                struct lov_comp_md_v1 *lcm = (struct lov_comp_md_v1 *)lmm;
+               bool p_zero = false;
                int i;
                __u16 count = le16_to_cpu(lcm->lcm_entry_count);
 
@@ -424,39 +440,72 @@ static int lfsck_layout_verify_header(struct dt_object *obj,
                        __u64 start = le64_to_cpu(lcme->lcme_extent.e_start);
                        __u64 end = le64_to_cpu(lcme->lcme_extent.e_end);
                        __u32 comp_id = le32_to_cpu(lcme->lcme_id);
+                       bool ext, inited, zero;
+                       __u32 flags;
 
                        if (unlikely(comp_id == LCME_ID_INVAL ||
                                     comp_id > LCME_ID_MAX)) {
-                               CDEBUG(D_LFSCK, "found invalid FPL ID %u "
+                               CDEBUG(D_LFSCK, "found invalid PFL ID %u "
                                       "for the file "DFID" at idx %d\n",
                                       comp_id, PFID(lfsck_dto2fid(obj)), i);
 
                                return -EINVAL;
                        }
 
-                       if (unlikely(start >= end ||
-                                    !lfsck_comp_extent_aligned(start) ||
-                                    (!lfsck_comp_extent_aligned(end) &&
-                                     end != LUSTRE_EOF))) {
-                               CDEBUG(D_LFSCK, "found invalid FPL extent "
-                                      "range [%llu - %llu) for the file "
-                                      DFID" at idx %d\n",
-                                      start, end, PFID(lfsck_dto2fid(obj)), i);
+                       flags = le32_to_cpu(lcme->lcme_flags);
+                       ext = flags & LCME_FL_EXTENSION;
+                       inited = flags & LCME_FL_INIT;
+                       zero = !!(start == end);
+
+                       if ((i == 0) && zero) {
+                               CDEBUG(D_LFSCK, "invalid PFL comp %d: [%llu "
+                                      "- %llu) for "DFID"\n", i, start, end,
+                                      PFID(lfsck_dto2fid(obj)));
+                               return -EINVAL;
+                       }
+
+                       if ((zero && (inited || (i + 1 == count))) ||
+                           (start > end)) {
+                               CDEBUG(D_LFSCK, "invalid PFL comp %d/%d: "
+                                      "[%llu, %llu) for "DFID", %sinited\n",
+                                      i, count, start, end,
+                                      PFID(lfsck_dto2fid(obj)),
+                                      inited ? "" : "NOT ");
+                               return -EINVAL;
+                       }
+
+                       if (!ext && p_zero) {
+                               CDEBUG(D_LFSCK, "invalid PFL comp %d: [%llu, "
+                                      "%llu) for "DFID": NOT extension "
+                                      "after 0-length component\n", i,
+                                      start, end, PFID(lfsck_dto2fid(obj)));
+                               return -EINVAL;
+                       }
 
+                       if (ext && (inited || p_dom || zero)) {
+                               CDEBUG(D_LFSCK, "invalid PFL comp %d: [%llu, "
+                                      "%llu) for "DFID": %s\n", i,
+                                      start, end, PFID(lfsck_dto2fid(obj)),
+                                      inited ? "inited extension" :
+                                      p_dom ? "extension follows DOM" :
+                                      zero ? "zero length extension" : "");
                                return -EINVAL;
                        }
 
                        rc = lfsck_layout_verify_header_v1v3(obj,
                                        (struct lov_mds_md_v1 *)((char *)lmm +
                                        le32_to_cpu(lcme->lcme_offset)), start,
-                                       comp_id);
+                                       end, comp_id, ext, &p_dom);
+
+                       p_zero = zero;
                }
        } else if (le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC_FOREIGN) {
                rc = lfsck_layout_verify_header_foreign(obj,
                                                (struct lov_foreign_md *)lmm,
                                                len);
        } else {
-               rc = lfsck_layout_verify_header_v1v3(obj, lmm, 1, 0);
+               rc = lfsck_layout_verify_header_v1v3(obj, lmm, 0, LUSTRE_EOF,
+                                                    0, false, &p_dom);
        }
 
        return rc;
@@ -647,7 +696,7 @@ lfsck_rbtree_insert(struct lfsck_layout_slave_data *llsd,
        return lrn;
 }
 
-extern const struct dt_index_operations lfsck_orphan_index_ops;
+static const struct dt_index_operations lfsck_orphan_index_ops;
 
 static int lfsck_rbtree_setup(const struct lu_env *env,
                              struct lfsck_component *com)
@@ -1199,7 +1248,7 @@ lfsck_layout_lastid_create(const struct lu_env *env,
        memset(dof, 0, sizeof(*dof));
        dof->dof_type = dt_mode_to_dft(S_IFREG);
 
-       th = dt_trans_create(env, dt);
+       th = lfsck_trans_create(env, dt, lfsck);
        if (IS_ERR(th))
                GOTO(log, rc = PTR_ERR(th));
 
@@ -1314,7 +1363,7 @@ lfsck_layout_lastid_store(const struct lu_env *env,
                        continue;
                }
 
-               th = dt_trans_create(env, dt);
+               th = lfsck_trans_create(env, dt, lfsck);
                if (IS_ERR(th)) {
                        rc1 = PTR_ERR(th);
                        CDEBUG(D_LFSCK, "%s: layout LFSCK failed to store "
@@ -1391,23 +1440,15 @@ lfsck_layout_lastid_load(const struct lu_env *env,
 
                        if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_DELAY4) &&
                            cfs_fail_val > 0) {
-                               struct l_wait_info lwi = LWI_TIMEOUT(
-                                               cfs_time_seconds(cfs_fail_val),
-                                               NULL, NULL);
-
-                               /* Some others may changed the cfs_fail_val
-                                * as zero after above check, re-check it for
-                                * sure to avoid falling into wait for ever. */
-                               if (likely(lwi.lwi_timeout > 0)) {
-                                       struct ptlrpc_thread *thread =
-                                               &lfsck->li_thread;
-
-                                       up_write(&com->lc_sem);
-                                       l_wait_event(thread->t_ctl_waitq,
-                                                    !thread_is_running(thread),
-                                                    &lwi);
-                                       down_write(&com->lc_sem);
-                               }
+                               struct ptlrpc_thread *thread =
+                                       &lfsck->li_thread;
+
+                               up_write(&com->lc_sem);
+                               wait_event_idle_timeout(
+                                       thread->t_ctl_waitq,
+                                       !thread_is_running(thread),
+                                       cfs_time_seconds(cfs_fail_val));
+                               down_write(&com->lc_sem);
                        }
                }
 
@@ -1570,7 +1611,7 @@ static int lfsck_layout_ins_dangling_rec(const struct lu_env *env,
 
        mutex_lock(&com->lc_sub_trace_objs[idx].lsto_mutex);
 
-       th = dt_trans_create(env, dev);
+       th = lfsck_trans_create(env, dev, com->lc_lfsck);
        if (IS_ERR(th))
                GOTO(unlock, rc = PTR_ERR(th));
 
@@ -1626,7 +1667,7 @@ static int lfsck_layout_del_dangling_rec(const struct lu_env *env,
 
        mutex_lock(&com->lc_sub_trace_objs[idx].lsto_mutex);
 
-       th = dt_trans_create(env, dev);
+       th = lfsck_trans_create(env, dev, com->lc_lfsck);
        if (IS_ERR(th))
                GOTO(unlock, rc = PTR_ERR(th));
 
@@ -2162,6 +2203,7 @@ static int lfsck_layout_update_lovea(const struct lu_env *env,
 }
 
 static int __lfsck_layout_update_pfid(const struct lu_env *env,
+                                     struct lfsck_component *com,
                                      struct dt_object *child,
                                      const struct lu_fid *pfid,
                                      const struct ost_layout *ol, __u32 offset,
@@ -2184,7 +2226,7 @@ static int __lfsck_layout_update_pfid(const struct lu_env *env,
        ff->ff_range = cpu_to_le32(range);
        lfsck_buf_init(&buf, ff, sizeof(*ff));
 
-       handle = dt_trans_create(env, dev);
+       handle = lfsck_trans_create(env, dev, com->lc_lfsck);
        if (IS_ERR(handle))
                RETURN(PTR_ERR(handle));
 
@@ -2226,7 +2268,7 @@ static int lfsck_layout_update_pfid(const struct lu_env *env,
        if (IS_ERR(child))
                RETURN(PTR_ERR(child));
 
-       rc = __lfsck_layout_update_pfid(env, child,
+       rc = __lfsck_layout_update_pfid(env, com, child,
                                        lu_object_fid(&parent->do_lu),
                                        &rec->lor_layout, ea_off,
                                        rec->lor_layout_version,
@@ -2337,6 +2379,9 @@ static int lfsck_layout_recreate_parent(const struct lu_env *env,
        int                              rc     = 0;
        ENTRY;
 
+       if (lfsck_is_dryrun(lfsck))
+               GOTO(log, rc = 0);
+
        if (unlikely(lpf == NULL))
                GOTO(log, rc = -ENXIO);
 
@@ -2391,8 +2436,7 @@ again:
        do {
                snprintf(name, NAME_MAX, DFID"%s-%s-%d", PFID(pfid), infix,
                         type, idx++);
-               rc = dt_lookup(env, lfsck->li_lpf_obj, (struct dt_rec *)tfid,
-                              (const struct dt_key *)name);
+               rc = dt_lookup_dir(env, lfsck->li_lpf_obj, name, tfid);
                if (rc != 0 && rc != -ENOENT)
                        GOTO(log, rc);
        } while (rc == 0);
@@ -2404,8 +2448,7 @@ again:
 
        /* Re-check whether the name conflict with othrs after taken
         * the ldlm lock. */
-       rc = dt_lookup(env, lfsck->li_lpf_obj, (struct dt_rec *)tfid,
-                      (const struct dt_key *)name);
+       rc = dt_lookup_dir(env, lfsck->li_lpf_obj, name, tfid);
        if (unlikely(rc == 0)) {
                lfsck_unlock(llh);
                goto again;
@@ -2421,7 +2464,7 @@ again:
                GOTO(unlock, rc);
 
        /* The 1st transaction. */
-       th = dt_trans_create(env, dev);
+       th = lfsck_trans_create(env, dev, lfsck);
        if (IS_ERR(th))
                GOTO(unlock, rc = PTR_ERR(th));
 
@@ -2474,7 +2517,7 @@ again:
                th = NULL;
 
                /* The 2nd transaction. */
-               rc = __lfsck_layout_update_pfid(env, cobj, pfid,
+               rc = __lfsck_layout_update_pfid(env, com, cobj, pfid,
                                                &rec->lor_layout, ea_off,
                                                rec->lor_layout_version,
                                                rec->lor_range);
@@ -2621,7 +2664,7 @@ static int lfsck_layout_slave_conditional_destroy(const struct lu_env *env,
        if (la->la_ctime != 0)
                GOTO(unlock, rc = -ETXTBSY);
 
-       th = dt_trans_create(env, dev);
+       th = lfsck_trans_create(env, dev, lfsck);
        if (IS_ERR(th))
                GOTO(unlock, rc = PTR_ERR(th));
 
@@ -2737,7 +2780,10 @@ static int lfsck_layout_conflict_create(const struct lu_env *env,
        if (rc != 0 && rc != -ENOENT)
                GOTO(unlock, rc);
 
-       th = dt_trans_create(env, dev);
+       if (lfsck_is_dryrun(com->lc_lfsck))
+               GOTO(unlock, rc = 0);
+
+       th = lfsck_trans_create(env, dev, com->lc_lfsck);
        if (IS_ERR(th))
                GOTO(unlock, rc = PTR_ERR(th));
 
@@ -2816,6 +2862,9 @@ static int lfsck_layout_recreate_lovea(const struct lu_env *env,
        bool new_mirror = true;
        ENTRY;
 
+       if (lfsck_is_dryrun(lfsck))
+               RETURN(0);
+
        rc = lfsck_ibits_lock(env, lfsck, parent, &lh,
                              MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR,
                              LCK_EX);
@@ -2855,7 +2904,7 @@ again:
        }
 
        if (!(bk->lb_param & LPF_DRYRUN)) {
-               handle = dt_trans_create(env, dt);
+               handle = lfsck_trans_create(env, dt, lfsck);
                if (IS_ERR(handle))
                        GOTO(unlock_layout, rc = PTR_ERR(handle));
 
@@ -2929,7 +2978,7 @@ again:
                GOTO(unlock_parent, rc = rc1);
 
        magic = le32_to_cpu(lmm->lmm_magic);
-       if (magic == LOV_MAGIC_COMP_V1) {
+       if (magic == LOV_MAGIC_COMP_V1 || magic == LOV_MAGIC_SEL) {
                __u64 start;
                __u64 end;
                __u16 mirror_id0 = mirror_id_of(ol->ol_comp_id);
@@ -3358,7 +3407,7 @@ static int lfsck_lov2layout(struct lov_mds_md_v1 *lmm, struct filter_fid *ff,
                ol->ol_comp_id = 0;
                ff->ff_layout_version = 0;
                ff->ff_range = 0;
-       } else if (magic == LOV_MAGIC_COMP_V1) {
+       } else if (magic == LOV_MAGIC_COMP_V1 || magic == LOV_MAGIC_SEL) {
                struct lov_comp_md_v1 *lcm = (struct lov_comp_md_v1 *)lmm;
                struct lov_comp_md_entry_v1 *lcme = NULL;
                __u16 count = le16_to_cpu(lcm->lcm_entry_count);
@@ -3478,7 +3527,7 @@ static int __lfsck_layout_repair_dangling(const struct lu_env *env,
                GOTO(unlock1, rc);
 
        buf = lfsck_buf_get(env, ff, sizeof(struct filter_fid));
-       handle = dt_trans_create(env, dev);
+       handle = lfsck_trans_create(env, dev, lfsck);
        if (IS_ERR(handle))
                GOTO(unlock1, rc = PTR_ERR(handle));
 
@@ -3517,7 +3566,7 @@ static int __lfsck_layout_repair_dangling(const struct lu_env *env,
 
                lmm = lovea->lb_buf;
                magic = le32_to_cpu(lmm->lmm_magic);
-               if (magic == LOV_MAGIC_COMP_V1) {
+               if (magic == LOV_MAGIC_COMP_V1 || magic == LOV_MAGIC_SEL) {
                        struct lov_comp_md_v1 *lcm = buf->lb_buf;
                        struct lov_comp_md_entry_v1 *lcme;
                        __u16 count = le16_to_cpu(lcm->lcm_entry_count);
@@ -3719,7 +3768,7 @@ static int lfsck_layout_repair_unmatched_pair(const struct lu_env *env,
 
        buf = lfsck_buf_get(env, ff, sizeof(*ff));
 
-       handle = dt_trans_create(env, dev);
+       handle = lfsck_trans_create(env, dev, com->lc_lfsck);
        if (IS_ERR(handle))
                GOTO(unlock1, rc = PTR_ERR(handle));
 
@@ -3847,7 +3896,7 @@ static int lfsck_layout_repair_multiple_references(const struct lu_env *env,
        memset(dof, 0, sizeof(*dof));
 
        dev = lfsck_obj2dev(child);
-       handle = dt_trans_create(env, dev);
+       handle = lfsck_trans_create(env, dev, lfsck);
        if (IS_ERR(handle))
                GOTO(log, rc = PTR_ERR(handle));
 
@@ -3888,7 +3937,7 @@ static int lfsck_layout_repair_multiple_references(const struct lu_env *env,
        if (IS_ERR(parent))
                GOTO(log, rc = PTR_ERR(parent));
 
-       handle = dt_trans_create(env, dev);
+       handle = lfsck_trans_create(env, dev, lfsck);
        if (IS_ERR(handle))
                GOTO(log, rc = PTR_ERR(handle));
 
@@ -3913,7 +3962,7 @@ static int lfsck_layout_repair_multiple_references(const struct lu_env *env,
 
        lmm = buf->lb_buf;
        magic = le32_to_cpu(lmm->lmm_magic);
-       if (magic == LOV_MAGIC_COMP_V1) {
+       if (magic == LOV_MAGIC_COMP_V1 || magic == LOV_MAGIC_SEL) {
                struct lov_comp_md_v1 *lcm = buf->lb_buf;
                struct lov_comp_md_entry_v1 *lcme;
                __u16 count = le16_to_cpu(lcm->lcm_entry_count);
@@ -4010,7 +4059,7 @@ static int lfsck_layout_repair_owner(const struct lu_env *env,
        tla->la_uid = pla->la_uid;
        tla->la_gid = pla->la_gid;
        tla->la_valid = LA_UID | LA_GID;
-       handle = dt_trans_create(env, dev);
+       handle = lfsck_trans_create(env, dev, com->lc_lfsck);
        if (IS_ERR(handle))
                GOTO(log, rc = PTR_ERR(handle));
 
@@ -4065,6 +4114,11 @@ log:
        return rc;
 }
 
+#define CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid, cfid, msg)              \
+       CDEBUG(D_LFSCK, "%s:("DFID"|"DFID")/"DFID":XATTR %s: %s\n",      \
+              lfsck_lfsck2name(lfsck), PFID(&lso->lso_fid), PFID(pfid), \
+              PFID(cfid), XATTR_NAME_FID, msg);
+
 /* Check whether the OST-object correctly back points to the
  * MDT-object (@parent) via the XATTR_NAME_FID xattr (@pfid). */
 static int lfsck_layout_check_parent(const struct lu_env *env,
@@ -4082,6 +4136,7 @@ static int lfsck_layout_check_parent(const struct lu_env *env,
        struct lov_mds_md_v1            *lmm;
        struct lov_ost_data_v1          *objs;
        struct lustre_handle             lh     = { 0 };
+       struct lfsck_instance           *lfsck  = com->lc_lfsck;
        int                              rc;
        int                              i;
        __u32                            magic;
@@ -4093,13 +4148,20 @@ static int lfsck_layout_check_parent(const struct lu_env *env,
        idx = pfid->f_stripe_idx;
        pfid->f_ver = 0;
 
-       if (unlikely(!fid_is_sane(pfid)))
+       if (unlikely(!fid_is_sane(pfid))) {
+               CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid, cfid,
+                                     "the parent FID is invalid");
+
                RETURN(LLIT_UNMATCHED_PAIR);
+       }
 
        if (lu_fid_eq(pfid, &lso->lso_fid)) {
                if (likely(llr->llr_lov_idx == idx))
                        RETURN(0);
 
+               CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid, cfid,
+                                     "the stripe index is unmatched");
+
                RETURN(LLIT_UNMATCHED_PAIR);
        }
 
@@ -4107,17 +4169,38 @@ static int lfsck_layout_check_parent(const struct lu_env *env,
        if (IS_ERR(tobj))
                RETURN(PTR_ERR(tobj));
 
-       if (dt_object_exists(tobj) == 0 || lfsck_is_dead_obj(tobj) ||
-           !S_ISREG(lfsck_object_type(tobj)))
+       if (dt_object_exists(tobj) == 0) {
+               CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid, cfid,
+                                     "the parent is nonexistent");
+
                GOTO(out, rc = LLIT_UNMATCHED_PAIR);
+       }
+
+       if (lfsck_is_dead_obj(tobj)) {
+               CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid, cfid,
+                                     "the parent is dead object");
+
+               GOTO(out, rc = LLIT_UNMATCHED_PAIR);
+       }
+
+       if (!S_ISREG(lfsck_object_type(tobj))) {
+               CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid, cfid,
+                                     "the parent is not a regular file");
+
+               GOTO(out, rc = LLIT_UNMATCHED_PAIR);
+       }
 
        /* Load the tobj's layout EA, in spite of it is a local MDT-object or
         * remote one on another MDT. Then check whether the given OST-object
         * is in such layout. If yes, it is multiple referenced, otherwise it
         * is unmatched referenced case. */
        rc = lfsck_layout_get_lovea(env, tobj, buf);
-       if (rc == 0 || rc == -ENODATA || rc == -ENOENT)
+       if (rc == 0 || rc == -ENODATA || rc == -ENOENT) {
+               CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid, cfid,
+                                     "the parent has no stripe data");
+
                GOTO(out, rc = LLIT_UNMATCHED_PAIR);
+       }
 
        if (unlikely(rc == -EOPNOTSUPP))
                GOTO(out, rc = LLIT_NONE);
@@ -4127,12 +4210,16 @@ static int lfsck_layout_check_parent(const struct lu_env *env,
 
        lmm = buf->lb_buf;
        magic = le32_to_cpu(lmm->lmm_magic);
-       if (magic == LOV_MAGIC_COMP_V1) {
+       if (magic == LOV_MAGIC_COMP_V1 || magic == LOV_MAGIC_SEL) {
                struct lov_comp_md_v1 *lcm = buf->lb_buf;
                struct lov_comp_md_entry_v1 *lcme;
 
-               if (ff->ff_layout.ol_comp_id == 0)
+               if (ff->ff_layout.ol_comp_id == 0) {
+                       CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid, cfid,
+                                             "the parent has incorrect comp_id");
+
                        GOTO(out, rc = LLIT_UNMATCHED_PAIR);
+               }
 
                count = le16_to_cpu(lcm->lcm_entry_count);
                for (i = 0; i < count; i++) {
@@ -4143,13 +4230,21 @@ static int lfsck_layout_check_parent(const struct lu_env *env,
                                        le32_to_cpu(lcme->lcme_offset);
                                magic = le32_to_cpu(lmm->lmm_magic);
                                if (!(le32_to_cpu(lcme->lcme_flags) &
-                                     LCME_FL_INIT))
+                                     LCME_FL_INIT)) {
+                                       CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid,
+                                                             cfid,
+                                                             "the parent has uninitialized component");
+
                                        GOTO(out, rc = LLIT_UNMATCHED_PAIR);
+                               }
 
                                goto further;
                        }
                }
 
+               CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid, cfid,
+                                     "the parent has no matched comp_id");
+
                GOTO(out, rc = LLIT_UNMATCHED_PAIR);
        }
 
@@ -4197,10 +4292,15 @@ further:
                         * after taken the lock. */
                        if (!dt_object_remote(tobj)) {
                                if (dt_object_exists(tobj) == 0 ||
-                                   lfsck_is_dead_obj(tobj))
+                                   lfsck_is_dead_obj(tobj)) {
+                                       CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid,
+                                                             cfid,
+                                                             "the parent doesn't exist anymore after lock");
+
                                        rc = LLIT_UNMATCHED_PAIR;
-                               else
+                               } else {
                                        rc = LLIT_MULTIPLE_REFERENCED;
+                               }
 
                                GOTO(unlock, rc);
                        }
@@ -4215,15 +4315,22 @@ further:
                         * has been been removed or not. */
                        rc = dt_xattr_get(env, tobj, &LU_BUF_NULL,
                                          XATTR_NAME_DUMMY);
-                       if (unlikely(rc == -ENOENT || rc >= 0))
+                       if (unlikely(rc == -ENOENT || rc >= 0)) {
+                               CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid, cfid,
+                                                     "the parent is remote object and nonexistent after lock");
+
                                rc = LLIT_UNMATCHED_PAIR;
-                       else if (rc == -ENODATA)
+                       } else if (rc == -ENODATA) {
                                rc = LLIT_MULTIPLE_REFERENCED;
+                       }
 
                        GOTO(unlock, rc);
                }
        }
 
+       CDEBUG_UNMATCHED_PAIR(lfsck, lso, pfid, cfid,
+                             "the parent has no matched stripe");
+
        GOTO(out, rc = LLIT_UNMATCHED_PAIR);
 
 unlock:
@@ -4243,7 +4350,7 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env,
                                             struct lfsck_assistant_req *lar)
 {
        struct lfsck_layout_req              *llr    =
-                       container_of0(lar, struct lfsck_layout_req, llr_lar);
+               container_of(lar, struct lfsck_layout_req, llr_lar);
        struct lfsck_assistant_object        *lso    = lar->lar_parent;
        struct lfsck_layout                  *lo     = com->lc_file_ram;
        struct lfsck_thread_info             *info   = lfsck_env_info(env);
@@ -4284,6 +4391,12 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env,
        lfsck_buf_init(&buf, ff, sizeof(*ff));
        rc = dt_xattr_get(env, child, &buf, XATTR_NAME_FID);
        if (unlikely(rc > 0 && rc < sizeof(struct lu_fid))) {
+               CDEBUG(D_LFSCK, "%s:"DFID"/"DFID": "
+                      "the child object's %s is corrupted\n",
+                      lfsck_lfsck2name(lfsck), PFID(&lso->lso_fid),
+                      PFID(lu_object_fid(&child->do_lu)),
+                      XATTR_NAME_FID);
+
                type = LLIT_UNMATCHED_PAIR;
                goto repair;
        }
@@ -4682,7 +4795,7 @@ static int lfsck_layout_async_query(const struct lu_env *env,
        *tmp = *lr;
        ptlrpc_request_set_replen(req);
 
-       llsaa = ptlrpc_req_async_args(req);
+       llsaa = ptlrpc_req_async_args(llsaa, req);
        llsaa->llsaa_exp = exp;
        llsaa->llsaa_com = lfsck_component_get(com);
        llsaa->llsaa_llst = llst;
@@ -4911,7 +5024,7 @@ static int lfsck_layout_master_check_pairs(const struct lu_env *env,
 
        lmm = buf->lb_buf;
        magic = le32_to_cpu(lmm->lmm_magic);
-       if (magic == LOV_MAGIC_COMP_V1) {
+       if (magic == LOV_MAGIC_COMP_V1 || magic == LOV_MAGIC_SEL) {
                struct lov_comp_md_v1 *lcm = buf->lb_buf;
                struct lov_comp_md_entry_v1 *lcme;
 
@@ -5059,7 +5172,8 @@ static int lfsck_layout_slave_repair_pfid(const struct lu_env *env,
                     lfsck_is_dead_obj(obj)))
                GOTO(unlock, rc = 0);
 
-       rc = __lfsck_layout_update_pfid(env, obj, &lrl->lrl_ff_client.ff_parent,
+       rc = __lfsck_layout_update_pfid(env, com, obj,
+                                       &lrl->lrl_ff_client.ff_parent,
                                        &lrl->lrl_ff_client.ff_layout,
                                        lrl->lrl_ff_client.ff_layout_version,
                                        lrl->lrl_ff_client.ff_range,
@@ -5356,7 +5470,7 @@ static int lfsck_layout_scan_stripes(const struct lu_env *env,
                                     struct dt_object *parent,
                                     struct lov_mds_md_v1 *lmm, __u32 comp_id)
 {
-       struct lfsck_thread_info        *info    = lfsck_env_info(env);
+       struct lfsck_thread_info        *info    = lfsck_env_info(env);
        struct lfsck_instance           *lfsck   = com->lc_lfsck;
        struct lfsck_bookmark           *bk      = &lfsck->li_bookmark_ram;
        struct lfsck_layout             *lo      = com->lc_file_ram;
@@ -5366,7 +5480,6 @@ static int lfsck_layout_scan_stripes(const struct lu_env *env,
        struct lfsck_tgt_descs          *ltds    = &lfsck->li_ost_descs;
        struct ptlrpc_thread            *mthread = &lfsck->li_thread;
        struct ptlrpc_thread            *athread = &lad->lad_thread;
-       struct l_wait_info               lwi     = { 0 };
        struct lu_buf                    buf;
        int                              rc      = 0;
        int                              i;
@@ -5396,11 +5509,10 @@ static int lfsck_layout_scan_stripes(const struct lu_env *env,
                if (unlikely(lovea_slot_is_dummy(objs)))
                        continue;
 
-               l_wait_event(mthread->t_ctl_waitq,
-                            lad->lad_prefetched < bk->lb_async_windows ||
-                            !thread_is_running(mthread) ||
-                            thread_is_stopped(athread),
-                            &lwi);
+               wait_event_idle(mthread->t_ctl_waitq,
+                               lad->lad_prefetched < bk->lb_async_windows ||
+                               !thread_is_running(mthread) ||
+                               thread_is_stopped(athread));
 
                if (unlikely(!thread_is_running(mthread)) ||
                             thread_is_stopped(athread))
@@ -5516,7 +5628,7 @@ static int lfsck_layout_scan_stripes(const struct lu_env *env,
                lad->lad_prefetched++;
                spin_unlock(&lad->lad_lock);
                if (wakeup)
-                       wake_up_all(&athread->t_ctl_waitq);
+                       wake_up(&athread->t_ctl_waitq);
 
 next:
                down_write(&com->lc_sem);
@@ -5607,15 +5719,16 @@ again:
        size = rc;
        lmm = buf->lb_buf;
        magic = le32_to_cpu(lmm->lmm_magic);
-       if (magic == LOV_MAGIC_COMP_V1) {
+       if (magic == LOV_MAGIC_COMP_V1 || magic == LOV_MAGIC_SEL) {
+               struct lov_mds_md_v1 *v1;
                int i;
 
                lcm = buf->lb_buf;
                count = le16_to_cpu(lcm->lcm_entry_count);
                for (i = 0; i < count; i++) {
                        lcme = &lcm->lcm_entries[i];
-                       lmm = buf->lb_buf + le32_to_cpu(lcme->lcme_offset);
-                       if (memcmp(oi, &lmm->lmm_oi, sizeof(*oi)) != 0)
+                       v1 = buf->lb_buf + le32_to_cpu(lcme->lcme_offset);
+                       if (memcmp(oi, &v1->lmm_oi, sizeof(*oi)) != 0)
                                goto fix;
                }
 
@@ -5643,7 +5756,7 @@ fix:
                if (rc != 0)
                        GOTO(out, rc);
 
-               handle = dt_trans_create(env, dev);
+               handle = lfsck_trans_create(env, dev, lfsck);
                if (IS_ERR(handle))
                        GOTO(out, rc = PTR_ERR(handle));
 
@@ -5663,13 +5776,14 @@ fix:
                goto again;
        }
 
-       if (magic == LOV_MAGIC_COMP_V1) {
+       if (magic == LOV_MAGIC_COMP_V1 || magic == LOV_MAGIC_SEL) {
+               struct lov_mds_md_v1 *v1;
                int i;
 
                for (i = 0; i < count; i++) {
                        lcme = &lcm->lcm_entries[i];
-                       lmm = buf->lb_buf + le32_to_cpu(lcme->lcme_offset);
-                       lmm->lmm_oi = *oi;
+                       v1 = buf->lb_buf + le32_to_cpu(lcme->lcme_offset);
+                       v1->lmm_oi = *oi;
                }
        } else {
                lmm->lmm_oi = *oi;
@@ -5704,7 +5818,7 @@ out:
                       PFID(lfsck_dto2fid(obj)), rc);
 
        if (stripe) {
-               if (magic == LOV_MAGIC_COMP_V1) {
+               if (magic == LOV_MAGIC_COMP_V1 || magic == LOV_MAGIC_SEL) {
                        int i;
 
                        for (i = 0; i < count; i++) {
@@ -5750,13 +5864,11 @@ static int lfsck_layout_slave_exec_oit(const struct lu_env *env,
 
        if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_DELAY5) &&
            cfs_fail_val == lfsck_dev_idx(lfsck)) {
-               struct l_wait_info       lwi = LWI_TIMEOUT(cfs_time_seconds(1),
-                                                          NULL, NULL);
                struct ptlrpc_thread    *thread = &lfsck->li_thread;
 
-               l_wait_event(thread->t_ctl_waitq,
-                            !thread_is_running(thread),
-                            &lwi);
+               wait_event_idle_timeout(thread->t_ctl_waitq,
+                                       !thread_is_running(thread),
+                                       cfs_time_seconds(1));
        }
 
        lfsck_rbtree_update_bitmap(env, com, fid, false);
@@ -6058,8 +6170,8 @@ static void lfsck_layout_dump(const struct lu_env *env,
                           "run_time_phase2: %lld seconds\n"
                           "average_speed_phase1: %llu items/sec\n"
                           "average_speed_phase2: N/A\n"
-                          "real-time_speed_phase1: %llu items/sec\n"
-                          "real-time_speed_phase2: N/A\n",
+                          "real_time_speed_phase1: %llu items/sec\n"
+                          "real_time_speed_phase2: N/A\n",
                           checked,
                           lo->ll_objs_checked_phase2,
                           rtime,
@@ -6105,8 +6217,8 @@ static void lfsck_layout_dump(const struct lu_env *env,
                           "run_time_phase2: %lld seconds\n"
                           "average_speed_phase1: %llu items/sec\n"
                           "average_speed_phase2: %llu items/sec\n"
-                          "real-time_speed_phase1: N/A\n"
-                          "real-time_speed_phase2: %llu items/sec\n"
+                          "real_time_speed_phase1: N/A\n"
+                          "real_time_speed_phase2: %llu items/sec\n"
                           "current_position: "DFID"\n",
                           lo->ll_objs_checked_phase1,
                           checked,
@@ -6130,8 +6242,8 @@ static void lfsck_layout_dump(const struct lu_env *env,
                           "run_time_phase2: %lld seconds\n"
                           "average_speed_phase1: %llu items/sec\n"
                           "average_speed_phase2: %llu objs/sec\n"
-                          "real-time_speed_phase1: N/A\n"
-                          "real-time_speed_phase2: N/A\n"
+                          "real_time_speed_phase1: N/A\n"
+                          "real_time_speed_phase2: N/A\n"
                           "current_position: N/A\n",
                           lo->ll_objs_checked_phase1,
                           lo->ll_objs_checked_phase2,
@@ -6207,9 +6319,6 @@ static int lfsck_layout_slave_double_scan(const struct lu_env *env,
                                       LFSCK_CHECKPOINT_INTERVAL;
 
        while (1) {
-               struct l_wait_info lwi = LWI_TIMEOUT(cfs_time_seconds(30),
-                                                    NULL, NULL);
-
                rc = lfsck_layout_slave_query_master(env, com);
                if (list_empty(&llsd->llsd_master_list)) {
                        if (unlikely(!thread_is_running(thread)))
@@ -6223,21 +6332,22 @@ static int lfsck_layout_slave_double_scan(const struct lu_env *env,
                if (rc < 0)
                        GOTO(done, rc);
 
-               rc = l_wait_event(thread->t_ctl_waitq,
-                                 !thread_is_running(thread) ||
-                                 lo->ll_flags & LF_INCOMPLETE ||
-                                 list_empty(&llsd->llsd_master_list),
-                                 &lwi);
+               rc = wait_event_idle_timeout(
+                       thread->t_ctl_waitq,
+                       !thread_is_running(thread) ||
+                       lo->ll_flags & LF_INCOMPLETE ||
+                       list_empty(&llsd->llsd_master_list),
+                       cfs_time_seconds(30));
                if (unlikely(!thread_is_running(thread)))
                        GOTO(done, rc = 0);
 
                if (lo->ll_flags & LF_INCOMPLETE)
                        GOTO(done, rc = 1);
 
-               if (rc == -ETIMEDOUT)
+               if (rc == 0)
                        continue;
 
-               GOTO(done, rc = (rc < 0 ? rc : 1));
+               GOTO(done, rc = 1);
        }
 
 done:
@@ -6246,7 +6356,7 @@ done:
                        (rc > 0 && lo->ll_flags & LF_INCOMPLETE) ? 0 : rc);
        lfsck_layout_slave_quit(env, com);
        if (atomic_dec_and_test(&lfsck->li_double_scan_count))
-               wake_up_all(&lfsck->li_thread.t_ctl_waitq);
+               wake_up(&lfsck->li_thread.t_ctl_waitq);
 
        CDEBUG(D_LFSCK, "%s: layout LFSCK slave phase2 scan finished, "
               "status %d: rc = %d\n",
@@ -6502,7 +6612,7 @@ static int lfsck_layout_master_in_notify(const struct lu_env *env,
                stop->ls_flags = lr->lr_param & ~LPF_BROADCAST;
                lfsck_stop(env, lfsck->li_bottom, stop);
        } else if (lfsck_phase2_next_ready(lad)) {
-               wake_up_all(&lad->lad_thread.t_ctl_waitq);
+               wake_up(&lad->lad_thread.t_ctl_waitq);
        }
 
        RETURN(0);
@@ -6586,7 +6696,7 @@ static int lfsck_layout_slave_in_notify(const struct lu_env *env,
                                                              true);
                        if (llst != NULL) {
                                lfsck_layout_llst_put(llst);
-                               wake_up_all(&lfsck->li_thread.t_ctl_waitq);
+                               wake_up(&lfsck->li_thread.t_ctl_waitq);
                        }
                }
 
@@ -6608,7 +6718,7 @@ static int lfsck_layout_slave_in_notify(const struct lu_env *env,
 
        lfsck_layout_llst_put(llst);
        if (list_empty(&llsd->llsd_master_list))
-               wake_up_all(&lfsck->li_thread.t_ctl_waitq);
+               wake_up(&lfsck->li_thread.t_ctl_waitq);
 
        if (lr->lr_event == LE_PEER_EXIT &&
            (lfsck->li_bookmark_ram.lb_param & LPF_FAILOUT ||
@@ -6747,7 +6857,7 @@ static int lfsck_layout_slave_join(const struct lu_env *env,
        RETURN(rc);
 }
 
-static struct lfsck_operations lfsck_layout_master_ops = {
+static const struct lfsck_operations lfsck_layout_master_ops = {
        .lfsck_reset            = lfsck_layout_reset,
        .lfsck_fail             = lfsck_layout_fail,
        .lfsck_checkpoint       = lfsck_layout_master_checkpoint,
@@ -6763,7 +6873,7 @@ static struct lfsck_operations lfsck_layout_master_ops = {
        .lfsck_query            = lfsck_layout_query,
 };
 
-static struct lfsck_operations lfsck_layout_slave_ops = {
+static const struct lfsck_operations lfsck_layout_slave_ops = {
        .lfsck_reset            = lfsck_layout_reset,
        .lfsck_fail             = lfsck_layout_fail,
        .lfsck_checkpoint       = lfsck_layout_slave_checkpoint,
@@ -6801,7 +6911,7 @@ static void lfsck_layout_assistant_fill_pos(const struct lu_env *env,
        pos->lp_oit_cookie = llr->llr_lar.lar_parent->lso_oit_cookie - 1;
 }
 
-struct lfsck_assistant_operations lfsck_layout_assistant_ops = {
+const struct lfsck_assistant_operations lfsck_layout_assistant_ops = {
        .la_handler_p1          = lfsck_layout_assistant_handler_p1,
        .la_handler_p2          = lfsck_layout_assistant_handler_p2,
        .la_fill_pos            = lfsck_layout_assistant_fill_pos,
@@ -7000,6 +7110,7 @@ static int lfsck_fid_match_idx(const struct lu_env *env,
 }
 
 static void lfsck_layout_destroy_orphan(const struct lu_env *env,
+                                       struct lfsck_instance *lfsck,
                                        struct dt_object *obj)
 {
        struct dt_device        *dev    = lfsck_obj2dev(obj);
@@ -7007,7 +7118,7 @@ static void lfsck_layout_destroy_orphan(const struct lu_env *env,
        int                      rc;
        ENTRY;
 
-       handle = dt_trans_create(env, dev);
+       handle = lfsck_trans_create(env, dev, lfsck);
        if (IS_ERR(handle))
                RETURN_EXIT;
 
@@ -7340,7 +7451,7 @@ again1:
                         * OST-object there. Destroy it now! */
                        if (unlikely(!(la->la_mode & S_ISUID))) {
                                dt_read_unlock(env, obj);
-                               lfsck_layout_destroy_orphan(env, obj);
+                               lfsck_layout_destroy_orphan(env, lfsck, obj);
                                lfsck_object_put(env, obj);
                                pos++;
                                goto again1;
@@ -7521,7 +7632,7 @@ static int lfsck_orphan_it_key_rec(const struct lu_env *env,
        return 0;
 }
 
-const struct dt_index_operations lfsck_orphan_index_ops = {
+static const struct dt_index_operations lfsck_orphan_index_ops = {
        .dio_lookup             = lfsck_orphan_index_lookup,
        .dio_declare_insert     = lfsck_orphan_index_declare_insert,
        .dio_insert             = lfsck_orphan_index_insert,