Whamcloud - gitweb
LU-6343 lfsck: locate object only when necessary 93/13993/9
authorFan Yong <fan.yong@intel.com>
Wed, 8 Apr 2015 13:29:13 +0000 (21:29 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 28 Apr 2015 05:11:36 +0000 (05:11 +0000)
Currently, for every item to be verified by the LFSCK assistant
thread, the LFSCK assistant thread will try to locate its parent
directory (for namespace LFSCK) or its parent MDT-object (for
layout LFSCK) firstly via the given parent FID. But under most
cases, the system is consistent, such locating parent object is
unnecessary. For example, for namespace LFSCK, the LFSCK main
engine has put the <parent_FID, child_name, child_FID> in the
pre-loaded request, then the assistant thread will locate the
child object with the child_FID and search its linkEA to find
the <parent_FID, child_name> pairs.

Be as some improvement, we will make the LFSCK to locate related
object (especially for parent object) only when really used.

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

index 373bb1b..72a0ef3 100644 (file)
@@ -608,13 +608,14 @@ out:
 
 static int lfsck_exec_dir(const struct lu_env *env,
                          struct lfsck_instance *lfsck,
 
 static int lfsck_exec_dir(const struct lu_env *env,
                          struct lfsck_instance *lfsck,
+                         struct lfsck_assistant_object *lso,
                          struct lu_dirent *ent, __u16 type)
 {
        struct lfsck_component *com;
        int                     rc;
 
        list_for_each_entry(com, &lfsck->li_list_scan, lc_link) {
                          struct lu_dirent *ent, __u16 type)
 {
        struct lfsck_component *com;
        int                     rc;
 
        list_for_each_entry(com, &lfsck->li_list_scan, lc_link) {
-               rc = com->lc_ops->lfsck_exec_dir(env, com, ent, type);
+               rc = com->lc_ops->lfsck_exec_dir(env, com, lso, ent, type);
                if (rc != 0)
                        return rc;
        }
                if (rc != 0)
                        return rc;
        }
@@ -743,6 +744,7 @@ static int lfsck_master_dir_engine(const struct lu_env *env,
                        (struct lu_dirent *)info->lti_key;
        struct lfsck_bookmark           *bk     = &lfsck->li_bookmark_ram;
        struct ptlrpc_thread            *thread = &lfsck->li_thread;
                        (struct lu_dirent *)info->lti_key;
        struct lfsck_bookmark           *bk     = &lfsck->li_bookmark_ram;
        struct ptlrpc_thread            *thread = &lfsck->li_thread;
+       struct lfsck_assistant_object   *lso    = NULL;
        int                              rc;
        __u16                            type;
        ENTRY;
        int                              rc;
        __u16                            type;
        ENTRY;
@@ -755,7 +757,7 @@ static int lfsck_master_dir_engine(const struct lu_env *env,
                               lfsck_lfsck2name(lfsck),
                               PFID(lfsck_dto2fid(dir)), lfsck->li_cookie_dir);
 
                               lfsck_lfsck2name(lfsck),
                               PFID(lfsck_dto2fid(dir)), lfsck->li_cookie_dir);
 
-                       RETURN(0);
+                       GOTO(out, rc = 0);
                }
 
                lfsck->li_new_scanned++;
                }
 
                lfsck->li_new_scanned++;
@@ -773,7 +775,7 @@ static int lfsck_master_dir_engine(const struct lu_env *env,
                               lfsck->li_cookie_dir, rc);
                        lfsck_fail(env, lfsck, true);
                        if (bk->lb_param & LPF_FAILOUT)
                               lfsck->li_cookie_dir, rc);
                        lfsck_fail(env, lfsck, true);
                        if (bk->lb_param & LPF_FAILOUT)
-                               RETURN(rc);
+                               GOTO(out, rc);
                        else
                                goto checkpoint;
                }
                        else
                                goto checkpoint;
                }
@@ -786,16 +788,29 @@ static int lfsck_master_dir_engine(const struct lu_env *env,
                if (ent->lde_namelen == 1 && ent->lde_name[0] == '.')
                        goto checkpoint;
 
                if (ent->lde_namelen == 1 && ent->lde_name[0] == '.')
                        goto checkpoint;
 
+               if (lso == NULL) {
+                       lso = lfsck_assistant_object_init(env,
+                               lfsck_dto2fid(dir), NULL,
+                               lfsck->li_pos_current.lp_oit_cookie, true);
+                       if (IS_ERR(lso)) {
+                               if (bk->lb_param & LPF_FAILOUT)
+                                       RETURN(PTR_ERR(lso));
+
+                               lso = NULL;
+                               goto checkpoint;
+                       }
+               }
+
                /* The type in the @ent structure may has been overwritten,
                 * so we need to pass the @type parameter independently. */
                /* The type in the @ent structure may has been overwritten,
                 * so we need to pass the @type parameter independently. */
-               rc = lfsck_exec_dir(env, lfsck, ent, type);
+               rc = lfsck_exec_dir(env, lfsck, lso, ent, type);
                if (rc != 0 && bk->lb_param & LPF_FAILOUT)
                if (rc != 0 && bk->lb_param & LPF_FAILOUT)
-                       RETURN(rc);
+                       GOTO(out, rc);
 
 checkpoint:
                rc = lfsck_checkpoint(env, lfsck);
                if (rc != 0 && bk->lb_param & LPF_FAILOUT)
 
 checkpoint:
                rc = lfsck_checkpoint(env, lfsck);
                if (rc != 0 && bk->lb_param & LPF_FAILOUT)
-                       RETURN(rc);
+                       GOTO(out, rc);
 
                /* Rate control. */
                lfsck_control_speed(lfsck);
 
                /* Rate control. */
                lfsck_control_speed(lfsck);
@@ -805,14 +820,14 @@ checkpoint:
                               lfsck_lfsck2name(lfsck),
                               PFID(lfsck_dto2fid(dir)),
                               lfsck->li_cookie_dir);
                               lfsck_lfsck2name(lfsck),
                               PFID(lfsck_dto2fid(dir)),
                               lfsck->li_cookie_dir);
-                       RETURN(0);
+                       GOTO(out, rc = 0);
                }
 
                if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_FATAL2)) {
                        spin_lock(&lfsck->li_lock);
                        thread_set_flags(thread, SVC_STOPPING);
                        spin_unlock(&lfsck->li_lock);
                }
 
                if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_FATAL2)) {
                        spin_lock(&lfsck->li_lock);
                        thread_set_flags(thread, SVC_STOPPING);
                        spin_unlock(&lfsck->li_lock);
-                       RETURN(-EINVAL);
+                       GOTO(out, rc = -EINVAL);
                }
 
                rc = iops->next(env, di);
                }
 
                rc = iops->next(env, di);
@@ -821,7 +836,13 @@ checkpoint:
        if (rc > 0 && !lfsck->li_oit_over)
                lfsck_close_dir(env, lfsck, rc);
 
        if (rc > 0 && !lfsck->li_oit_over)
                lfsck_close_dir(env, lfsck, rc);
 
