From: Fan Yong Date: Wed, 8 Apr 2015 13:29:13 +0000 (+0800) Subject: LU-6343 lfsck: locate object only when necessary X-Git-Tag: 2.7.53~37 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=5b3eef20c5a0e31d2cd9580f0cbaa0223783905a LU-6343 lfsck: locate object only when necessary 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 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 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 Change-Id: If6a3677a6ad3fa1c694ee06f9688c1f38374f8de Reviewed-on: http://review.whamcloud.com/13993 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Alex Zhuravlev Reviewed-by: Lai Siyao Reviewed-by: Oleg Drokin --- diff --git a/lustre/lfsck/lfsck_engine.c b/lustre/lfsck/lfsck_engine.c index 373bb1b..72a0ef3 100644 --- a/lustre/lfsck/lfsck_engine.c +++ b/lustre/lfsck/lfsck_engine.c @@ -608,13 +608,14 @@ out: 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) { - 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; } @@ -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 lfsck_assistant_object *lso = NULL; 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); - RETURN(0); + GOTO(out, rc = 0); } 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) - RETURN(rc); + GOTO(out, rc); 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 (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. */ - 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) - RETURN(rc); + GOTO(out, rc); 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); @@ -805,14 +820,14 @@ checkpoint: 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); - RETURN(-EINVAL); + GOTO(out, rc = -EINVAL); } rc = iops->next(env, di); @@ -821,7 +836,13 @@ checkpoint: 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; } /** diff --git a/lustre/lfsck/lfsck_internal.h b/lustre/lfsck/lfsck_internal.h index 5041e63..21163e8 100644 --- a/lustre/lfsck/lfsck_internal.h +++ b/lustre/lfsck/lfsck_internal.h @@ -360,6 +360,15 @@ struct lfsck_layout { __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; @@ -393,6 +402,7 @@ struct lfsck_operations { int (*lfsck_exec_dir)(const struct lu_env *env, struct lfsck_component *com, + struct lfsck_assistant_object *lso, struct lu_dirent *ent, __u16 type); @@ -718,15 +728,14 @@ struct lfsck_thread_args { }; 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; - __u64 lnr_oit_cookie; __u64 lnr_dir_cookie; __u32 lnr_attr; __u32 lnr_size; @@ -735,6 +744,13 @@ struct lfsck_namespace_req { 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, @@ -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_attr lti_la3; 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_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); @@ -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, - 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 */ @@ -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); } + +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 */ diff --git a/lustre/lfsck/lfsck_layout.c b/lustre/lfsck/lfsck_layout.c index e156fd2..c172ce7 100644 --- a/lustre/lfsck/lfsck_layout.c +++ b/lustre/lfsck/lfsck_layout.c @@ -88,50 +88,12 @@ struct lfsck_layout_slave_data { 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; }; -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) { @@ -215,16 +177,8 @@ lfsck_layout_llst_find_and_del(struct lfsck_layout_slave_data *llsd, 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 * -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) { @@ -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); - 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; @@ -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); - lfsck_layout_object_put(env, llr->llr_parent); + lfsck_assistant_object_put(env, lar->lar_parent); 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, - 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 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); @@ -2695,20 +2645,21 @@ static int lfsck_layout_repair_dangling(const struct lu_env *env, 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 = 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 @@ -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)); - 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); @@ -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); - rc = dt_create(env, child, cla, NULL, dof, handle); + rc = dt_create(env, child, la, NULL, dof, handle); 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, - 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); @@ -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, - 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 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); @@ -2812,10 +2762,12 @@ static int lfsck_layout_repair_unmatched_pair(const struct lu_env *env, 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); @@ -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. */ - rc = dt_attr_get(env, parent, tla); + rc = dt_attr_get(env, parent, la); 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); @@ -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, - pla->la_uid, pla->la_gid, rc); + la->la_uid, la->la_gid, 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)); + 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)); @@ -2931,7 +2887,7 @@ static int lfsck_layout_repair_multiple_references(const struct lu_env *env, 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); @@ -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 lu_attr *pla) + struct lu_attr *la) { 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; @@ -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)); - 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) @@ -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. */ - 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 (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); - tla->la_valid = LA_UID | LA_GID; 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, - pla->la_uid, pla->la_gid, rc); + la->la_uid, la->la_gid, 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, - struct dt_object *parent, + struct lfsck_assistant_object *lso, 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) @@ -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) { + 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)) - RETURN (LLIT_INCONSISTENT_OWNER); + RETURN(LLIT_INCONSISTENT_OWNER); 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 (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); @@ -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_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 dt_object *parent; + struct dt_object *parent = NULL; 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; @@ -3290,21 +3250,17 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env, 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) { - 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; @@ -3335,9 +3291,9 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env, 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), - pla, cla, llr, &buf, idx); + cla, llr, &buf, idx); 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); + /* 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; @@ -3353,11 +3311,22 @@ static int lfsck_layout_assistant_handler_p1(const struct lu_env *env, } 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) { @@ -3416,8 +3385,8 @@ out: } 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; } @@ -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_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; @@ -4309,18 +4278,27 @@ static int lfsck_layout_scan_stripes(const struct lu_env *env, 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; } } - 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; @@ -4364,8 +4342,8 @@ next: 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; } @@ -4627,6 +4605,7 @@ unlock: 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; @@ -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); - 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 = { diff --git a/lustre/lfsck/lfsck_lib.c b/lustre/lfsck/lfsck_lib.c index 679a4f7..97e3b7d 100644 --- a/lustre/lfsck/lfsck_lib.c +++ b/lustre/lfsck/lfsck_lib.c @@ -1943,6 +1943,56 @@ lfsck_assistant_data_init(struct lfsck_assistant_operations *lao, 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 diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c index 1aa9e4a..cd519fc 100644 --- a/lustre/lfsck/lfsck_namespace.c +++ b/lustre/lfsck/lfsck_namespace.c @@ -59,6 +59,7 @@ enum lfsck_nameentry_check { 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; @@ -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); - 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_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; @@ -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); + lfsck_assistant_object_put(env, lar->lar_parent); 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 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; @@ -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_assistant_object *lso = NULL; 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; } + 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); - 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_oit_cookie = lfsck->li_pos_current.lp_oit_cookie; 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, + struct lfsck_assistant_object *lso, 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; - 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; @@ -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), - 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); @@ -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; - 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; @@ -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; - 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; @@ -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)) { - 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) { - 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); @@ -5125,6 +5129,15 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env, 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, @@ -5169,10 +5182,6 @@ again: 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) { @@ -5202,13 +5211,12 @@ again: 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)) { + ns->ln_flags |= LF_INCONSISTENT; 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) { + ns->ln_flags |= LF_INCONSISTENT; type = LNIT_BAD_DIRENT; GOTO(stop, rc = 0); @@ -5241,7 +5250,6 @@ again: 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; @@ -5252,20 +5260,46 @@ again: type = LNIT_BAD_TYPE; count = 1; - ns->ln_flags |= LF_UPGRADE; 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; } - if (!lustre_handle_is_used(&lh)) + if (!lustre_handle_is_used(&lh)) { + remove = false; + newdata = false; + type = LNIT_NONE; + 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); @@ -5345,6 +5379,15 @@ out: 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) @@ -5352,6 +5395,15 @@ out: } 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; @@ -5381,12 +5433,12 @@ out: 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", - 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); @@ -5403,8 +5455,7 @@ out: 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) { @@ -5456,8 +5507,8 @@ out: 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; } @@ -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 lfsck_assistant_object *lso = NULL; 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; - 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)); @@ -5868,6 +5933,9 @@ next: } 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); @@ -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); - 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_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, diff --git a/lustre/lfsck/lfsck_striped_dir.c b/lustre/lfsck/lfsck_striped_dir.c index ba31128..d9c7c39 100644 --- a/lustre/lfsck/lfsck_striped_dir.c +++ b/lustre/lfsck/lfsck_striped_dir.c @@ -1798,8 +1798,6 @@ 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 * @@ -1808,7 +1806,6 @@ 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); @@ -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; - 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; @@ -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++; - lfsck_namespace_trace_update(env, com, - lfsck_dto2fid(dir), + lfsck_namespace_trace_update(env, com, pfid, 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 (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) @@ -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++) { - 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; @@ -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)) { - 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; @@ -1982,6 +1999,20 @@ int lfsck_namespace_striped_dir_rescan(const struct lu_env *env, 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) { @@ -2047,6 +2078,20 @@ repair: } 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); @@ -2071,6 +2116,20 @@ repair: 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; @@ -2104,8 +2163,10 @@ next: 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); + obj = NULL; + } 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] 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. * @@ -2169,7 +2237,6 @@ 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); @@ -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; - 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; @@ -2191,6 +2260,13 @@ int lfsck_namespace_handle_striped_master(const struct lu_env *env, 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); @@ -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), - 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 || @@ -2344,5 +2419,7 @@ out: if (obj != NULL && !IS_ERR(obj)) lfsck_object_put(env, obj); + lfsck_object_put(env, dir); + return rc; }