Whamcloud - gitweb
LU-6138 lfsck: NOT hold reference on pre-loaded object 66/13666/5
authorFan Yong <fan.yong@intel.com>
Thu, 20 Nov 2014 04:55:33 +0000 (12:55 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 18 Feb 2015 22:08:50 +0000 (22:08 +0000)
To improve the LFSCK performance, the LFSCK main engine will pre-load
the object locally or remotely, then generate related LFSCK request
that reference the pre-loaded object, and then push the request into
related LFSCK pipeline. The LFSCK assistant thread will handle the
LFSCK request some later asynchronously.

Originally, the LFSCK request holds the pre-loaded object reference,
so the assistant thread can handle it directly without locating the
object by FID again. But holding the object reference will cause the
object cannot be purged out RAM. If some LFSCK request has held the
object, and some other unlinked the object before the LFSCK assistant
thread handling the LFSCK request, then the unlinked object will be
cached in RAM until the last reference released. Because the LFSCK
main engine and assistant thread run asynchronously, we do not know
when the LFSCK request that holding the object reference will be
handled. If the assistant thread needs to locate the object with
the same FID before that, it will fall into self-deadlock for ever.

Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: I516653aa2143bb32a5f350b314951b78dead3e79
Reviewed-on: http://review.whamcloud.com/13666
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/lfsck/lfsck_internal.h
lustre/lfsck/lfsck_layout.c
lustre/lfsck/lfsck_namespace.c
lustre/lfsck/lfsck_striped_dir.c

index 287ae97..6094721 100644 (file)
@@ -719,11 +719,11 @@ struct lfsck_thread_args {
 
 struct lfsck_assistant_req {
        struct list_head        lar_list;
+       struct lu_fid           lar_fid;
 };
 
 struct lfsck_namespace_req {
        struct lfsck_assistant_req       lnr_lar;
-       struct dt_object                *lnr_obj;
        struct lfsck_lmv                *lnr_lmv;
        struct lu_fid                    lnr_fid;
        __u64                            lnr_oit_cookie;
@@ -938,6 +938,7 @@ int lfsck_namespace_rebuild_linkea(const struct lu_env *env,
                                   struct linkea_data *ldata);
 int lfsck_namespace_repair_dangling(const struct lu_env *env,
                                    struct lfsck_component *com,
+                                   struct dt_object *parent,
                                    struct dt_object *child,
                                    struct lfsck_namespace_req *lnr);
 int lfsck_namespace_repair_dirent(const struct lu_env *env,
@@ -993,9 +994,11 @@ int lfsck_namespace_repair_bad_name_hash(const struct lu_env *env,
                                         const char *name);
 int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
                                       struct lfsck_component *com,
+                                      struct dt_object *dir,
                                       struct lfsck_namespace_req *lnr);
 int lfsck_namespace_handle_striped_master(const struct lu_env *env,
                                          struct lfsck_component *com,
+                                         struct dt_object *dir,
                                          struct lfsck_namespace_req *lnr);
 
 /* lfsck_layout.c */
index 8267c6b..632da13 100644 (file)
@@ -89,7 +89,6 @@ struct lfsck_layout_slave_data {
 };
 
 struct lfsck_layout_object {
-       struct dt_object        *llo_obj;
        struct lu_attr           llo_attr;
        atomic_t                 llo_ref;
        __u64                    llo_cookie;
@@ -128,8 +127,6 @@ lfsck_layout_object_init(const struct lu_env *env, struct dt_object *obj,
                return ERR_PTR(rc);
        }
 
-       lu_object_get(&obj->do_lu);
-       llo->llo_obj = obj;
        llo->llo_cookie = cookie;
        /* The gen can be used to check whether some others have changed the
         * file layout after LFSCK pre-fetching but before real verification. */
@@ -225,14 +222,13 @@ lfsck_layout_llst_find_and_del(struct lfsck_layout_slave_data *llsd,
 static inline void lfsck_layout_object_put(const struct lu_env *env,
                                           struct lfsck_layout_object *llo)
 {
-       if (atomic_dec_and_test(&llo->llo_ref)) {
-               lfsck_object_put(env, llo->llo_obj);
+       if (atomic_dec_and_test(&llo->llo_ref))
                OBD_FREE_PTR(llo);
-       }
 }
 
 static struct lfsck_layout_req *
 lfsck_layout_assistant_req_init(struct lfsck_layout_object *parent,
+                               const struct lu_fid *pfid,
                                struct dt_object *child, __u32 ost_idx,
                                __u32 lov_idx)
 {
@@ -243,6 +239,8 @@ lfsck_layout_assistant_req_init(struct lfsck_layout_object *parent,
                return ERR_PTR(-ENOMEM);
 
        INIT_LIST_HEAD(&llr->llr_lar.lar_list);
+       llr->llr_lar.lar_fid = *pfid;
+
        atomic_inc(&parent->llo_ref);
        llr->llr_parent = parent;
        llr->llr_child = child;
@@ -2676,6 +2674,7 @@ log:
  * 2) Re-create the missing OST-object with the FID/owner information. */
 static int lfsck_layout_repair_dangling(const struct lu_env *env,
                                        struct lfsck_component *com,
+                                       struct dt_object *parent,
                                        struct lfsck_layout_req *llr,
                                        const struct lu_attr *pla)
 {
@@ -2683,7 +2682,6 @@ static int lfsck_layout_repair_dangling(const struct lu_env *env,
        struct filter_fid               *pfid   = &info->lti_new_pfid;
        struct dt_allocation_hint       *hint   = &info->lti_hint;
        struct lu_attr                  *cla    = &info->lti_la2;
-       struct dt_object                *parent = llr->llr_parent->llo_obj;
        struct dt_object                *child  = llr->llr_child;
        struct dt_device                *dev    = lfsck_obj2dt_dev(child);
        const struct lu_fid             *tfid   = lu_object_fid(&parent->do_lu);
@@ -2782,13 +2780,13 @@ log:
  * given MDT-object as its parent. So update the OST-object filter_fid. */
 static int lfsck_layout_repair_unmatched_pair(const struct lu_env *env,
                                              struct lfsck_component *com,
+                                             struct dt_object *parent,
                                              struct lfsck_layout_req *llr,
                                              const struct lu_attr *pla)
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
        struct filter_fid               *pfid   = &info->lti_new_pfid;
        struct lu_attr                  *tla    = &info->lti_la3;
-       struct dt_object                *parent = llr->llr_parent->llo_obj;
        struct dt_object                *child  = llr->llr_child;
        struct dt_device                *dev    = lfsck_obj2dt_dev(child);
        const struct lu_fid             *tfid   = lu_object_fid(&parent->do_lu);
@@ -2875,6 +2873,7 @@ log:
  * new OST-object(s) with new fid(s) for the non-recognized MDT-object(s). */
 static int lfsck_layout_repair_multiple_references(const struct lu_env *env,
                                                   struct lfsck_component *com,
+                                                  struct dt_object *parent,
                                                   struct lfsck_layout_req *llr,
                                                   struct lu_attr *la,
                                                   struct lu_buf *buf)
@@ -2884,7 +2883,6 @@ static int lfsck_layout_repair_multiple_references(const struct lu_env *env,
        struct dt_object_format         *dof    = &info->lti_dof;
        struct dt_device                *pdev   = com->lc_lfsck->li_next;
        struct ost_id                   *oi     = &info->lti_oi;
-       struct dt_object                *parent = llr->llr_parent->llo_obj;
        struct dt_device                *cdev   = lfsck_obj2dt_dev(llr->llr_child);
        struct dt_object                *child  = NULL;
        struct lu_device                *d      = &cdev->dd_lu_dev;
@@ -3005,12 +3003,12 @@ log:
  * is partly done. */
 static int lfsck_layout_repair_owner(const struct lu_env *env,
                                     struct lfsck_component *com,
+                                    struct dt_object *parent,
                                     struct lfsck_layout_req *llr,
                                     struct lu_attr *pla)
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
        struct lu_attr                  *tla    = &info->lti_la3;
-       struct dt_object                *parent = llr->llr_parent->llo_obj;
        struct dt_object                *child  = llr->llr_child;
        struct dt_device                *dev    = lfsck_obj2dt_dev(child);
        struct thandle                  *handle;
@@ -3239,7 +3237,7 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env,
        struct filter_fid_old                *pea    = &info->lti_old_pfid;
        struct lu_fid                        *pfid   = &info->lti_fid;
        struct lu_buf                         buf    = { NULL };
-       struct dt_object                     *parent = llr->llr_parent->llo_obj;
+       struct dt_object                     *parent;
        struct dt_object                     *child  = llr->llr_child;
        struct lu_attr                       *pla    = &info->lti_la;
        struct lu_attr                       *cla    = &info->lti_la2;
@@ -3250,8 +3248,12 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env,
        int                                   rc;
        ENTRY;
 
+       parent = lfsck_object_find(env, lfsck, &lar->lar_fid);
+       if (IS_ERR(parent))
+               RETURN(PTR_ERR(parent));
+
        if (unlikely(lfsck_is_dead_obj(parent)))
-               RETURN(0);
+               GOTO(put_parent, rc = 0);
 
        rc = dt_attr_get(env, parent, pla, BYPASS_CAPA);
        if (rc != 0)
@@ -3260,7 +3262,7 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env,
        rc = dt_attr_get(env, child, cla, BYPASS_CAPA);
        if (rc == -ENOENT) {
                if (unlikely(lfsck_is_dead_obj(parent)))
-                       RETURN(0);
+                       GOTO(put_parent, rc = 0);
 
                type = LLIT_DANGLING;
                goto repair;
@@ -3318,17 +3320,18 @@ repair:
 
        switch (type) {
        case LLIT_DANGLING:
-               rc = lfsck_layout_repair_dangling(env, com, llr, pla);
+               rc = lfsck_layout_repair_dangling(env, com, parent, llr, pla);
                break;
        case LLIT_UNMATCHED_PAIR:
-               rc = lfsck_layout_repair_unmatched_pair(env, com, llr, pla);
+               rc = lfsck_layout_repair_unmatched_pair(env, com, parent,
+                                                       llr, pla);
                break;
        case LLIT_MULTIPLE_REFERENCED:
-               rc = lfsck_layout_repair_multiple_references(env, com, llr,
-                                                            pla, &buf);
+               rc = lfsck_layout_repair_multiple_references(env, com, parent,
+                                                            llr, pla, &buf);
                break;
        case LLIT_INCONSISTENT_OWNER:
-               rc = lfsck_layout_repair_owner(env, com, llr, pla);
+               rc = lfsck_layout_repair_owner(env, com, parent, llr, pla);
                break;
        default:
                rc = 0;
@@ -3371,6 +3374,9 @@ out:
        }
        up_write(&com->lc_sem);
 
+put_parent:
+       lu_object_put(env, &parent->do_lu);
+
        return rc;
 }
 
@@ -4297,7 +4303,9 @@ static int lfsck_layout_scan_stripes(const struct lu_env *env,
                        }
                }
 
-               llr = lfsck_layout_assistant_req_init(llo, cobj, index, i);
+               llr = lfsck_layout_assistant_req_init(llo,
+                                                     lfsck_dto2fid(parent),
+                                                     cobj, index, i);
                if (IS_ERR(llr)) {
                        rc = PTR_ERR(llr);
                        goto next;
index 6e29717..529b5d1 100644 (file)
@@ -70,7 +70,7 @@ lfsck_namespace_assistant_req_init(struct lfsck_instance *lfsck,
                return ERR_PTR(-ENOMEM);
 
        INIT_LIST_HEAD(&lnr->lnr_lar.lar_list);
-       lnr->lnr_obj = lfsck_object_get(lfsck->li_obj_dir);
+       lnr->lnr_lar.lar_fid = *lfsck_dto2fid(lfsck->li_obj_dir);
        lnr->lnr_lmv = lfsck_lmv_get(lfsck->li_lmv);
        lnr->lnr_fid = ent->lde_fid;
        lnr->lnr_oit_cookie = lfsck->li_pos_current.lp_oit_cookie;
@@ -93,7 +93,6 @@ static void lfsck_namespace_assistant_req_fini(const struct lu_env *env,
        if (lnr->lnr_lmv != NULL)
                lfsck_lmv_put(env, lnr->lnr_lmv);
 
-       lu_object_put(env, &lnr->lnr_obj->do_lu);
        OBD_FREE(lnr, lnr->lnr_size);
 }
 
@@ -3804,7 +3803,7 @@ static void lfsck_namespace_close_dir(const struct lu_env *env,
        /* Generate a dummy request to indicate that all shards' name entry
         * in this striped directory has been scanned for the first time. */
        INIT_LIST_HEAD(&lnr->lnr_lar.lar_list);
-       lnr->lnr_obj = lfsck_object_get(lfsck->li_obj_dir);
+       lnr->lnr_lar.lar_fid = *lfsck_dto2fid(lfsck->li_obj_dir);
        lnr->lnr_lmv = lfsck_lmv_get(llmv);
        lnr->lnr_fid = *lfsck_dto2fid(lfsck->li_obj_dir);
        lnr->lnr_oit_cookie = lfsck->li_pos_current.lp_oit_cookie;
@@ -4703,6 +4702,8 @@ static struct lfsck_operations lfsck_namespace_ops = {
  *
  * \param[in] env      pointer to the thread context
  * \param[in] com      pointer to the lfsck component
+ * \param[in] parent   pointer to the dir object that contains the dangling
+ *                     name entry
  * \param[in] child    pointer to the object corresponding to the dangling
  *                     name entry
  * \param[in] lnr      pointer to the namespace request that contains the
@@ -4714,6 +4715,7 @@ static struct lfsck_operations lfsck_namespace_ops = {
  */
 int lfsck_namespace_repair_dangling(const struct lu_env *env,
                                    struct lfsck_component *com,
+                                   struct dt_object *parent,
                                    struct dt_object *child,
                                    struct lfsck_namespace_req *lnr)
 {
@@ -4723,7 +4725,6 @@ int lfsck_namespace_repair_dangling(const struct lu_env *env,
        struct dt_object_format         *dof    = &info->lti_dof;
        struct dt_insert_rec            *rec    = &info->lti_dt_rec;
        struct lmv_mds_md_v1            *lmv2   = &info->lti_lmv2;
-       struct dt_object                *parent = lnr->lnr_obj;
        const struct lu_name            *cname;
        struct linkea_data               ldata  = { NULL };
        struct lustre_handle             lh     = { 0 };
@@ -4937,9 +4938,9 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env,
        struct thandle             *handle   = NULL;
        struct lfsck_namespace_req *lnr      =
                        container_of0(lar, struct lfsck_namespace_req, lnr_lar);
-       struct dt_object           *dir      = lnr->lnr_obj;
+       struct dt_object           *dir      = NULL;
        struct dt_object           *obj      = NULL;
-       const struct lu_fid        *pfid     = lfsck_dto2fid(dir);
+       const struct lu_fid        *pfid;
        struct dt_device           *dev      = NULL;
        struct lustre_handle        lh       = { 0 };
        bool                        repaired = false;
@@ -4954,6 +4955,14 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env,
        enum lfsck_namespace_inconsistency_type type = LNIT_NONE;
        ENTRY;
 
+       dir = lfsck_object_find_bottom(env, lfsck, &lar->lar_fid);
+       if (IS_ERR(dir))
+               RETURN(PTR_ERR(dir));
+
+       if (unlikely(lfsck_is_dead_obj(dir)))
+               GOTO(put_dir, rc = 0);
+
+       pfid = lfsck_dto2fid(dir);
        la->la_nlink = 0;
        if (lnr->lnr_attr & LUDA_UPGRADE) {
                ns->ln_flags |= LF_UPGRADE;
@@ -4994,9 +5003,9 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env,
        }
 
        if (unlikely(lnr->lnr_dir_cookie == MDS_DIR_END_OFF)) {
-               rc = lfsck_namespace_striped_dir_rescan(env, com, lnr);
+               rc = lfsck_namespace_striped_dir_rescan(env, com, dir, lnr);
 
-               RETURN(rc);
+               GOTO(put_dir, rc);
        }
 
        if (lnr->lnr_name[0] == '.' &&
@@ -5004,9 +5013,9 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env,
                GOTO(out, rc = 0);
 
        if (lnr->lnr_lmv != NULL && lnr->lnr_lmv->ll_lmv_master) {
-               rc = lfsck_namespace_handle_striped_master(env, com, lnr);
+               rc = lfsck_namespace_handle_striped_master(env, com, dir, lnr);
 
-               RETURN(rc);
+               GOTO(put_dir, rc);
        }
 
        idx = lfsck_find_mdt_idx_by_fid(env, lfsck, &lnr->lnr_fid);
@@ -5017,7 +5026,7 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env,
                if (unlikely(strcmp(lnr->lnr_name, dotdot) == 0))
                        GOTO(out, rc = 0);
 
-               dev = lfsck->li_next;
+               dev = lfsck->li_bottom;
        } else {
                struct lfsck_tgt_desc *ltd;
 
@@ -5062,7 +5071,7 @@ dangling:
                        }
 
                        type = LNIT_DANGLING;
-                       rc = lfsck_namespace_repair_dangling(env, com,
+                       rc = lfsck_namespace_repair_dangling(env, com, dir,
                                                             obj, lnr);
                        if (rc == 0)
                                repaired = true;
@@ -5314,7 +5323,7 @@ out:
                CDEBUG(D_LFSCK, "%s: namespace LFSCK assistant fail to handle "
                       "the entry: "DFID", parent "DFID", name %.*s: rc = %d\n",
                       lfsck_lfsck2name(lfsck), PFID(&lnr->lnr_fid),
-                      PFID(lfsck_dto2fid(lnr->lnr_obj)),
+                      PFID(lfsck_dto2fid(dir)),
                       lnr->lnr_namelen, lnr->lnr_name, rc);
 
                lfsck_namespace_record_failure(env, lfsck, ns);
@@ -5332,7 +5341,7 @@ out:
                               "repaired the entry: "DFID", parent "DFID
                               ", name %.*s\n", lfsck_lfsck2name(lfsck),
                               PFID(&lnr->lnr_fid),
-                              PFID(lfsck_dto2fid(lnr->lnr_obj)),
+                              PFID(lfsck_dto2fid(dir)),
                               lnr->lnr_namelen, lnr->lnr_name);
 
                if (repaired) {
@@ -5384,6 +5393,9 @@ out:
        if (obj != NULL && !IS_ERR(obj))
                lfsck_object_put(env, obj);
 
+put_dir:
+       lu_object_put(env, &dir->do_lu);
+
        return rc;
 }
 
@@ -6008,7 +6020,7 @@ static void lfsck_namespace_assistant_fill_pos(const struct lu_env *env,
                         lnr_lar.lar_list);
        pos->lp_oit_cookie = lnr->lnr_oit_cookie;
        pos->lp_dir_cookie = lnr->lnr_dir_cookie - 1;
-       pos->lp_dir_parent = *lfsck_dto2fid(lnr->lnr_obj);
+       pos->lp_dir_parent = lnr->lnr_lar.lar_fid;
 }
 
 static int lfsck_namespace_double_scan_result(const struct lu_env *env,
index c21e1dc..e612140 100644 (file)
@@ -290,6 +290,7 @@ static inline bool lfsck_is_valid_slave_lmv(struct lmv_mds_md_v1 *lmv)
  *
  * \param[in] env      pointer to the thread context
  * \param[in] com      pointer to the lfsck component
+ * \param[in] obj      pointer to the striped directory to be handled
  * \param[in] lnr      pointer to the namespace request that contains the
  *                     striped directory to be handled and other information
  *
@@ -299,9 +300,9 @@ static inline bool lfsck_is_valid_slave_lmv(struct lmv_mds_md_v1 *lmv)
  */
 static int lfsck_remove_lmv(const struct lu_env *env,
                            struct lfsck_component *com,
+                           struct dt_object *obj,
                            struct lfsck_namespace_req *lnr)
 {
-       struct dt_object        *obj    = lnr->lnr_obj;
        struct lustre_handle     lh     = { 0 };
        int                      rc;
 
@@ -367,6 +368,7 @@ static int lfsck_remove_dirent(const struct lu_env *env,
  *
  * \param[in] env      pointer to the thread context
  * \param[in] com      pointer to the lfsck component
+ * \param[in] dir      pointer to the striped directory to be handled
  * \param[in] lslr     pointer to lfsck_disable_master_lmv slot which content
  *                     will be replaced by the given information
  * \param[in] lnr      contain the shard's FID to be used to fill the
@@ -382,6 +384,7 @@ static int lfsck_remove_dirent(const struct lu_env *env,
  */
 static int lfsck_replace_lmv(const struct lu_env *env,
                             struct lfsck_component *com,
+                            struct dt_object *dir,
                             struct lfsck_slave_lmv_rec *lslr,
                             struct lfsck_namespace_req *lnr,
                             struct lmv_mds_md_v1 *lmv,
@@ -390,7 +393,7 @@ static int lfsck_replace_lmv(const struct lu_env *env,
        struct lfsck_lmv *llmv = lnr->lnr_lmv;
        int               rc;
 
-       rc = lfsck_remove_dirent(env, com, lnr->lnr_obj,
+       rc = lfsck_remove_dirent(env, com, dir,
                                 &lslr->lslr_fid, index);
        if (rc < 0)
                return rc;
@@ -454,6 +457,7 @@ static int lfsck_replace_lmv(const struct lu_env *env,
  *
  * \param[in] env      pointer to the thread context
  * \param[in] com      pointer to the lfsck component
+ * \param[in] dir      pointer to the striped directory to be handled
  * \param[in] lnr      contain the shard's FID to fill the @lslr slot,
  *                     it also records the known max filled index and
  *                     the known max stripe count
@@ -480,13 +484,13 @@ static int lfsck_replace_lmv(const struct lu_env *env,
  */
 static int lfsck_record_lmv(const struct lu_env *env,
                            struct lfsck_component *com,
+                           struct dt_object *dir,
                            struct lfsck_namespace_req *lnr,
                            struct lmv_mds_md_v1 *lmv, __u32 shard_idx,
                            __u32 flags, __u32 flags2, __u32 *depth)
 {
        struct lfsck_instance      *lfsck = com->lc_lfsck;
        struct lfsck_lmv           *llmv  = lnr->lnr_lmv;
-       struct dt_object           *dir   = lnr->lnr_obj;
        const struct lu_fid        *fid   = &lnr->lnr_fid;
        struct lfsck_slave_lmv_rec *lslr;
        struct lfsck_rec_lmv_save  *lrls;
@@ -567,7 +571,7 @@ static int lfsck_record_lmv(const struct lu_env *env,
                         * mark the master MDT-object as read-only. The
                         * administrator can handle the conflict with
                         * more human knowledge. */
-                       rc = lfsck_remove_lmv(env, com, lnr);
+                       rc = lfsck_remove_lmv(env, com, dir, lnr);
                        break;
                case LSLF_BAD_INDEX2:
                        GOTO(out, rc = -EEXIST);
@@ -586,7 +590,7 @@ no_lmvea:
                                 * as read-only. The administrator can
                                 * handle the conflict with more human
                                 * knowledge. */
-                               rc = lfsck_remove_lmv(env, com, lnr);
+                               rc = lfsck_remove_lmv(env, com, dir, lnr);
                        } else {
                                /* Otherwise, remove the current name entry,
                                 * and add its FID in the LFSCK tracing file
@@ -609,7 +613,7 @@ no_lmvea:
                        /* The name entry claims an index that is conflict
                         * with a valid existing name entry, then try the
                         * index in the lmv recursively. */
-                       rc = lfsck_record_lmv(env, com, lnr, lmv, index,
+                       rc = lfsck_record_lmv(env, com, dir, lnr, lmv, index,
                                LSLF_BAD_INDEX2, lslr->lslr_flags, depth);
                        lmv->lmv_master_mdt_index = index;
                        if (rc == -ERANGE || rc == -EEXIST)
@@ -618,7 +622,7 @@ no_lmvea:
                                 * not know how to resolve the conflict.
                                 * We will handle it as handle the case
                                 * of 'LSLF_NONE' vs 'LSLF_NONE'. */
-                               rc = lfsck_remove_lmv(env, com, lnr);
+                               rc = lfsck_remove_lmv(env, com, dir, lnr);
 
                        break;
                default:
@@ -644,7 +648,7 @@ none:
                                 * as read-only. The administrator can
                                 * handle the conflict with more human
                                 * knowledge. */
-                               rc = lfsck_remove_lmv(env, com, lnr);
+                               rc = lfsck_remove_lmv(env, com, dir, lnr);
                        } else {
                                lrls = &lfsck->li_rec_lmv_save[*depth - 1];
                                lrls->lrls_fid = lslr->lslr_fid;
@@ -656,8 +660,8 @@ none:
                                                com, &lrls->lrls_fid,
                                                LNTF_CHECK_PARENT, true);
                                if (rc == 0)
-                                       rc = lfsck_replace_lmv(env, com, lslr,
-                                                       lnr, lmv, index, flags);
+                                       rc = lfsck_replace_lmv(env, com, dir,
+                                               lslr, lnr, lmv, index, flags);
                        }
 
                        break;
@@ -678,7 +682,7 @@ none:
                        /* The name entry claims an index that is conflict
                         * with a valid existing name entry, then try the
                         * index in the lmv recursively. */
-                       rc = lfsck_record_lmv(env, com, lnr, lmv, index,
+                       rc = lfsck_record_lmv(env, com, dir, lnr, lmv, index,
                                LSLF_BAD_INDEX2, lslr->lslr_flags, depth);
                        lmv->lmv_master_mdt_index = index;
                        if (rc == -ERANGE || rc == -EEXIST) {
@@ -700,7 +704,7 @@ none:
                case LSLF_NO_LMVEA:
                        /* Remove the existing dangling name entry.
                         * Refill the lslr slot with the given LMV. */
-                       rc = lfsck_replace_lmv(env, com, lslr, lnr,
+                       rc = lfsck_replace_lmv(env, com, dir, lslr, lnr,
                                               lmv, index, flags);
                        break;
                case LSLF_DANGLING:
@@ -714,7 +718,7 @@ none:
                        /* The name entry claims an index that is conflict
                         * with a valid existing name entry, then try the
                         * index in the lmv recursively. */
-                       rc = lfsck_record_lmv(env, com, lnr, lmv, index,
+                       rc = lfsck_record_lmv(env, com, dir, lnr, lmv, index,
                                LSLF_BAD_INDEX2, lslr->lslr_flags, depth);
                        lmv->lmv_master_mdt_index = index;
                        if (rc == -ERANGE || rc == -EEXIST)
@@ -722,7 +726,7 @@ none:
                                 * also conflict with other, then remove
                                 * the existing dangling name entry.
                                 * Refill the lslr slot with the given LMV. */
-                               rc = lfsck_replace_lmv(env, com, lslr, lnr,
+                               rc = lfsck_replace_lmv(env, com, dir, lslr, lnr,
                                                       lmv, shard_idx, flags);
 
                        break;
@@ -747,7 +751,7 @@ none:
 
                /* The existing one has another possible slot,
                 * try it recursively. */
-               rc = lfsck_record_lmv(env, com, lnr, lmv, index,
+               rc = lfsck_record_lmv(env, com, dir, lnr, lmv, index,
                                      LSLF_BAD_INDEX2, flags, depth);
                *lmv = lrls->lrls_lmv;
                lnr->lnr_fid = lrls->lrls_fid;
@@ -787,7 +791,7 @@ conflict:
                         * mark the master MDT-object as read-only. The
                         * administrator can handle the conflict with
                         * more human knowledge. */
-                       rc = lfsck_remove_lmv(env, com, lnr);
+                       rc = lfsck_remove_lmv(env, com, dir, lnr);
                        break;
                case LSLF_BAD_INDEX2:
                        GOTO(out, rc = -EEXIST);
@@ -803,7 +807,7 @@ conflict:
                        /* The name entry claims an index that is conflict
                         * with a valid existing name entry, then try the
                         * index in the lmv recursively. */
-                       rc = lfsck_record_lmv(env, com, lnr, lmv, index,
+                       rc = lfsck_record_lmv(env, com, dir, lnr, lmv, index,
                                LSLF_BAD_INDEX2, lslr->lslr_flags, depth);
                        lmv->lmv_master_mdt_index = index;
                        if (rc == -ERANGE || rc == -EEXIST)
@@ -812,7 +816,7 @@ conflict:
                                 * not know how to resolve the conflict.
                                 * We will handle it as handle the case
                                 * of 'LSLF_NONE' vs 'LSLF_NONE'. */
-                               rc = lfsck_remove_lmv(env, com, lnr);
+                               rc = lfsck_remove_lmv(env, com, dir, lnr);
 
                        break;
                }
@@ -1812,6 +1816,8 @@ out:
  *
  * \param[in] env      pointer to the thread context
  * \param[in] com      pointer to the lfsck component
+ * \paran[in] dir      pointer to the striped directory or its shard to be
+ *                     rescanned
  * \param[in] lnr      pointer to the namespace request that contains the
  *                     striped directory or the shard
  *
@@ -1820,6 +1826,7 @@ out:
  */
 int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
                                       struct lfsck_component *com,
+                                      struct dt_object *dir,
                                       struct lfsck_namespace_req *lnr)
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
@@ -1828,7 +1835,6 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
        struct lfsck_lmv                *llmv   = lnr->lnr_lmv;
        struct lmv_mds_md_v1            *lmv    = &llmv->ll_lmv;
        struct lmv_mds_md_v1            *lmv2   = &info->lti_lmv2;
-       struct dt_object                *dir    = lnr->lnr_obj;
        const struct lu_fid             *pfid   = lfsck_dto2fid(dir);
        struct lu_seq_range             *range  = &info->lti_range;
        struct seq_server_site          *ss     =
@@ -1995,7 +2001,7 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
 
 repair:
                if (create) {
-                       rc1 = lfsck_namespace_repair_dangling(env, com,
+                       rc1 = lfsck_namespace_repair_dangling(env, com, dir,
                                                              obj, lnr);
                        if (rc1 >= 0) {
                                create_repaired = true;
@@ -2172,6 +2178,8 @@ next:
  *
  * \param[in] env      pointer to the thread context
  * \param[in] com      pointer to the lfsck component
+ * \param[in] dir      pointer to the master MDT-object of the
+ *                     striped directory
  * \param[in] lnr      pointer to the namespace request that contains the
  *                     shard's name, parent object, parent's LMV, and ect.
  *
@@ -2180,6 +2188,7 @@ next:
  */
 int lfsck_namespace_handle_striped_master(const struct lu_env *env,
                                          struct lfsck_component *com,
+                                         struct dt_object *dir,
                                          struct lfsck_namespace_req *lnr)
 {
        struct lfsck_thread_info   *info        = lfsck_env_info(env);
@@ -2187,7 +2196,6 @@ int lfsck_namespace_handle_striped_master(const struct lu_env *env,
        struct lfsck_instance      *lfsck       = com->lc_lfsck;
        struct lfsck_namespace     *ns          = com->lc_file_ram;
        struct lfsck_lmv           *llmv        = lnr->lnr_lmv;
-       struct dt_object           *dir         = lnr->lnr_obj;
        const struct lu_fid        *pfid        = lfsck_dto2fid(dir);
        struct dt_object           *obj         = NULL;
        struct dt_device           *dev         = NULL;
@@ -2259,7 +2267,7 @@ dangling:
                if (rc == 0) {
                        memset(lmv, 0, sizeof(*lmv));
                        lmv->lmv_magic = LMV_MAGIC;
-                       rc = lfsck_record_lmv(env, com, lnr, lmv, stripe,
+                       rc = lfsck_record_lmv(env, com, dir, lnr, lmv, stripe,
                                              LSLF_DANGLING, LSLF_NONE, &depth);
                }
 
@@ -2282,10 +2290,10 @@ dangling:
                goto dangling;
 
        if (rc == -ENODATA)
-               rc = lfsck_record_lmv(env, com, lnr, lmv, stripe,
+               rc = lfsck_record_lmv(env, com, dir, lnr, lmv, stripe,
                                      LSLF_NO_LMVEA, LSLF_NONE, &depth);
        else if (rc == 0)
-               rc = lfsck_record_lmv(env, com, lnr, lmv, stripe,
+               rc = lfsck_record_lmv(env, com, dir, lnr, lmv, stripe,
                                      lmv->lmv_master_mdt_index != stripe ?
                                      LSLF_BAD_INDEX1 : LSLF_NONE, LSLF_NONE,
                                      &depth);
@@ -2322,7 +2330,7 @@ out:
                CDEBUG(D_LFSCK, "%s: namespace LFSCK assistant fail to handle "
                       "the shard: "DFID", parent "DFID", name %.*s: rc = %d\n",
                       lfsck_lfsck2name(lfsck), PFID(&lnr->lnr_fid),
-                      PFID(lfsck_dto2fid(lnr->lnr_obj)),
+                      PFID(lfsck_dto2fid(dir)),
                       lnr->lnr_namelen, lnr->lnr_name, rc);
 
                if ((rc == -ENOTCONN || rc == -ESHUTDOWN || rc == -EREMCHG ||