-       RETURN(rc);
+       GOTO(out, rc);
+
+out:
+       if (lso != NULL)
+               lfsck_assistant_object_put(env, lso);
+
+       return rc;
 }
 
 /**
 }
 
 /**
index 5041e63..21163e8 100644 (file)
@@ -360,6 +360,15 @@ struct lfsck_layout {
        __u8    ll_ost_bitmap[0];
 };
 
        __u8    ll_ost_bitmap[0];
 };
 
+struct lfsck_assistant_object {
+       struct lu_fid           lso_fid;
+       __u64                   lso_oit_cookie;
+       struct lu_attr          lso_attr;
+       atomic_t                lso_ref;
+       unsigned int            lso_dead:1,
+                               lso_is_dir:1;
+};
+
 struct lfsck_component;
 struct lfsck_tgt_descs;
 struct lfsck_tgt_desc;
 struct lfsck_component;
 struct lfsck_tgt_descs;
 struct lfsck_tgt_desc;
@@ -393,6 +402,7 @@ struct lfsck_operations {
 
        int (*lfsck_exec_dir)(const struct lu_env *env,
                              struct lfsck_component *com,
 
        int (*lfsck_exec_dir)(const struct lu_env *env,
                              struct lfsck_component *com,
+                             struct lfsck_assistant_object *lso,
                              struct lu_dirent *ent,
                              __u16 type);
 
                              struct lu_dirent *ent,
                              __u16 type);
 
@@ -718,15 +728,14 @@ struct lfsck_thread_args {
 };
 
 struct lfsck_assistant_req {
 };
 
 struct lfsck_assistant_req {
-       struct list_head        lar_list;
-       struct lu_fid           lar_fid;
+       struct list_head                 lar_list;
+       struct lfsck_assistant_object   *lar_parent;
 };
 
 struct lfsck_namespace_req {
        struct lfsck_assistant_req       lnr_lar;
        struct lfsck_lmv                *lnr_lmv;
        struct lu_fid                    lnr_fid;
 };
 
 struct lfsck_namespace_req {
        struct lfsck_assistant_req       lnr_lar;
        struct lfsck_lmv                *lnr_lmv;
        struct lu_fid                    lnr_fid;
-       __u64                            lnr_oit_cookie;
        __u64                            lnr_dir_cookie;
        __u32                            lnr_attr;
        __u32                            lnr_size;
        __u64                            lnr_dir_cookie;
        __u32                            lnr_attr;
        __u32                            lnr_size;
@@ -735,6 +744,13 @@ struct lfsck_namespace_req {
        char                             lnr_name[0];
 };
 
        char                             lnr_name[0];
 };
 
+struct lfsck_layout_req {
+       struct lfsck_assistant_req       llr_lar;
+       struct dt_object                *llr_child;
+       __u32                            llr_ost_idx;
+       __u32                            llr_lov_idx; /* offset in LOV EA */
+};
+
 struct lfsck_assistant_operations {
        int (*la_handler_p1)(const struct lu_env *env,
                             struct lfsck_component *com,
 struct lfsck_assistant_operations {
        int (*la_handler_p1)(const struct lu_env *env,
                             struct lfsck_component *com,
@@ -821,7 +837,6 @@ struct lfsck_thread_info {
        struct lu_fid           lti_fid3;
        struct lu_attr          lti_la;
        struct lu_attr          lti_la2;
        struct lu_fid           lti_fid3;
        struct lu_attr          lti_la;
        struct lu_attr          lti_la2;
-       struct lu_attr          lti_la3;
        struct ost_id           lti_oi;
        union {
                struct lustre_mdt_attrs lti_lma;
        struct ost_id           lti_oi;
        union {
                struct lustre_mdt_attrs lti_lma;
@@ -896,6 +911,14 @@ void lfsck_thread_args_fini(struct lfsck_thread_args *lta);
 struct lfsck_assistant_data *
 lfsck_assistant_data_init(struct lfsck_assistant_operations *lao,
                          const char *name);
 struct lfsck_assistant_data *
 lfsck_assistant_data_init(struct lfsck_assistant_operations *lao,
                          const char *name);
+struct lfsck_assistant_object *
+lfsck_assistant_object_init(const struct lu_env *env, const struct lu_fid *fid,
+                           const struct lu_attr *attr, __u64 cookie,
+                           bool is_dir);
+struct dt_object *
+lfsck_assistant_object_load(const struct lu_env *env,
+                           struct lfsck_instance *lfsck,
+                           struct lfsck_assistant_object *lso);
 int lfsck_async_interpret_common(const struct lu_env *env,
                                 struct ptlrpc_request *req,
                                 void *args, int rc);
 int lfsck_async_interpret_common(const struct lu_env *env,
                                 struct ptlrpc_request *req,
                                 void *args, int rc);
@@ -1005,11 +1028,9 @@ 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,
                                         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 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 */
                                          struct lfsck_namespace_req *lnr);
 
 /* lfsck_layout.c */
@@ -1426,4 +1447,20 @@ static inline void lfsck_lmv_header_cpu_to_le(struct lmv_mds_md_v1 *dst,
        dst->lmv_hash_type = cpu_to_le32(src->lmv_hash_type);
        dst->lmv_layout_version = cpu_to_le32(src->lmv_layout_version);
 }
        dst->lmv_hash_type = cpu_to_le32(src->lmv_hash_type);
        dst->lmv_layout_version = cpu_to_le32(src->lmv_layout_version);
 }
+
+static inline struct lfsck_assistant_object *
+lfsck_assistant_object_get(struct lfsck_assistant_object *lso)
+{
+       atomic_inc(&lso->lso_ref);
+
+       return lso;
+}
+
+static inline void
+lfsck_assistant_object_put(const struct lu_env *env,
+                          struct lfsck_assistant_object *lso)
+{
+       if (atomic_dec_and_test(&lso->lso_ref))
+               OBD_FREE_PTR(lso);
+}
 #endif /* _LFSCK_INTERNAL_H */
 #endif /* _LFSCK_INTERNAL_H */
index e156fd2..c172ce7 100644 (file)
@@ -88,50 +88,12 @@ struct lfsck_layout_slave_data {
        unsigned int             llsd_rbtree_valid:1;
 };
 
        unsigned int             llsd_rbtree_valid:1;
 };
 
-struct lfsck_layout_object {
-       struct lu_attr           llo_attr;
-       atomic_t                 llo_ref;
-       __u64                    llo_cookie;
-};
-
-struct lfsck_layout_req {
-       struct lfsck_assistant_req       llr_lar;
-       struct lfsck_layout_object      *llr_parent;
-       struct dt_object                *llr_child;
-       __u32                            llr_ost_idx;
-       __u32                            llr_lov_idx; /* offset in LOV EA */
-};
-
 struct lfsck_layout_slave_async_args {
        struct obd_export                *llsaa_exp;
        struct lfsck_component           *llsaa_com;
        struct lfsck_layout_slave_target *llsaa_llst;
 };
 
 struct lfsck_layout_slave_async_args {
        struct obd_export                *llsaa_exp;
        struct lfsck_component           *llsaa_com;
        struct lfsck_layout_slave_target *llsaa_llst;
 };
 
-static struct lfsck_layout_object *
-lfsck_layout_object_init(const struct lu_env *env, struct dt_object *obj,
-                        __u64 cookie)
-{
-       struct lfsck_layout_object *llo;
-       int                         rc;
-
-       OBD_ALLOC_PTR(llo);
-       if (llo == NULL)
-               return ERR_PTR(-ENOMEM);
-
-       rc = dt_attr_get(env, obj, &llo->llo_attr);
-       if (rc != 0) {
-               OBD_FREE_PTR(llo);
-
-               return ERR_PTR(rc);
-       }
-
-       llo->llo_cookie = cookie;
-       atomic_set(&llo->llo_ref, 1);
-
-       return llo;
-}
-
 static inline void
 lfsck_layout_llst_put(struct lfsck_layout_slave_target *llst)
 {
 static inline void
 lfsck_layout_llst_put(struct lfsck_layout_slave_target *llst)
 {
@@ -215,16 +177,8 @@ lfsck_layout_llst_find_and_del(struct lfsck_layout_slave_data *llsd,
        return NULL;
 }
 
        return NULL;
 }
 
-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))
-               OBD_FREE_PTR(llo);
-}
-
 static struct lfsck_layout_req *
 static struct lfsck_layout_req *
-lfsck_layout_assistant_req_init(struct lfsck_layout_object *parent,
-                               const struct lu_fid *pfid,
+lfsck_layout_assistant_req_init(struct lfsck_assistant_object *lso,
                                struct dt_object *child, __u32 ost_idx,
                                __u32 lov_idx)
 {
                                struct dt_object *child, __u32 ost_idx,
                                __u32 lov_idx)
 {
@@ -235,10 +189,7 @@ lfsck_layout_assistant_req_init(struct lfsck_layout_object *parent,
                return ERR_PTR(-ENOMEM);
 
        INIT_LIST_HEAD(&llr->llr_lar.lar_list);
                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_lar.lar_parent = lfsck_assistant_object_get(lso);
        llr->llr_child = child;
        llr->llr_ost_idx = ost_idx;
        llr->llr_lov_idx = lov_idx;
        llr->llr_child = child;
        llr->llr_ost_idx = ost_idx;
        llr->llr_lov_idx = lov_idx;
@@ -253,7 +204,7 @@ static void lfsck_layout_assistant_req_fini(const struct lu_env *env,
                        container_of0(lar, struct lfsck_layout_req, llr_lar);
 
        lfsck_object_put(env, llr->llr_child);
                        container_of0(lar, struct lfsck_layout_req, llr_lar);
 
        lfsck_object_put(env, llr->llr_child);
-       lfsck_layout_object_put(env, llr->llr_parent);
+       lfsck_assistant_object_put(env, lar->lar_parent);
        OBD_FREE_PTR(llr);
 }
 
        OBD_FREE_PTR(llr);
 }
 
@@ -2671,12 +2622,11 @@ static int lfsck_layout_repair_dangling(const struct lu_env *env,
                                        struct lfsck_component *com,
                                        struct dt_object *parent,
                                        struct lfsck_layout_req *llr,
                                        struct lfsck_component *com,
                                        struct dt_object *parent,
                                        struct lfsck_layout_req *llr,
-                                       const struct lu_attr *pla)
+                                       struct lu_attr *la)
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
        struct filter_fid               *pfid   = &info->lti_new_pfid;
        struct dt_object_format         *dof    = &info->lti_dof;
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
        struct filter_fid               *pfid   = &info->lti_new_pfid;
        struct dt_object_format         *dof    = &info->lti_dof;
-       struct lu_attr                  *cla    = &info->lti_la2;
        struct dt_object                *child  = llr->llr_child;
        struct dt_device                *dev    = lfsck_obj2dev(child);
        const struct lu_fid             *tfid   = lu_object_fid(&parent->do_lu);
        struct dt_object                *child  = llr->llr_child;
        struct dt_device                *dev    = lfsck_obj2dev(child);
        const struct lu_fid             *tfid   = lu_object_fid(&parent->do_lu);
@@ -2695,20 +2645,21 @@ static int lfsck_layout_repair_dangling(const struct lu_env *env,
        if (!create)
                GOTO(log, rc = 1);
 
        if (!create)
                GOTO(log, rc = 1);
 
-       memset(cla, 0, sizeof(*cla));
-       cla->la_uid = pla->la_uid;
-       cla->la_gid = pla->la_gid;
-       cla->la_mode = S_IFREG | 0666;
-       cla->la_valid = LA_TYPE | LA_MODE | LA_UID | LA_GID |
-                       LA_ATIME | LA_MTIME | LA_CTIME;
-       memset(dof, 0, sizeof(*dof));
-
        rc = lfsck_ibits_lock(env, com->lc_lfsck, parent, &lh,
                              MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR,
                              LCK_EX);
        if (rc != 0)
                GOTO(log, rc);
 
        rc = lfsck_ibits_lock(env, com->lc_lfsck, parent, &lh,
                              MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR,
                              LCK_EX);
        if (rc != 0)
                GOTO(log, rc);
 
+       rc = dt_attr_get(env, parent, la);
+       if (rc != 0)
+               GOTO(unlock1, rc);
+
+       la->la_mode = S_IFREG | 0666;
+       la->la_atime = la->la_mtime = la->la_ctime = 0;
+       la->la_valid = LA_TYPE | LA_MODE | LA_UID | LA_GID |
+                      LA_ATIME | LA_MTIME | LA_CTIME;
+       memset(dof, 0, sizeof(*dof));
        pfid->ff_parent.f_seq = cpu_to_le64(tfid->f_seq);
        pfid->ff_parent.f_oid = cpu_to_le32(tfid->f_oid);
        /* Currently, the filter_fid::ff_parent::f_ver is not the real parent
        pfid->ff_parent.f_seq = cpu_to_le64(tfid->f_seq);
        pfid->ff_parent.f_oid = cpu_to_le32(tfid->f_oid);
        /* Currently, the filter_fid::ff_parent::f_ver is not the real parent
@@ -2721,7 +2672,7 @@ static int lfsck_layout_repair_dangling(const struct lu_env *env,
        if (IS_ERR(handle))
                GOTO(unlock1, rc = PTR_ERR(handle));
 
        if (IS_ERR(handle))
                GOTO(unlock1, rc = PTR_ERR(handle));
 
-       rc = dt_declare_create(env, child, cla, NULL, dof, handle);
+       rc = dt_declare_create(env, child, la, NULL, dof, handle);
        if (rc != 0)
                GOTO(stop, rc);
 
        if (rc != 0)
                GOTO(stop, rc);
 
@@ -2738,7 +2689,7 @@ static int lfsck_layout_repair_dangling(const struct lu_env *env,
        if (unlikely(lfsck_is_dead_obj(parent)))
                GOTO(unlock2, rc = 1);
 
        if (unlikely(lfsck_is_dead_obj(parent)))
                GOTO(unlock2, rc = 1);
 
-       rc = dt_create(env, child, cla, NULL, dof, handle);
+       rc = dt_create(env, child, la, NULL, dof, handle);
        if (rc != 0)
                GOTO(unlock2, rc);
 
        if (rc != 0)
                GOTO(unlock2, rc);
 
@@ -2762,7 +2713,7 @@ log:
               "stripe-index %u, owner %u/%u. %s: rc = %d\n",
               lfsck_lfsck2name(com->lc_lfsck), PFID(lfsck_dto2fid(parent)),
               PFID(lfsck_dto2fid(child)), llr->llr_ost_idx,
               "stripe-index %u, owner %u/%u. %s: rc = %d\n",
               lfsck_lfsck2name(com->lc_lfsck), PFID(lfsck_dto2fid(parent)),
               PFID(lfsck_dto2fid(child)), llr->llr_ost_idx,
-              llr->llr_lov_idx, pla->la_uid, pla->la_gid,
+              llr->llr_lov_idx, la->la_uid, la->la_gid,
               create ? "Create the lost OST-object as required" :
                        "Keep the MDT-object there by default", rc);
 
               create ? "Create the lost OST-object as required" :
                        "Keep the MDT-object there by default", rc);
 
@@ -2776,11 +2727,10 @@ 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,
                                              struct lfsck_component *com,
                                              struct dt_object *parent,
                                              struct lfsck_layout_req *llr,
-                                             const struct lu_attr *pla)
+                                             struct lu_attr *la)
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
        struct filter_fid               *pfid   = &info->lti_new_pfid;
 {
        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                *child  = llr->llr_child;
        struct dt_device                *dev    = lfsck_obj2dev(child);
        const struct lu_fid             *tfid   = lu_object_fid(&parent->do_lu);
        struct dt_object                *child  = llr->llr_child;
        struct dt_device                *dev    = lfsck_obj2dev(child);
        const struct lu_fid             *tfid   = lu_object_fid(&parent->do_lu);
@@ -2812,10 +2762,12 @@ static int lfsck_layout_repair_unmatched_pair(const struct lu_env *env,
        if (rc != 0)
                GOTO(stop, rc);
 
        if (rc != 0)
                GOTO(stop, rc);
 
-       tla->la_valid = LA_UID | LA_GID;
-       tla->la_uid = pla->la_uid;
-       tla->la_gid = pla->la_gid;
-       rc = dt_declare_attr_set(env, child, tla, handle);
+       rc = dt_attr_get(env, parent, la);
+       if (rc != 0)
+               GOTO(stop, rc);
+
+       la->la_valid = LA_UID | LA_GID;
+       rc = dt_declare_attr_set(env, child, la, handle);
        if (rc != 0)
                GOTO(stop, rc);
 
        if (rc != 0)
                GOTO(stop, rc);
 
@@ -2832,12 +2784,12 @@ static int lfsck_layout_repair_unmatched_pair(const struct lu_env *env,
                GOTO(unlock2, rc);
 
        /* Get the latest parent's owner. */
                GOTO(unlock2, rc);
 
        /* Get the latest parent's owner. */
-       rc = dt_attr_get(env, parent, tla);
+       rc = dt_attr_get(env, parent, la);
        if (rc != 0)
                GOTO(unlock2, rc);
 
        if (rc != 0)
                GOTO(unlock2, rc);
 
-       tla->la_valid = LA_UID | LA_GID;
-       rc = dt_attr_set(env, child, tla, handle);
+       la->la_valid = LA_UID | LA_GID;
+       rc = dt_attr_set(env, child, la, handle);
 
        GOTO(unlock2, rc);
 
 
        GOTO(unlock2, rc);
 
@@ -2856,7 +2808,7 @@ log:
               "stripe-index %u, owner %u/%u: rc = %d\n",
               lfsck_lfsck2name(com->lc_lfsck), PFID(lfsck_dto2fid(parent)),
               PFID(lfsck_dto2fid(child)), llr->llr_ost_idx, llr->llr_lov_idx,
               "stripe-index %u, owner %u/%u: rc = %d\n",
               lfsck_lfsck2name(com->lc_lfsck), PFID(lfsck_dto2fid(parent)),
               PFID(lfsck_dto2fid(child)), llr->llr_ost_idx, llr->llr_lov_idx,
-              pla->la_uid, pla->la_gid, rc);
+              la->la_uid, la->la_gid, rc);
 
        return rc;
 }
 
        return rc;
 }
@@ -2919,6 +2871,10 @@ static int lfsck_layout_repair_multiple_references(const struct lu_env *env,
 
        child = container_of(n, struct dt_object, do_lu);
        memset(hint, 0, sizeof(*hint));
 
        child = container_of(n, struct dt_object, do_lu);
        memset(hint, 0, sizeof(*hint));
+       rc = dt_attr_get(env, parent, la);
+       if (rc != 0)
+               GOTO(log, rc);
+
        la->la_valid = LA_UID | LA_GID;
        memset(dof, 0, sizeof(*dof));
 
        la->la_valid = LA_UID | LA_GID;
        memset(dof, 0, sizeof(*dof));
 
@@ -2931,7 +2887,7 @@ static int lfsck_layout_repair_multiple_references(const struct lu_env *env,
        if (rc != 0)
                GOTO(stop, rc);
 
        if (rc != 0)
                GOTO(stop, rc);
 
-       rc = dt_trans_start(env, dev, handle);
+       rc = dt_trans_start_local(env, dev, handle);
        if (rc != 0)
                GOTO(stop, rc);
 
        if (rc != 0)
                GOTO(stop, rc);
 
@@ -3047,10 +3003,10 @@ 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 lfsck_component *com,
                                     struct dt_object *parent,
                                     struct lfsck_layout_req *llr,
-                                    struct lu_attr *pla)
+                                    struct lu_attr *la)
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
-       struct lu_attr                  *tla    = &info->lti_la3;
+       struct lu_attr                  *tla    = &info->lti_la;
        struct dt_object                *child  = llr->llr_child;
        struct dt_device                *dev    = lfsck_obj2dev(child);
        struct thandle                  *handle;
        struct dt_object                *child  = llr->llr_child;
        struct dt_device                *dev    = lfsck_obj2dev(child);
        struct thandle                  *handle;
@@ -3061,8 +3017,8 @@ static int lfsck_layout_repair_owner(const struct lu_env *env,
        if (IS_ERR(handle))
                GOTO(log, rc = PTR_ERR(handle));
 
        if (IS_ERR(handle))
                GOTO(log, rc = PTR_ERR(handle));
 
-       tla->la_uid = pla->la_uid;
-       tla->la_gid = pla->la_gid;
+       tla->la_uid = la->la_uid;
+       tla->la_gid = la->la_gid;
        tla->la_valid = LA_UID | LA_GID;
        rc = dt_declare_attr_set(env, child, tla, handle);
        if (rc != 0)
        tla->la_valid = LA_UID | LA_GID;
        rc = dt_declare_attr_set(env, child, tla, handle);
        if (rc != 0)
@@ -3078,16 +3034,15 @@ static int lfsck_layout_repair_owner(const struct lu_env *env,
                GOTO(unlock, rc = 1);
 
        /* Get the latest parent's owner. */
                GOTO(unlock, rc = 1);
 
        /* Get the latest parent's owner. */
-       rc = dt_attr_get(env, parent, tla);
+       rc = dt_attr_get(env, parent, la);
        if (rc != 0)
                GOTO(unlock, rc);
 
        /* Some others chown/chgrp during the LFSCK, needs to do nothing. */
        if (rc != 0)
                GOTO(unlock, rc);
 
        /* Some others chown/chgrp during the LFSCK, needs to do nothing. */
-       if (unlikely(tla->la_uid != pla->la_uid ||
-                    tla->la_gid != pla->la_gid))
+       if (unlikely(tla->la_uid != la->la_uid ||
+                    tla->la_gid != la->la_gid))
                GOTO(unlock, rc = 1);
 
                GOTO(unlock, rc = 1);
 
-       tla->la_valid = LA_UID | LA_GID;
        rc = dt_attr_set(env, child, tla, handle);
 
        GOTO(unlock, rc);
        rc = dt_attr_set(env, child, tla, handle);
 
        GOTO(unlock, rc);
@@ -3104,7 +3059,7 @@ log:
               "stripe-index %u, owner %u/%u: rc = %d\n",
               lfsck_lfsck2name(com->lc_lfsck), PFID(lfsck_dto2fid(parent)),
               PFID(lfsck_dto2fid(child)), llr->llr_ost_idx, llr->llr_lov_idx,
               "stripe-index %u, owner %u/%u: rc = %d\n",
               lfsck_lfsck2name(com->lc_lfsck), PFID(lfsck_dto2fid(parent)),
               PFID(lfsck_dto2fid(child)), llr->llr_ost_idx, llr->llr_lov_idx,
-              pla->la_uid, pla->la_gid, rc);
+              la->la_uid, la->la_gid, rc);
 
        return rc;
 }
 
        return rc;
 }
@@ -3113,10 +3068,9 @@ log:
  * MDT-object (@parent) via the XATTR_NAME_FID xattr (@pfid). */
 static int lfsck_layout_check_parent(const struct lu_env *env,
                                     struct lfsck_component *com,
  * MDT-object (@parent) via the XATTR_NAME_FID xattr (@pfid). */
 static int lfsck_layout_check_parent(const struct lu_env *env,
                                     struct lfsck_component *com,
-                                    struct dt_object *parent,
+                                    struct lfsck_assistant_object *lso,
                                     const struct lu_fid *pfid,
                                     const struct lu_fid *cfid,
                                     const struct lu_fid *pfid,
                                     const struct lu_fid *cfid,
-                                    const struct lu_attr *pla,
                                     const struct lu_attr *cla,
                                     struct lfsck_layout_req *llr,
                                     struct lu_buf *lov_ea, __u32 idx)
                                     const struct lu_attr *cla,
                                     struct lfsck_layout_req *llr,
                                     struct lu_buf *lov_ea, __u32 idx)
@@ -3136,9 +3090,14 @@ static int lfsck_layout_check_parent(const struct lu_env *env,
        if (fid_is_zero(pfid)) {
                /* client never wrote. */
                if (cla->la_size == 0 && cla->la_blocks == 0) {
        if (fid_is_zero(pfid)) {
                /* client never wrote. */
                if (cla->la_size == 0 && cla->la_blocks == 0) {
+                       struct lu_attr *pla = &lso->lso_attr;
+
+                       /* Someone may has changed the owner after the @pla
+                        * pre-loaded. It can be handled when repairs owner
+                        * inside lfsck_layout_repair_owner(). */
                        if (unlikely(cla->la_uid != pla->la_uid ||
                                     cla->la_gid != pla->la_gid))
                        if (unlikely(cla->la_uid != pla->la_uid ||
                                     cla->la_gid != pla->la_gid))
-                               RETURN (LLIT_INCONSISTENT_OWNER);
+                               RETURN(LLIT_INCONSISTENT_OWNER);
 
                        RETURN(0);
                }
 
                        RETURN(0);
                }
@@ -3149,7 +3108,7 @@ static int lfsck_layout_check_parent(const struct lu_env *env,
        if (unlikely(!fid_is_sane(pfid)))
                RETURN(LLIT_UNMATCHED_PAIR);
 
        if (unlikely(!fid_is_sane(pfid)))
                RETURN(LLIT_UNMATCHED_PAIR);
 
-       if (lu_fid_eq(pfid, lu_object_fid(&parent->do_lu))) {
+       if (lu_fid_eq(pfid, &lso->lso_fid)) {
                if (llr->llr_lov_idx == idx)
                        RETURN(0);
 
                if (llr->llr_lov_idx == idx)
                        RETURN(0);
 
@@ -3274,15 +3233,16 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env,
 {
        struct lfsck_layout_req              *llr    =
                        container_of0(lar, struct lfsck_layout_req, llr_lar);
 {
        struct lfsck_layout_req              *llr    =
                        container_of0(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);
        struct filter_fid_old                *pea    = &info->lti_old_pfid;
        struct lu_fid                        *pfid   = &info->lti_fid;
        struct lu_buf                         buf    = { NULL };
        struct lfsck_layout                  *lo     = com->lc_file_ram;
        struct lfsck_thread_info             *info   = lfsck_env_info(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;
+       struct dt_object                     *parent = NULL;
        struct dt_object                     *child  = llr->llr_child;
        struct dt_object                     *child  = llr->llr_child;
-       struct lu_attr                       *pla    = &info->lti_la;
-       struct lu_attr                       *cla    = &info->lti_la2;
+       struct lu_attr                       *pla    = &lso->lso_attr;
+       struct lu_attr                       *cla    = &info->lti_la;
        struct lfsck_instance                *lfsck  = com->lc_lfsck;
        struct lfsck_bookmark                *bk     = &lfsck->li_bookmark_ram;
        enum lfsck_layout_inconsistency_type  type   = LLIT_NONE;
        struct lfsck_instance                *lfsck  = com->lc_lfsck;
        struct lfsck_bookmark                *bk     = &lfsck->li_bookmark_ram;
        enum lfsck_layout_inconsistency_type  type   = LLIT_NONE;
@@ -3290,21 +3250,17 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env,
        int                                   rc;
        ENTRY;
 
        int                                   rc;
        ENTRY;
 
-       parent = lfsck_object_find_bottom(env, lfsck, &lar->lar_fid);
-       if (IS_ERR(parent))
-               RETURN(PTR_ERR(parent));
-
-       if (unlikely(lfsck_is_dead_obj(parent)))
-               GOTO(put_parent, rc = 0);
-
-       rc = dt_attr_get(env, parent, pla);
-       if (rc != 0)
-               GOTO(out, rc);
+       if (lso->lso_dead)
+               RETURN(0);
 
        rc = dt_attr_get(env, child, cla);
        if (rc == -ENOENT) {
 
        rc = dt_attr_get(env, child, cla);
        if (rc == -ENOENT) {
-               if (unlikely(lfsck_is_dead_obj(parent)))
-                       GOTO(put_parent, rc = 0);
+               parent = lfsck_assistant_object_load(env, lfsck, lso);
+               if (IS_ERR(parent)) {
+                       rc = PTR_ERR(parent);
+
+                       RETURN(rc == -ENOENT ? 0 : rc);
+               }
 
                type = LLIT_DANGLING;
                goto repair;
 
                type = LLIT_DANGLING;
                goto repair;
@@ -3335,9 +3291,9 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env,
                pfid->f_ver = 0;
        }
 
                pfid->f_ver = 0;
        }
 
-       rc = lfsck_layout_check_parent(env, com, parent, pfid,
+       rc = lfsck_layout_check_parent(env, com, lso, pfid,
                                       lu_object_fid(&child->do_lu),
                                       lu_object_fid(&child->do_lu),
-                                      pla, cla, llr, &buf, idx);
+                                      cla, llr, &buf, idx);
        if (rc > 0) {
                type = rc;
                goto repair;
        if (rc > 0) {
                type = rc;
                goto repair;
@@ -3346,6 +3302,8 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env,
        if (rc < 0)
                GOTO(out, rc);
 
        if (rc < 0)
                GOTO(out, rc);
 
+       /* Someone may has changed the owner after the parent attr pre-loaded.
+        * It can be handled later inside the lfsck_layout_repair_owner(). */
        if (unlikely(cla->la_uid != pla->la_uid ||
                     cla->la_gid != pla->la_gid)) {
                type = LLIT_INCONSISTENT_OWNER;
        if (unlikely(cla->la_uid != pla->la_uid ||
                     cla->la_gid != pla->la_gid)) {
                type = LLIT_INCONSISTENT_OWNER;
@@ -3353,11 +3311,22 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env,
        }
 
 repair:
        }
 
 repair:
-       if (bk->lb_param & LPF_DRYRUN) {
-               if (type != LLIT_NONE)
-                       GOTO(out, rc = 1);
-               else
-                       GOTO(out, rc = 0);
+       if (type == LLIT_NONE)
+               GOTO(out, rc = 0);
+
+       if (bk->lb_param & LPF_DRYRUN)
+               GOTO(out, rc = 1);
+
+       if (parent == NULL) {
+               parent = lfsck_assistant_object_load(env, lfsck, lso);
+               if (IS_ERR(parent)) {
+                       rc = PTR_ERR(parent);
+
+                       if (rc == -ENOENT)
+                               RETURN(0);
+
+                       GOTO(out, rc);
+               }
        }
 
        switch (type) {
        }
 
        switch (type) {
@@ -3416,8 +3385,8 @@ out:
        }
        up_write(&com->lc_sem);
 
        }
        up_write(&com->lc_sem);
 
-put_parent:
-       lfsck_object_put(env, parent);
+       if (parent != NULL && !IS_ERR(parent))
+               lfsck_object_put(env, parent);
 
        return rc;
 }
 
        return rc;
 }
@@ -4187,7 +4156,7 @@ static int lfsck_layout_scan_stripes(const struct lu_env *env,
        struct lfsck_bookmark           *bk      = &lfsck->li_bookmark_ram;
        struct lfsck_layout             *lo      = com->lc_file_ram;
        struct lfsck_assistant_data     *lad     = com->lc_data;
        struct lfsck_bookmark           *bk      = &lfsck->li_bookmark_ram;
        struct lfsck_layout             *lo      = com->lc_file_ram;
        struct lfsck_assistant_data     *lad     = com->lc_data;
-       struct lfsck_layout_object      *llo     = NULL;
+       struct lfsck_assistant_object   *lso     = NULL;
        struct lov_ost_data_v1          *objs;
        struct lfsck_tgt_descs          *ltds    = &lfsck->li_ost_descs;
        struct ptlrpc_thread            *mthread = &lfsck->li_thread;
        struct lov_ost_data_v1          *objs;
        struct lfsck_tgt_descs          *ltds    = &lfsck->li_ost_descs;
        struct ptlrpc_thread            *mthread = &lfsck->li_thread;
@@ -4309,18 +4278,27 @@ static int lfsck_layout_scan_stripes(const struct lu_env *env,
                if (rc != 0)
                        goto next;
 
                if (rc != 0)
                        goto next;
 
-               if (llo == NULL) {
-                       llo = lfsck_layout_object_init(env, parent,
-                               lfsck->li_pos_current.lp_oit_cookie);
-                       if (IS_ERR(llo)) {
-                               rc = PTR_ERR(llo);
+               if (lso == NULL) {
+                       struct lu_attr *attr = &info->lti_la;
+
+                       rc = dt_attr_get(env, parent, attr);
+                       if (rc != 0) {
+                               rc = PTR_ERR(lso);
+                               goto next;
+                       }
+
+                       lso = lfsck_assistant_object_init(env,
+                               lfsck_dto2fid(parent), attr,
+                               lfsck->li_pos_current.lp_oit_cookie, false);
+                       if (IS_ERR(lso)) {
+                               rc = PTR_ERR(lso);
+                               lso = NULL;
+
                                goto next;
                        }
                }
 
                                goto next;
                        }
                }
 
-               llr = lfsck_layout_assistant_req_init(llo,
-                                                     lfsck_dto2fid(parent),
-                                                     cobj, index, i);
+               llr = lfsck_layout_assistant_req_init(lso, cobj, index, i);
                if (IS_ERR(llr)) {
                        rc = PTR_ERR(llr);
                        goto next;
                if (IS_ERR(llr)) {
                        rc = PTR_ERR(llr);
                        goto next;
@@ -4364,8 +4342,8 @@ next:
        GOTO(out, rc = 0);
 
 out:
        GOTO(out, rc = 0);
 
 out:
-       if (llo != NULL && !IS_ERR(llo))
-               lfsck_layout_object_put(env, llo);
+       if (lso != NULL)
+               lfsck_assistant_object_put(env, lso);
 
        return rc;
 }
 
        return rc;
 }
@@ -4627,6 +4605,7 @@ unlock:
 
 static int lfsck_layout_exec_dir(const struct lu_env *env,
                                 struct lfsck_component *com,
 
 static int lfsck_layout_exec_dir(const struct lu_env *env,
                                 struct lfsck_component *com,
+                                struct lfsck_assistant_object *lso,
                                 struct lu_dirent *ent, __u16 type)
 {
        return 0;
                                 struct lu_dirent *ent, __u16 type)
 {
        return 0;
@@ -5495,7 +5474,7 @@ static void lfsck_layout_assistant_fill_pos(const struct lu_env *env,
        llr = list_entry(lad->lad_req_list.next,
                         struct lfsck_layout_req,
                         llr_lar.lar_list);
        llr = list_entry(lad->lad_req_list.next,
                         struct lfsck_layout_req,
                         llr_lar.lar_list);
-       pos->lp_oit_cookie = llr->llr_parent->llo_cookie - 1;
+       pos->lp_oit_cookie = llr->llr_lar.lar_parent->lso_oit_cookie - 1;
 }
 
 struct lfsck_assistant_operations lfsck_layout_assistant_ops = {
 }
 
 struct lfsck_assistant_operations lfsck_layout_assistant_ops = {
index 679a4f7..97e3b7d 100644 (file)
@@ -1943,6 +1943,56 @@ lfsck_assistant_data_init(struct lfsck_assistant_operations *lao,
        return lad;
 }
 
        return lad;
 }
 
+struct lfsck_assistant_object *
+lfsck_assistant_object_init(const struct lu_env *env, const struct lu_fid *fid,
+                           const struct lu_attr *attr, __u64 cookie,
+                           bool is_dir)
+{
+       struct lfsck_assistant_object   *lso;
+
+       OBD_ALLOC_PTR(lso);
+       if (lso == NULL)
+               return ERR_PTR(-ENOMEM);
+
+       lso->lso_fid = *fid;
+       if (attr != NULL)
+               lso->lso_attr = *attr;
+
+       atomic_set(&lso->lso_ref, 1);
+       lso->lso_oit_cookie = cookie;
+       if (is_dir)
+               lso->lso_is_dir = 1;
+
+       return lso;
+}
+
+struct dt_object *
+lfsck_assistant_object_load(const struct lu_env *env,
+                           struct lfsck_instance *lfsck,
+                           struct lfsck_assistant_object *lso)
+{
+       struct dt_object *obj;
+
+       obj = lfsck_object_find_bottom(env, lfsck, &lso->lso_fid);
+       if (IS_ERR(obj))
+               return obj;
+
+       if (unlikely(!dt_object_exists(obj) || lfsck_is_dead_obj(obj))) {
+               lso->lso_dead = 1;
+               lfsck_object_put(env, obj);
+
+               return ERR_PTR(-ENOENT);
+       }
+
+       if (lso->lso_is_dir && unlikely(!dt_try_as_dir(env, obj))) {
+               lfsck_object_put(env, obj);
+
+               return ERR_PTR(-ENOTDIR);
+       }
+
+       return obj;
+}
+
 /**
  * Generic LFSCK asynchronous communication interpretor function.
  * The LFSCK RPC reply for both the event notification and status
 /**
  * Generic LFSCK asynchronous communication interpretor function.
  * The LFSCK RPC reply for both the event notification and status
index 1aa9e4a..cd519fc 100644 (file)
@@ -59,6 +59,7 @@ enum lfsck_nameentry_check {
 
 static struct lfsck_namespace_req *
 lfsck_namespace_assistant_req_init(struct lfsck_instance *lfsck,
 
 static struct lfsck_namespace_req *
 lfsck_namespace_assistant_req_init(struct lfsck_instance *lfsck,
+                                  struct lfsck_assistant_object *lso,
                                   struct lu_dirent *ent, __u16 type)
 {
        struct lfsck_namespace_req *lnr;
                                   struct lu_dirent *ent, __u16 type)
 {
        struct lfsck_namespace_req *lnr;
@@ -70,10 +71,9 @@ lfsck_namespace_assistant_req_init(struct lfsck_instance *lfsck,
                return ERR_PTR(-ENOMEM);
 
        INIT_LIST_HEAD(&lnr->lnr_lar.lar_list);
                return ERR_PTR(-ENOMEM);
 
        INIT_LIST_HEAD(&lnr->lnr_lar.lar_list);
-       lnr->lnr_lar.lar_fid = *lfsck_dto2fid(lfsck->li_obj_dir);
+       lnr->lnr_lar.lar_parent = lfsck_assistant_object_get(lso);
        lnr->lnr_lmv = lfsck_lmv_get(lfsck->li_lmv);
        lnr->lnr_fid = ent->lde_fid;
        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;
        lnr->lnr_dir_cookie = ent->lde_hash;
        lnr->lnr_attr = ent->lde_attrs;
        lnr->lnr_size = size;
        lnr->lnr_dir_cookie = ent->lde_hash;
        lnr->lnr_attr = ent->lde_attrs;
        lnr->lnr_size = size;
@@ -93,6 +93,7 @@ static void lfsck_namespace_assistant_req_fini(const struct lu_env *env,
        if (lnr->lnr_lmv != NULL)
                lfsck_lmv_put(env, lnr->lnr_lmv);
 
        if (lnr->lnr_lmv != NULL)
                lfsck_lmv_put(env, lnr->lnr_lmv);
 
+       lfsck_assistant_object_put(env, lar->lar_parent);
        OBD_FREE(lnr, lnr->lnr_size);
 }
 
        OBD_FREE(lnr, lnr->lnr_size);
 }
 
@@ -904,7 +905,7 @@ static int lfsck_namespace_insert_orphan(const struct lu_env *env,
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
        struct lu_name                  *cname  = &info->lti_name;
        struct dt_insert_rec            *rec    = &info->lti_dt_rec;
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
        struct lu_name                  *cname  = &info->lti_name;
        struct dt_insert_rec            *rec    = &info->lti_dt_rec;
-       struct lu_attr                  *la     = &info->lti_la3;
+       struct lu_attr                  *la     = &info->lti_la2;
        const struct lu_fid             *cfid   = lfsck_dto2fid(orphan);
        const struct lu_fid             *pfid;
        struct lu_fid                    tfid;
        const struct lu_fid             *cfid   = lfsck_dto2fid(orphan);
        const struct lu_fid             *pfid;
        struct lu_fid                    tfid;
@@ -3812,6 +3813,7 @@ static void lfsck_namespace_close_dir(const struct lu_env *env,
 {
        struct lfsck_namespace          *ns     = com->lc_file_ram;
        struct lfsck_assistant_data     *lad    = com->lc_data;
 {
        struct lfsck_namespace          *ns     = com->lc_file_ram;
        struct lfsck_assistant_data     *lad    = com->lc_data;
+       struct lfsck_assistant_object   *lso    = NULL;
        struct lfsck_instance           *lfsck  = com->lc_lfsck;
        struct lfsck_lmv                *llmv   = lfsck->li_lmv;
        struct lfsck_namespace_req      *lnr;
        struct lfsck_instance           *lfsck  = com->lc_lfsck;
        struct lfsck_lmv                *llmv   = lfsck->li_lmv;
        struct lfsck_namespace_req      *lnr;
@@ -3830,13 +3832,21 @@ static void lfsck_namespace_close_dir(const struct lu_env *env,
                RETURN_EXIT;
        }
 
                RETURN_EXIT;
        }
 
+       lso = lfsck_assistant_object_init(env, lfsck_dto2fid(lfsck->li_obj_dir),
+                       NULL, lfsck->li_pos_current.lp_oit_cookie, true);
+       if (IS_ERR(lso)) {
+               OBD_FREE(lnr, size);
+               ns->ln_striped_dirs_skipped++;
+
+               RETURN_EXIT;
+       }
+
        /* 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);
        /* 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_lar.lar_fid = *lfsck_dto2fid(lfsck->li_obj_dir);
+       lnr->lnr_lar.lar_parent = lso;
        lnr->lnr_lmv = lfsck_lmv_get(llmv);
        lnr->lnr_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;
        lnr->lnr_dir_cookie = MDS_DIR_END_OFF;
        lnr->lnr_size = size;
 
        lnr->lnr_dir_cookie = MDS_DIR_END_OFF;
        lnr->lnr_size = size;
 
@@ -4120,6 +4130,7 @@ out:
 
 static int lfsck_namespace_exec_dir(const struct lu_env *env,
                                    struct lfsck_component *com,
 
 static int lfsck_namespace_exec_dir(const struct lu_env *env,
                                    struct lfsck_component *com,
+                                   struct lfsck_assistant_object *lso,
                                    struct lu_dirent *ent, __u16 type)
 {
        struct lfsck_assistant_data     *lad     = com->lc_data;
                                    struct lu_dirent *ent, __u16 type)
 {
        struct lfsck_assistant_data     *lad     = com->lc_data;
@@ -4144,7 +4155,7 @@ static int lfsck_namespace_exec_dir(const struct lu_env *env,
        if (unlikely(lfsck_is_dead_obj(lfsck->li_obj_dir)))
                return 0;
 
        if (unlikely(lfsck_is_dead_obj(lfsck->li_obj_dir)))
                return 0;
 
-       lnr = lfsck_namespace_assistant_req_init(com->lc_lfsck, ent, type);
+       lnr = lfsck_namespace_assistant_req_init(com->lc_lfsck, lso, ent, type);
        if (IS_ERR(lnr)) {
                struct lfsck_namespace *ns = com->lc_file_ram;
 
        if (IS_ERR(lnr)) {
                struct lfsck_namespace *ns = com->lc_file_ram;
 
@@ -4972,7 +4983,7 @@ log:
        CDEBUG(D_LFSCK, "%s: namespace LFSCK assistant found dangling "
               "reference for: parent "DFID", child "DFID", type %u, "
               "name %s. %s: rc = %d\n", lfsck_lfsck2name(lfsck),
        CDEBUG(D_LFSCK, "%s: namespace LFSCK assistant found dangling "
               "reference for: parent "DFID", child "DFID", type %u, "
               "name %s. %s: rc = %d\n", lfsck_lfsck2name(lfsck),
-              PFID(&lnr->lnr_lar.lar_fid), PFID(lfsck_dto2fid(child)),
+              PFID(lfsck_dto2fid(parent)), PFID(lfsck_dto2fid(child)),
               type, cname->ln_name,
               create ? "Create the lost OST-object as required" :
                        "Keep the MDT-object there by default", rc);
               type, cname->ln_name,
               create ? "Create the lost OST-object as required" :
                        "Keep the MDT-object there by default", rc);
@@ -5002,7 +5013,8 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env,
                        container_of0(lar, struct lfsck_namespace_req, lnr_lar);
        struct dt_object           *dir      = NULL;
        struct dt_object           *obj      = NULL;
                        container_of0(lar, struct lfsck_namespace_req, lnr_lar);
        struct dt_object           *dir      = NULL;
        struct dt_object           *obj      = NULL;
-       const struct lu_fid        *pfid;
+       struct lfsck_assistant_object *lso   = lar->lar_parent;
+       const struct lu_fid        *pfid     = &lso->lso_fid;
        struct dt_device           *dev      = NULL;
        struct lustre_handle        lh       = { 0 };
        bool                        repaired = false;
        struct dt_device           *dev      = NULL;
        struct lustre_handle        lh       = { 0 };
        bool                        repaired = false;
@@ -5017,17 +5029,9 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env,
        enum lfsck_namespace_inconsistency_type type = LNIT_NONE;
        ENTRY;
 
        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);
-
-       if (unlikely(!dt_try_as_dir(env, dir)))
-               GOTO(put_dir, rc = -ENOTDIR);
+       if (lso->lso_dead)
+               RETURN(0);
 
 
-       pfid = lfsck_dto2fid(dir);
        la->la_nlink = 0;
        if (lnr->lnr_attr & LUDA_UPGRADE) {
                ns->ln_flags |= LF_UPGRADE;
        la->la_nlink = 0;
        if (lnr->lnr_attr & LUDA_UPGRADE) {
                ns->ln_flags |= LF_UPGRADE;
@@ -5068,18 +5072,18 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env,
        }
 
        if (unlikely(lnr->lnr_dir_cookie == MDS_DIR_END_OFF)) {
        }
 
        if (unlikely(lnr->lnr_dir_cookie == MDS_DIR_END_OFF)) {
-               rc = lfsck_namespace_striped_dir_rescan(env, com, dir, lnr);
+               rc = lfsck_namespace_striped_dir_rescan(env, com, lnr);
 
 
-               GOTO(put_dir, rc);
+               RETURN(rc);
        }
 
        if (fid_seq_is_dot(fid_seq(&lnr->lnr_fid)))
                GOTO(out, rc = 0);
 
        if (lnr->lnr_lmv != NULL && lnr->lnr_lmv->ll_lmv_master) {
        }
 
        if (fid_seq_is_dot(fid_seq(&lnr->lnr_fid)))
                GOTO(out, rc = 0);
 
        if (lnr->lnr_lmv != NULL && lnr->lnr_lmv->ll_lmv_master) {
-               rc = lfsck_namespace_handle_striped_master(env, com, dir, lnr);
+               rc = lfsck_namespace_handle_striped_master(env, com, lnr);
 
 
-               GOTO(put_dir, rc);
+               RETURN(rc);
        }
 
        idx = lfsck_find_mdt_idx_by_fid(env, lfsck, &lnr->lnr_fid);
        }
 
        idx = lfsck_find_mdt_idx_by_fid(env, lfsck, &lnr->lnr_fid);
@@ -5125,6 +5129,15 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env,
        if (dt_object_exists(obj) == 0) {
 
 dangling:
        if (dt_object_exists(obj) == 0) {
 
 dangling:
+               if (dir == NULL) {
+                       dir = lfsck_assistant_object_load(env, lfsck, lso);
+                       if (IS_ERR(dir)) {
+                               rc = PTR_ERR(dir);
+
+                               GOTO(trace, rc == -ENOENT ? 0 : rc);
+                       }
+               }
+
                rc = lfsck_namespace_check_exist(env, dir, obj, lnr->lnr_name);
                if (rc == 0) {
                        if (!lfsck_is_valid_slave_name_entry(env, lnr->lnr_lmv,
                rc = lfsck_namespace_check_exist(env, dir, obj, lnr->lnr_name);
                if (rc == 0) {
                        if (!lfsck_is_valid_slave_name_entry(env, lnr->lnr_lmv,
@@ -5169,10 +5182,6 @@ again:
                dtlocked = true;
        }
 
                dtlocked = true;
        }
 
-       rc = lfsck_namespace_check_exist(env, dir, obj, lnr->lnr_name);
-       if (rc != 0)
-               GOTO(stop, rc);
-
        rc = lfsck_links_read(env, obj, &ldata);
        if (unlikely(rc == -ENOENT)) {
                if (handle != NULL) {
        rc = lfsck_links_read(env, obj, &ldata);
        if (unlikely(rc == -ENOENT)) {
                if (handle != NULL) {
@@ -5202,13 +5211,12 @@ again:
                        goto stop;
                }
 
                        goto stop;
                }
 
-               ns->ln_flags |= LF_INCONSISTENT;
-
                /* If the name entry hash does not match the slave striped
                 * directory, and the name entry does not match also, then
                 * it is quite possible that name entry is corrupted. */
                if (!lfsck_is_valid_slave_name_entry(env, lnr->lnr_lmv,
                                        lnr->lnr_name, lnr->lnr_namelen)) {
                /* If the name entry hash does not match the slave striped
                 * directory, and the name entry does not match also, then
                 * it is quite possible that name entry is corrupted. */
                if (!lfsck_is_valid_slave_name_entry(env, lnr->lnr_lmv,
                                        lnr->lnr_name, lnr->lnr_namelen)) {
+                       ns->ln_flags |= LF_INCONSISTENT;
                        type = LNIT_BAD_DIRENT;
 
                        GOTO(stop, rc = 0);
                        type = LNIT_BAD_DIRENT;
 
                        GOTO(stop, rc = 0);
@@ -5219,6 +5227,7 @@ again:
                 * not recognize the name entry, then it is quite possible
                 * that the name entry is corrupted. */
                if ((lfsck_object_type(obj) & S_IFMT) != lnr->lnr_type) {
                 * not recognize the name entry, then it is quite possible
                 * that the name entry is corrupted. */
                if ((lfsck_object_type(obj) & S_IFMT) != lnr->lnr_type) {
+                       ns->ln_flags |= LF_INCONSISTENT;
                        type = LNIT_BAD_DIRENT;
 
                        GOTO(stop, rc = 0);
                        type = LNIT_BAD_DIRENT;
 
                        GOTO(stop, rc = 0);
@@ -5241,7 +5250,6 @@ again:
                        type = LNIT_BAD_TYPE;
 
                count = 1;
                        type = LNIT_BAD_TYPE;
 
                count = 1;
-               ns->ln_flags |= LF_INCONSISTENT;
                /* The magic crashed, we are not sure whether there are more
                 * corrupt data in the linkea, so remove all linkea entries. */
                remove = true;
                /* The magic crashed, we are not sure whether there are more
                 * corrupt data in the linkea, so remove all linkea entries. */
                remove = true;
@@ -5252,20 +5260,46 @@ again:
                        type = LNIT_BAD_TYPE;
 
                count = 1;
                        type = LNIT_BAD_TYPE;
 
                count = 1;
-               ns->ln_flags |= LF_UPGRADE;
                remove = false;
                newdata = true;
 
 nodata:
                if (bk->lb_param & LPF_DRYRUN) {
                remove = false;
                newdata = true;
 
 nodata:
                if (bk->lb_param & LPF_DRYRUN) {
+                       if (rc == -ENODATA)
+                               ns->ln_flags |= LF_UPGRADE;
+                       else
+                               ns->ln_flags |= LF_INCONSISTENT;
                        ns->ln_linkea_repaired++;
                        repaired = true;
                        log = true;
                        goto stop;
                }
 
                        ns->ln_linkea_repaired++;
                        repaired = true;
                        log = true;
                        goto stop;
                }
 
-               if (!lustre_handle_is_used(&lh))
+               if (!lustre_handle_is_used(&lh)) {
+                       remove = false;
+                       newdata = false;
+                       type = LNIT_NONE;
+
                        goto again;
                        goto again;
+               }
+
+               if (dir == NULL) {
+                       dir = lfsck_assistant_object_load(env, lfsck, lso);
+                       if (IS_ERR(dir)) {
+                               rc = PTR_ERR(dir);
+
+                               GOTO(stop, rc == -ENOENT ? 0 : rc);
+                       }
+               }
+
+               rc = lfsck_namespace_check_exist(env, dir, obj, lnr->lnr_name);
+               if (rc != 0)
+                       GOTO(stop, rc);
+
+               if (!remove && newdata)
+                       ns->ln_flags |= LF_UPGRADE;
+               else if (remove || !(ns->ln_flags & LF_UPGRADE))
+                       ns->ln_flags |= LF_INCONSISTENT;
 
                if (remove) {
                        LASSERT(newdata);
 
                if (remove) {
                        LASSERT(newdata);
@@ -5345,6 +5379,15 @@ out:
                ns->ln_flags |= LF_INCONSISTENT;
 
                log = false;
                ns->ln_flags |= LF_INCONSISTENT;
 
                log = false;
+               if (dir == NULL) {
+                       dir = lfsck_assistant_object_load(env, lfsck, lso);
+                       if (IS_ERR(dir)) {
+                               rc = PTR_ERR(dir);
+
+                               GOTO(trace, rc == -ENOENT ? 0 : rc);
+                       }
+               }
+
                rc = lfsck_namespace_repair_bad_name_hash(env, com, dir,
                                                lnr->lnr_lmv, lnr->lnr_name);
                if (rc >= 0)
                rc = lfsck_namespace_repair_bad_name_hash(env, com, dir,
                                                lnr->lnr_lmv, lnr->lnr_name);
                if (rc >= 0)
@@ -5352,6 +5395,15 @@ out:
        }
 
        if (rc >= 0) {
        }
 
        if (rc >= 0) {
+               if (type != LNIT_NONE && dir == NULL) {
+                       dir = lfsck_assistant_object_load(env, lfsck, lso);
+                       if (IS_ERR(dir)) {
+                               rc = PTR_ERR(dir);
+
+                               GOTO(trace, rc == -ENOENT ? 0 : rc);
+                       }
+               }
+
                switch (type) {
                case LNIT_BAD_TYPE:
                        log = false;
                switch (type) {
                case LNIT_BAD_TYPE:
                        log = false;
@@ -5381,12 +5433,12 @@ out:
                        dt_attr_get(env, obj, la);
        }
 
                        dt_attr_get(env, obj, la);
        }
 
+trace:
        down_write(&com->lc_sem);
        if (rc < 0) {
                CDEBUG(D_LFSCK, "%s: namespace LFSCK assistant fail to handle "
                       "the entry: "DFID", parent "DFID", name %.*s: rc = %d\n",
        down_write(&com->lc_sem);
        if (rc < 0) {
                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(dir)),
+                      lfsck_lfsck2name(lfsck), PFID(&lnr->lnr_fid), PFID(pfid),
                       lnr->lnr_namelen, lnr->lnr_name, rc);
 
                lfsck_namespace_record_failure(env, lfsck, ns);
                       lnr->lnr_namelen, lnr->lnr_name, rc);
 
                lfsck_namespace_record_failure(env, lfsck, ns);
@@ -5403,8 +5455,7 @@ out:
                        CDEBUG(D_LFSCK, "%s: namespace LFSCK assistant "
                               "repaired the entry: "DFID", parent "DFID
                               ", name %.*s\n", lfsck_lfsck2name(lfsck),
                        CDEBUG(D_LFSCK, "%s: namespace LFSCK assistant "
                               "repaired the entry: "DFID", parent "DFID
                               ", name %.*s\n", lfsck_lfsck2name(lfsck),
-                              PFID(&lnr->lnr_fid),
-                              PFID(lfsck_dto2fid(dir)),
+                              PFID(&lnr->lnr_fid), PFID(pfid),
                               lnr->lnr_namelen, lnr->lnr_name);
 
                if (repaired) {
                               lnr->lnr_namelen, lnr->lnr_name);
 
                if (repaired) {
@@ -5456,8 +5507,8 @@ out:
        if (obj != NULL && !IS_ERR(obj))
                lfsck_object_put(env, obj);
 
        if (obj != NULL && !IS_ERR(obj))
                lfsck_object_put(env, obj);
 
-put_dir:
-       lfsck_object_put(env, dir);
+       if (dir != NULL && !IS_ERR(dir))
+               lfsck_object_put(env, dir);
 
        return rc;
 }
 
        return rc;
 }
@@ -5812,6 +5863,7 @@ static int lfsck_namespace_rescan_striped_dir(const struct lu_env *env,
                        (struct lu_dirent *)info->lti_key;
        struct lfsck_bookmark           *bk     = &lfsck->li_bookmark_ram;
        struct ptlrpc_thread            *thread = &lfsck->li_thread;
                        (struct lu_dirent *)info->lti_key;
        struct lfsck_bookmark           *bk     = &lfsck->li_bookmark_ram;
        struct ptlrpc_thread            *thread = &lfsck->li_thread;
+       struct lfsck_assistant_object   *lso    = NULL;
        struct lfsck_namespace_req      *lnr;
        struct lfsck_assistant_req      *lar;
        int                              rc;
        struct lfsck_namespace_req      *lnr;
        struct lfsck_assistant_req      *lar;
        int                              rc;
@@ -5846,7 +5898,20 @@ static int lfsck_namespace_rescan_striped_dir(const struct lu_env *env,
                if (name_is_dot_or_dotdot(ent->lde_name, ent->lde_namelen))
                        goto next;
 
                if (name_is_dot_or_dotdot(ent->lde_name, ent->lde_namelen))
                        goto next;
 
-               lnr = lfsck_namespace_assistant_req_init(lfsck, ent, type);
+               if (lso == NULL) {
+                       lso = lfsck_assistant_object_init(env,
+                               lfsck_dto2fid(dir), NULL,
+                               lfsck->li_pos_current.lp_oit_cookie, true);
+                       if (IS_ERR(lso)) {
+                               if (bk->lb_param & LPF_FAILOUT)
+                                       GOTO(out, rc = PTR_ERR(lso));
+
+                               lso = NULL;
+                               goto next;
+                       }
+               }
+
+               lnr = lfsck_namespace_assistant_req_init(lfsck, lso, ent, type);
                if (IS_ERR(lnr)) {
                        if (bk->lb_param & LPF_FAILOUT)
                                GOTO(out, rc = PTR_ERR(lnr));
                if (IS_ERR(lnr)) {
                        if (bk->lb_param & LPF_FAILOUT)
                                GOTO(out, rc = PTR_ERR(lnr));
@@ -5868,6 +5933,9 @@ next:
        } while (rc == 0);
 
 out:
        } while (rc == 0);
 
 out:
+       if (lso != NULL && !IS_ERR(lso))
+               lfsck_assistant_object_put(env, lso);
+
        lfsck_close_dir(env, lfsck, rc);
        if (rc <= 0)
                RETURN(rc);
        lfsck_close_dir(env, lfsck, rc);
        if (rc <= 0)
                RETURN(rc);
@@ -6078,9 +6146,9 @@ static void lfsck_namespace_assistant_fill_pos(const struct lu_env *env,
        lnr = list_entry(lad->lad_req_list.next,
                         struct lfsck_namespace_req,
                         lnr_lar.lar_list);
        lnr = list_entry(lad->lad_req_list.next,
                         struct lfsck_namespace_req,
                         lnr_lar.lar_list);
-       pos->lp_oit_cookie = lnr->lnr_oit_cookie;
+       pos->lp_oit_cookie = lnr->lnr_lar.lar_parent->lso_oit_cookie;
        pos->lp_dir_cookie = lnr->lnr_dir_cookie - 1;
        pos->lp_dir_cookie = lnr->lnr_dir_cookie - 1;
-       pos->lp_dir_parent = lnr->lnr_lar.lar_fid;
+       pos->lp_dir_parent = lnr->lnr_lar.lar_parent->lso_fid;
 }
 
 static int lfsck_namespace_double_scan_result(const struct lu_env *env,
 }
 
 static int lfsck_namespace_double_scan_result(const struct lu_env *env,
index ba31128..d9c7c39 100644 (file)
@@ -1798,8 +1798,6 @@ out:
  *
  * \param[in] env      pointer to the thread context
  * \param[in] com      pointer to the lfsck component
  *
  * \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
  *
  * \param[in] lnr      pointer to the namespace request that contains the
  *                     striped directory or the shard
  *
@@ -1808,7 +1806,6 @@ out:
  */
 int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
                                       struct lfsck_component *com,
  */
 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);
                                       struct lfsck_namespace_req *lnr)
 {
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
@@ -1817,7 +1814,10 @@ 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 lfsck_lmv                *llmv   = lnr->lnr_lmv;
        struct lmv_mds_md_v1            *lmv    = &llmv->ll_lmv;
        struct lmv_mds_md_v1            *lmv2   = &info->lti_lmv2;
-       const struct lu_fid             *pfid   = lfsck_dto2fid(dir);
+       struct lfsck_assistant_object   *lso    = lnr->lnr_lar.lar_parent;
+       const struct lu_fid             *pfid   = &lso->lso_fid;
+       struct dt_object                *dir    = NULL;
+       struct dt_object                *obj    = NULL;
        struct lu_seq_range             *range  = &info->lti_range;
        struct seq_server_site          *ss     = lfsck_dev_site(lfsck);
        __u32                            stripe_count;
        struct lu_seq_range             *range  = &info->lti_range;
        struct seq_server_site          *ss     = lfsck_dev_site(lfsck);
        __u32                            stripe_count;
@@ -1829,8 +1829,7 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
        if (llmv->ll_lmv_slave) {
                if (llmv->ll_lmv_verified) {
                        ns->ln_striped_shards_scanned++;
        if (llmv->ll_lmv_slave) {
                if (llmv->ll_lmv_verified) {
                        ns->ln_striped_shards_scanned++;
-                       lfsck_namespace_trace_update(env, com,
-                                       lfsck_dto2fid(dir),
+                       lfsck_namespace_trace_update(env, com, pfid,
                                        LNTF_UNCERTAIN_LMV |
                                        LNTF_RECHECK_NAME_HASH, false);
                }
                                        LNTF_UNCERTAIN_LMV |
                                        LNTF_RECHECK_NAME_HASH, false);
                }
@@ -1879,6 +1878,15 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
        }
 
        if (llmv->ll_lmv_updated) {
        }
 
        if (llmv->ll_lmv_updated) {
+               if (dir == NULL) {
+                       dir = lfsck_assistant_object_load(env, lfsck, lso);
+                       if (IS_ERR(dir)) {
+                               rc = PTR_ERR(dir);
+
+                               RETURN(rc == -ENOENT ? 0 : rc);
+                       }
+               }
+
                lmv->lmv_layout_version++;
                rc = lfsck_namespace_update_lmv(env, com, dir, lmv, false);
                if (rc != 0)
                lmv->lmv_layout_version++;
                rc = lfsck_namespace_update_lmv(env, com, dir, lmv, false);
                if (rc != 0)
@@ -1890,7 +1898,6 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
 
        fld_range_set_mdt(range);
        for (i = 0; i <= llmv->ll_max_filled_off; i++) {
 
        fld_range_set_mdt(range);
        for (i = 0; i <= llmv->ll_max_filled_off; i++) {
-               struct dt_object *obj = NULL;
                struct lfsck_slave_lmv_rec *lslr = llmv->ll_lslr + i;
                const struct lu_fid *cfid = &lslr->lslr_fid;
                const struct lu_name *cname;
                struct lfsck_slave_lmv_rec *lslr = llmv->ll_lslr + i;
                const struct lu_fid *cfid = &lslr->lslr_fid;
                const struct lu_name *cname;
@@ -1917,8 +1924,18 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
 
                obj = lfsck_object_find_bottom_nowait(env, lfsck, cfid);
                if (IS_ERR(obj)) {
 
                obj = lfsck_object_find_bottom_nowait(env, lfsck, cfid);
                if (IS_ERR(obj)) {
-                       if (lfsck_is_dead_obj(dir))
-                               RETURN(0);
+                       if (dir == NULL) {
+                               dir = lfsck_assistant_object_load(env, lfsck,
+                                                                 lso);
+                               if (IS_ERR(dir)) {
+                                       if (PTR_ERR(dir) == -ENOENT)
+                                               RETURN(0);
+
+                                       dir = NULL;
+                               }
+                       } else if (lfsck_is_dead_obj(dir)) {
+                               GOTO(out, rc = 0);
+                       }
 
                        rc1 = PTR_ERR(obj);
                        goto next;
 
                        rc1 = PTR_ERR(obj);
                        goto next;
@@ -1982,6 +1999,20 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env,
 
 repair:
                if (create) {
 
 repair:
                if (create) {
+                       if (dir == NULL) {
+                               dir = lfsck_assistant_object_load(env, lfsck,
+                                                                 lso);
+                               if (IS_ERR(dir)) {
+                                       rc1 = PTR_ERR(dir);
+
+                                       if (rc1 == -ENOENT)
+                                               GOTO(out, rc = 0);
+
+                                       dir = NULL;
+                                       goto next;
+                               }
+                       }
+
                        rc1 = lfsck_namespace_repair_dangling(env, com, dir,
                                                              obj, lnr);
                        if (rc1 >= 0) {
                        rc1 = lfsck_namespace_repair_dangling(env, com, dir,
                                                              obj, lnr);
                        if (rc1 >= 0) {
@@ -2047,6 +2078,20 @@ repair:
                }
 
                if (rename) {
                }
 
                if (rename) {
+                       if (dir == NULL) {
+                               dir = lfsck_assistant_object_load(env, lfsck,
+                                                                 lso);
+                               if (IS_ERR(dir)) {
+                                       rc1 = PTR_ERR(dir);
+
+                                       if (rc1 == -ENOENT)
+                                               GOTO(out, rc = 0);
+
+                                       dir = NULL;
+                                       goto next;
+                               }
+                       }
+
                        rc1 = lfsck_namespace_repair_dirent(env, com, dir, obj,
                                        info->lti_tmpbuf2, lnr->lnr_name,
                                        lnr->lnr_type, true, false);
                        rc1 = lfsck_namespace_repair_dirent(env, com, dir, obj,
                                        info->lti_tmpbuf2, lnr->lnr_name,
                                        lnr->lnr_type, true, false);
@@ -2071,6 +2116,20 @@ repair:
                        if (rc1 != 0)
                                goto next;
 
                        if (rc1 != 0)
                                goto next;
 
+                       if (dir == NULL) {
+                               dir = lfsck_assistant_object_load(env, lfsck,
+                                                                 lso);
+                               if (IS_ERR(dir)) {
+                                       rc1 = PTR_ERR(dir);
+
+                                       if (rc1 == -ENOENT)
+                                               GOTO(out, rc = 0);
+
+                                       dir = NULL;
+                                       goto next;
+                               }
+                       }
+
                        rc1 = linkea_add_buf(&ldata, cname, lfsck_dto2fid(dir));
                        if (rc1 != 0)
                                goto next;
                        rc1 = linkea_add_buf(&ldata, cname, lfsck_dto2fid(dir));
                        if (rc1 != 0)
                                goto next;
@@ -2104,8 +2163,10 @@ next:
                      repair_lmvea ? "yes" : "no",
                      lmvea_repaired ? "yes" : "no", rc1);
 
                      repair_lmvea ? "yes" : "no",
                      lmvea_repaired ? "yes" : "no", rc1);
 
-               if (obj != NULL && !IS_ERR(obj))
+               if (obj != NULL && !IS_ERR(obj)) {
                        lfsck_object_put(env, obj);
                        lfsck_object_put(env, obj);
+                       obj = NULL;
+               }
 
                if (rc1 < 0) {
                        rc = rc1;
 
                if (rc1 < 0) {
                        rc = rc1;
@@ -2113,7 +2174,16 @@ next:
                }
        }
 
                }
        }
 
-       RETURN(rc);
+       GOTO(out, rc);
+
+out:
+       if (obj != NULL && !IS_ERR(obj))
+               lfsck_object_put(env, obj);
+
+       if (dir != NULL && !IS_ERR(dir))
+               lfsck_object_put(env, dir);
+
+       return rc;
 }
 
 /**
 }
 
 /**
@@ -2159,8 +2229,6 @@ next:
  *
  * \param[in] env      pointer to the thread context
  * \param[in] com      pointer to the lfsck component
  *
  * \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.
  *
  * \param[in] lnr      pointer to the namespace request that contains the
  *                     shard's name, parent object, parent's LMV, and ect.
  *
@@ -2169,7 +2237,6 @@ next:
  */
 int lfsck_namespace_handle_striped_master(const struct lu_env *env,
                                          struct lfsck_component *com,
  */
 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);
                                          struct lfsck_namespace_req *lnr)
 {
        struct lfsck_thread_info   *info        = lfsck_env_info(env);
@@ -2177,7 +2244,9 @@ 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 lfsck_instance      *lfsck       = com->lc_lfsck;
        struct lfsck_namespace     *ns          = com->lc_file_ram;
        struct lfsck_lmv           *llmv        = lnr->lnr_lmv;
-       const struct lu_fid        *pfid        = lfsck_dto2fid(dir);
+       struct lfsck_assistant_object *lso      = lnr->lnr_lar.lar_parent;
+       const struct lu_fid        *pfid        = &lso->lso_fid;
+       struct dt_object           *dir;
        struct dt_object           *obj         = NULL;
        struct dt_device           *dev         = NULL;
        int                         shard_idx   = 0;
        struct dt_object           *obj         = NULL;
        struct dt_device           *dev         = NULL;
        int                         shard_idx   = 0;
@@ -2191,6 +2260,13 @@ int lfsck_namespace_handle_striped_master(const struct lu_env *env,
        if (unlikely(llmv->ll_ignore))
                RETURN(0);
 
        if (unlikely(llmv->ll_ignore))
                RETURN(0);
 
+       dir = lfsck_assistant_object_load(env, lfsck, lso);
+       if (IS_ERR(dir)) {
+               rc = PTR_ERR(dir);
+
+               RETURN(rc == -ENOENT ? 0 : rc);
+       }
+
        shard_idx = lfsck_find_mdt_idx_by_fid(env, lfsck, &lnr->lnr_fid);
        if (shard_idx < 0)
                GOTO(fail_lmv, rc = shard_idx);
        shard_idx = lfsck_find_mdt_idx_by_fid(env, lfsck, &lnr->lnr_fid);
        if (shard_idx < 0)
                GOTO(fail_lmv, rc = shard_idx);
@@ -2311,8 +2387,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),
                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(dir)),
-                      lnr->lnr_namelen, lnr->lnr_name, rc);
+                      PFID(pfid), lnr->lnr_namelen, lnr->lnr_name, rc);
 
                if ((rc == -ENOTCONN || rc == -ESHUTDOWN || rc == -EREMCHG ||
                     rc == -ETIMEDOUT || rc == -EHOSTDOWN ||
 
                if ((rc == -ENOTCONN || rc == -ESHUTDOWN || rc == -EREMCHG ||
                     rc == -ETIMEDOUT || rc == -EHOSTDOWN ||
@@ -2344,5 +2419,7 @@ out:
        if (obj != NULL && !IS_ERR(obj))
                lfsck_object_put(env, obj);
 
        if (obj != NULL && !IS_ERR(obj))
                lfsck_object_put(env, obj);
 
+       lfsck_object_put(env, dir);
+
        return rc;
 }
        return rc;
 }