X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Flfsck%2Flfsck_namespace.c;h=f4308bc02d18e753c84b83312f4c7b3ed27b545f;hp=6ef4cc739c1c97b6879f9a2c534baa2f1920e96e;hb=44888417ecbf09fc6f294311dd98914aefda05c4;hpb=ad6dd123cc475e8babcc1b8698fc4d1963841832 diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c index 6ef4cc7..f4308bc 100644 --- a/lustre/lfsck/lfsck_namespace.c +++ b/lustre/lfsck/lfsck_namespace.c @@ -64,8 +64,8 @@ lfsck_namespace_assistant_req_init(struct lfsck_instance *lfsck, return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&lnr->lnr_lar.lar_list); - lu_object_get(&lfsck->li_obj_dir->do_lu); - lnr->lnr_obj = lfsck->li_obj_dir; + lnr->lnr_obj = lfsck_object_get(lfsck->li_obj_dir); + lnr->lnr_lmv = lfsck_lmv_get(lfsck->li_lmv); lnr->lnr_fid = ent->lde_fid; lnr->lnr_oit_cookie = lfsck->li_pos_current.lp_oit_cookie; lnr->lnr_dir_cookie = ent->lde_hash; @@ -84,6 +84,9 @@ static void lfsck_namespace_assistant_req_fini(const struct lu_env *env, struct lfsck_namespace_req *lnr = container_of0(lar, struct lfsck_namespace_req, lnr_lar); + if (lnr->lnr_lmv != NULL) + lfsck_lmv_put(env, lnr->lnr_lmv); + lu_object_put(env, &lnr->lnr_obj->do_lu); OBD_FREE(lnr, lnr->lnr_size); } @@ -131,6 +134,25 @@ static void lfsck_namespace_le_to_cpu(struct lfsck_namespace *dst, dst->ln_bad_type_repaired = le64_to_cpu(src->ln_bad_type_repaired); dst->ln_lost_dirent_repaired = le64_to_cpu(src->ln_lost_dirent_repaired); + dst->ln_striped_dirs_scanned = + le64_to_cpu(src->ln_striped_dirs_scanned); + dst->ln_striped_dirs_repaired = + le64_to_cpu(src->ln_striped_dirs_repaired); + dst->ln_striped_dirs_failed = + le64_to_cpu(src->ln_striped_dirs_failed); + dst->ln_striped_dirs_disabled = + le64_to_cpu(src->ln_striped_dirs_disabled); + dst->ln_striped_dirs_skipped = + le64_to_cpu(src->ln_striped_dirs_skipped); + dst->ln_striped_shards_scanned = + le64_to_cpu(src->ln_striped_shards_scanned); + dst->ln_striped_shards_repaired = + le64_to_cpu(src->ln_striped_shards_repaired); + dst->ln_striped_shards_failed = + le64_to_cpu(src->ln_striped_shards_failed); + dst->ln_striped_shards_skipped = + le64_to_cpu(src->ln_striped_shards_skipped); + dst->ln_name_hash_repaired = le64_to_cpu(src->ln_name_hash_repaired); dst->ln_local_lpf_scanned = le64_to_cpu(src->ln_local_lpf_scanned); dst->ln_local_lpf_moved = le64_to_cpu(src->ln_local_lpf_moved); dst->ln_local_lpf_skipped = le64_to_cpu(src->ln_local_lpf_skipped); @@ -181,6 +203,25 @@ static void lfsck_namespace_cpu_to_le(struct lfsck_namespace *dst, dst->ln_bad_type_repaired = cpu_to_le64(src->ln_bad_type_repaired); dst->ln_lost_dirent_repaired = cpu_to_le64(src->ln_lost_dirent_repaired); + dst->ln_striped_dirs_scanned = + cpu_to_le64(src->ln_striped_dirs_scanned); + dst->ln_striped_dirs_repaired = + cpu_to_le64(src->ln_striped_dirs_repaired); + dst->ln_striped_dirs_failed = + cpu_to_le64(src->ln_striped_dirs_failed); + dst->ln_striped_dirs_disabled = + cpu_to_le64(src->ln_striped_dirs_disabled); + dst->ln_striped_dirs_skipped = + cpu_to_le64(src->ln_striped_dirs_skipped); + dst->ln_striped_shards_scanned = + cpu_to_le64(src->ln_striped_shards_scanned); + dst->ln_striped_shards_repaired = + cpu_to_le64(src->ln_striped_shards_repaired); + dst->ln_striped_shards_failed = + cpu_to_le64(src->ln_striped_shards_failed); + dst->ln_striped_shards_skipped = + cpu_to_le64(src->ln_striped_shards_skipped); + dst->ln_name_hash_repaired = cpu_to_le64(src->ln_name_hash_repaired); dst->ln_local_lpf_scanned = cpu_to_le64(src->ln_local_lpf_scanned); dst->ln_local_lpf_moved = cpu_to_le64(src->ln_local_lpf_moved); dst->ln_local_lpf_skipped = cpu_to_le64(src->ln_local_lpf_skipped); @@ -728,6 +769,8 @@ static int lfsck_namespace_filter_linkea_entry(struct linkea_data *ldata, * type "O": The MDT-object has no linkEA, and there is no name * entry that references the MDT-object. * + * type "S": The orphan MDT-object is a shard of a striped directory + * * \see lfsck_layout_recreate_parent() for more types. * * The orphan name will be like: @@ -1088,6 +1131,8 @@ log: * * \see lfsck_layout_recreate_parent() for more types. * + * \param[in] lmv pointer to master LMV EA that will be set to the orphan + * * \retval positive number for repaired cases * \retval 0 if needs to repair nothing * \retval negative error number on failure @@ -1095,7 +1140,8 @@ log: static int lfsck_namespace_create_orphan_remote(const struct lu_env *env, struct lfsck_component *com, struct dt_object *orphan, - __u32 type) + __u32 type, + struct lmv_mds_md_v1 *lmv) { struct lfsck_thread_info *info = lfsck_env_info(env); struct lfsck_request *lr = &info->lti_lr; @@ -1144,6 +1190,13 @@ static int lfsck_namespace_create_orphan_remote(const struct lu_env *env, lr->lr_active = LFSCK_TYPE_NAMESPACE; lr->lr_fid = *fid; lr->lr_type = type; + if (lmv != NULL) { + lr->lr_hash_type = lmv->lmv_hash_type; + lr->lr_stripe_count = lmv->lmv_stripe_count; + lr->lr_layout_version = lmv->lmv_layout_version; + memcpy(lr->lr_pool_name, lmv->lmv_pool_name, + sizeof(lr->lr_pool_name)); + } ptlrpc_request_set_replen(req); rc = ptlrpc_queue_wait(req); @@ -1187,13 +1240,16 @@ out: * * \see lfsck_layout_recreate_parent() for more types. * + * \param[in] lmv pointer to master LMV EA that will be set to the orphan + * * \retval positive number for repaired cases * \retval negative error number on failure */ static int lfsck_namespace_create_orphan_local(const struct lu_env *env, struct lfsck_component *com, struct dt_object *orphan, - __u32 type) + __u32 type, + struct lmv_mds_md_v1 *lmv) { struct lfsck_thread_info *info = lfsck_env_info(env); struct lu_attr *la = &info->lti_la; @@ -1202,6 +1258,7 @@ static int lfsck_namespace_create_orphan_local(const struct lu_env *env, struct lu_name *cname = &info->lti_name2; struct dt_insert_rec *rec = &info->lti_dt_rec; struct lu_fid *tfid = &info->lti_fid; + struct lmv_mds_md_v1 *lmv2 = &info->lti_lmv2; const struct lu_fid *cfid = lfsck_dto2fid(orphan); const struct lu_fid *pfid; struct lfsck_instance *lfsck = com->lc_lfsck; @@ -1212,6 +1269,7 @@ static int lfsck_namespace_create_orphan_local(const struct lu_env *env, struct lustre_handle lh = { 0 }; struct linkea_data ldata = { 0 }; struct lu_buf linkea_buf; + struct lu_buf lmv_buf; char name[32]; int namelen; int idx = 0; @@ -1288,6 +1346,17 @@ static int lfsck_namespace_create_orphan_local(const struct lu_env *env, if (rc != 0) GOTO(stop, rc); + if (lmv != NULL) { + lmv->lmv_magic = LMV_MAGIC; + lmv->lmv_master_mdt_index = lfsck_dev_idx(dev); + lfsck_lmv_header_cpu_to_le(lmv2, lmv); + lfsck_buf_init(&lmv_buf, lmv2, sizeof(*lmv2)); + rc = dt_declare_xattr_set(env, child, &lmv_buf, + XATTR_NAME_LMV, 0, th); + if (rc != 0) + GOTO(stop, rc); + } + lfsck_buf_init(&linkea_buf, ldata.ld_buf->lb_buf, ldata.ld_leh->leh_len); rc = dt_declare_xattr_set(env, child, &linkea_buf, @@ -1337,6 +1406,13 @@ static int lfsck_namespace_create_orphan_local(const struct lu_env *env, GOTO(unlock2, rc); } + if (lmv != NULL) { + rc = dt_xattr_set(env, child, &lmv_buf, XATTR_NAME_LMV, 0, + th, BYPASS_CAPA); + if (rc != 0) + GOTO(unlock2, rc); + } + rc = dt_xattr_set(env, child, &linkea_buf, XATTR_NAME_LINK, 0, th, BYPASS_CAPA); dt_write_unlock(env, child); @@ -1394,23 +1470,26 @@ log: * * \see lfsck_layout_recreate_parent() for more types. * + * \param[in] lmv pointer to master LMV EA that will be set to the orphan + * * \retval positive number for repaired cases * \retval 0 if needs to repair nothing * \retval negative error number on failure */ static int lfsck_namespace_create_orphan(const struct lu_env *env, struct lfsck_component *com, - struct dt_object *orphan) + struct dt_object *orphan, + struct lmv_mds_md_v1 *lmv) { struct lfsck_namespace *ns = com->lc_file_ram; int rc; if (dt_object_remote(orphan)) rc = lfsck_namespace_create_orphan_remote(env, com, orphan, - S_IFDIR); + S_IFDIR, lmv); else rc = lfsck_namespace_create_orphan_local(env, com, orphan, - S_IFDIR); + S_IFDIR, lmv); if (rc != 0) ns->ln_flags |= LF_INCONSISTENT; @@ -2264,6 +2343,7 @@ lfsck_namespace_dsd_single(const struct lu_env *env, struct lfsck_namespace *ns = com->lc_file_ram; struct lfsck_instance *lfsck = com->lc_lfsck; struct dt_object *parent = NULL; + struct lmv_mds_md_v1 *lmv; int rc = 0; ENTRY; @@ -2308,8 +2388,33 @@ lfsck_namespace_dsd_single(const struct lu_env *env, lfsck_ibits_unlock(lh, LCK_EX); lost_parent: + lmv = &info->lti_lmv; + rc = lfsck_read_stripe_lmv(env, child, lmv); + if (rc != 0 && rc != -ENODATA) + GOTO(out, rc); + + if (rc == -ENODATA || lmv->lmv_magic != LMV_MAGIC_STRIPE) { + lmv = NULL; + } else if (lfsck_shard_name_to_index(env, + cname->ln_name, cname->ln_namelen, + S_IFDIR, cfid) < 0) { + /* It is an invalid name entry, we + * cannot trust the parent also. */ + rc = lfsck_namespace_shrink_linkea(env, com, child, + ldata, cname, tfid, true); + if (rc < 0) + GOTO(out, rc); + + snprintf(info->lti_tmpbuf, sizeof(info->lti_tmpbuf), + "-"DFID, PFID(pfid)); + rc = lfsck_namespace_insert_orphan(env, com, child, + info->lti_tmpbuf, "S", NULL); + + GOTO(out, rc); + } + /* Create the lost parent as an orphan. */ - rc = lfsck_namespace_create_orphan(env, com, parent); + rc = lfsck_namespace_create_orphan(env, com, parent, lmv); if (rc >= 0) { /* Add the missing name entry to the parent. */ rc = lfsck_namespace_insert_normal(env, com, parent, @@ -2371,6 +2476,28 @@ lost_parent: } lfsck_ibits_unlock(lh, LCK_EX); + rc = lfsck_namespace_check_name(env, parent, child, cname); + if (rc == -ENOENT) + goto lost_parent; + + if (rc < 0) + GOTO(out, rc); + + /* It is an invalid name entry, drop it. */ + if (unlikely(rc > 0)) { + rc = lfsck_namespace_shrink_linkea(env, com, child, + ldata, cname, tfid, true); + if (rc >= 0) { + snprintf(info->lti_tmpbuf, + sizeof(info->lti_tmpbuf), + "-"DFID, PFID(pfid)); + rc = lfsck_namespace_insert_orphan(env, com, + child, info->lti_tmpbuf, "D", NULL); + } + + GOTO(out, rc); + } + /* Add the missing name entry back to the namespace. */ rc = lfsck_namespace_insert_normal(env, com, parent, child, cname->ln_name); @@ -3172,7 +3299,7 @@ lost_parent: /* Create the lost parent as an orphan. */ rc = lfsck_namespace_create_orphan(env, com, - parent); + parent, NULL); if (rc < 0) { lfsck_object_put(env, parent); @@ -3303,6 +3430,30 @@ lost_parent: GOTO(out, rc = 0); } + rc = lfsck_namespace_check_name(env, parent, child, cname); + if (rc == -ENOENT) + goto lost_parent; + + if (rc < 0) { + lfsck_object_put(env, parent); + + GOTO(out, rc); + } + + /* It is an invalid name entry, drop it. */ + if (unlikely(rc > 0)) { + lfsck_object_put(env, parent); + rc = lfsck_namespace_shrink_linkea(env, com, child, + &ldata, cname, pfid, true); + if (rc < 0) + GOTO(out, rc); + + if (rc > 0) + repaired = true; + + continue; + } + /* Add the missing name entry back to the namespace. */ rc = lfsck_namespace_insert_normal(env, com, parent, child, cname->ln_name); @@ -3421,6 +3572,16 @@ static void lfsck_namespace_dump_statistics(struct seq_file *m, "local_lost_found_moved: "LPU64"\n" "local_lost_found_skipped: "LPU64"\n" "local_lost_found_failed: "LPU64"\n" + "striped_dirs_scanned: "LPU64"\n" + "striped_dirs_repaired: "LPU64"\n" + "striped_dirs_failed: "LPU64"\n" + "striped_dirs_disabled: "LPU64"\n" + "striped_dirs_skipped: "LPU64"\n" + "striped_shards_scanned: "LPU64"\n" + "striped_shards_repaired: "LPU64"\n" + "striped_shards_failed: "LPU64"\n" + "striped_shards_skipped: "LPU64"\n" + "name_hash_repaired: "LPU64"\n" "success_count: %u\n" "run_time_phase1: %u seconds\n" "run_time_phase2: %u seconds\n", @@ -3446,6 +3607,16 @@ static void lfsck_namespace_dump_statistics(struct seq_file *m, ns->ln_local_lpf_moved, ns->ln_local_lpf_skipped, ns->ln_local_lpf_failed, + ns->ln_striped_dirs_scanned, + ns->ln_striped_dirs_repaired, + ns->ln_striped_dirs_failed, + ns->ln_striped_dirs_disabled, + ns->ln_striped_dirs_skipped, + ns->ln_striped_shards_scanned, + ns->ln_striped_shards_repaired, + ns->ln_striped_shards_failed, + ns->ln_striped_shards_skipped, + ns->ln_name_hash_repaired, ns->ln_success_count, time_phase1, time_phase2); @@ -3535,6 +3706,90 @@ lfsck_namespace_fail(const struct lu_env *env, struct lfsck_component *com, up_write(&com->lc_sem); } +static void lfsck_namespace_close_dir(const struct lu_env *env, + struct lfsck_component *com) +{ + struct lfsck_namespace *ns = com->lc_file_ram; + struct lfsck_assistant_data *lad = com->lc_data; + struct lfsck_instance *lfsck = com->lc_lfsck; + struct lfsck_lmv *llmv = lfsck->li_lmv; + struct lfsck_namespace_req *lnr; + __u32 size = + sizeof(*lnr) + LFSCK_TMPBUF_LEN; + bool wakeup = false; + ENTRY; + + if (llmv == NULL) + RETURN_EXIT; + + OBD_ALLOC(lnr, size); + if (lnr == NULL) { + 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_obj = lfsck_object_get(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; + + spin_lock(&lad->lad_lock); + if (lad->lad_assistant_status < 0) { + spin_unlock(&lad->lad_lock); + lfsck_namespace_assistant_req_fini(env, &lnr->lnr_lar); + ns->ln_striped_dirs_skipped++; + + RETURN_EXIT; + } + + list_add_tail(&lnr->lnr_lar.lar_list, &lad->lad_req_list); + if (lad->lad_prefetched == 0) + wakeup = true; + + lad->lad_prefetched++; + spin_unlock(&lad->lad_lock); + if (wakeup) + wake_up_all(&lad->lad_thread.t_ctl_waitq); + + EXIT; +} + +static int lfsck_namespace_open_dir(const struct lu_env *env, + struct lfsck_component *com) +{ + struct lfsck_instance *lfsck = com->lc_lfsck; + struct lfsck_namespace *ns = com->lc_file_ram; + struct lfsck_lmv *llmv = lfsck->li_lmv; + int rc = 0; + ENTRY; + + if (llmv == NULL) + RETURN(0); + + if (llmv->ll_lmv_master) { + struct lmv_mds_md_v1 *lmv = &llmv->ll_lmv; + + if (lmv->lmv_master_mdt_index != + lfsck_dev_idx(lfsck->li_bottom)) { + lmv->lmv_master_mdt_index = + lfsck_dev_idx(lfsck->li_bottom); + ns->ln_flags |= LF_INCONSISTENT; + llmv->ll_lmv_updated = 1; + } + } else { + rc = lfsck_namespace_verify_stripe_slave(env, com, + lfsck->li_obj_dir, llmv); + } + + RETURN(rc > 0 ? 0 : rc); +} + static int lfsck_namespace_checkpoint(const struct lu_env *env, struct lfsck_component *com, bool init) { @@ -3631,6 +3886,16 @@ static int lfsck_namespace_prep(const struct lu_env *env, ns->ln_mul_ref_repaired = 0; ns->ln_bad_type_repaired = 0; ns->ln_lost_dirent_repaired = 0; + ns->ln_striped_dirs_scanned = 0; + ns->ln_striped_dirs_repaired = 0; + ns->ln_striped_dirs_failed = 0; + ns->ln_striped_dirs_disabled = 0; + ns->ln_striped_dirs_skipped = 0; + ns->ln_striped_shards_scanned = 0; + ns->ln_striped_shards_repaired = 0; + ns->ln_striped_shards_failed = 0; + ns->ln_striped_shards_skipped = 0; + ns->ln_name_hash_repaired = 0; fid_zero(&ns->ln_fid_latest_scanned_phase2); if (list_empty(&com->lc_link_dir)) list_add_tail(&com->lc_link_dir, @@ -4150,6 +4415,7 @@ static int lfsck_namespace_in_notify(const struct lu_env *env, switch (lr->lr_event) { case LE_CREATE_ORPHAN: { struct dt_object *orphan = NULL; + struct lmv_mds_md_v1 *lmv; CDEBUG(D_LFSCK, "%s: namespace LFSCK handling notify from " "MDT %x to create orphan"DFID" with type %o\n", @@ -4163,8 +4429,20 @@ static int lfsck_namespace_in_notify(const struct lu_env *env, if (dt_object_exists(orphan)) GOTO(out_create, rc = -EEXIST); + if (lr->lr_stripe_count > 0) { + lmv = &lfsck_env_info(env)->lti_lmv; + memset(lmv, 0, sizeof(*lmv)); + lmv->lmv_hash_type = lr->lr_hash_type; + lmv->lmv_stripe_count = lr->lr_stripe_count; + lmv->lmv_layout_version = lr->lr_layout_version; + memcpy(lmv->lmv_pool_name, lr->lr_pool_name, + sizeof(lmv->lmv_pool_name)); + } else { + lmv = NULL; + } + rc = lfsck_namespace_create_orphan_local(env, com, orphan, - lr->lr_type); + lr->lr_type, lmv); GOTO(out_create, rc = (rc == 1) ? 0 : rc); @@ -4332,6 +4610,8 @@ static int lfsck_namespace_query(const struct lu_env *env, static struct lfsck_operations lfsck_namespace_ops = { .lfsck_reset = lfsck_namespace_reset, .lfsck_fail = lfsck_namespace_fail, + .lfsck_close_dir = lfsck_namespace_close_dir, + .lfsck_open_dir = lfsck_namespace_open_dir, .lfsck_checkpoint = lfsck_namespace_checkpoint, .lfsck_prep = lfsck_namespace_prep, .lfsck_exec_oit = lfsck_namespace_exec_oit, @@ -4379,11 +4659,13 @@ int lfsck_namespace_repair_dangling(const struct lu_env *env, struct dt_allocation_hint *hint = &info->lti_hint; struct dt_object_format *dof = &info->lti_dof; struct dt_insert_rec *rec = &info->lti_dt_rec; + struct lmv_mds_md_v1 *lmv2 = &info->lti_lmv2; struct dt_object *parent = lnr->lnr_obj; const struct lu_name *cname; struct linkea_data ldata = { 0 }; struct lustre_handle lh = { 0 }; struct lu_buf linkea_buf; + struct lu_buf lmv_buf; struct lfsck_instance *lfsck = com->lc_lfsck; struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram; struct dt_device *dev = lfsck_obj2dt_dev(child); @@ -4471,9 +4753,31 @@ int lfsck_namespace_repair_dangling(const struct lu_env *env, rc = dt_declare_ref_add(env, child, th); if (rc != 0) GOTO(stop, rc); + + /* 5a. generate slave LMV EA. */ + if (lnr->lnr_lmv != NULL && lnr->lnr_lmv->ll_lmv_master) { + int idx; + + idx = lfsck_shard_name_to_index(env, + lnr->lnr_name, lnr->lnr_namelen, + type, lfsck_dto2fid(child)); + if (unlikely(idx < 0)) + GOTO(stop, rc = idx); + + *lmv2 = lnr->lnr_lmv->ll_lmv; + lmv2->lmv_magic = LMV_MAGIC_STRIPE; + lmv2->lmv_master_mdt_index = idx; + + lfsck_lmv_header_cpu_to_le(lmv2, lmv2); + lfsck_buf_init(&lmv_buf, lmv2, sizeof(*lmv2)); + rc = dt_declare_xattr_set(env, child, &lmv_buf, + XATTR_NAME_LMV, 0, th); + if (rc != 0) + GOTO(stop, rc); + } } - /* 5a. insert linkEA for child */ + /* 6a. insert linkEA for child */ lfsck_buf_init(&linkea_buf, ldata.ld_buf->lb_buf, ldata.ld_leh->leh_len); rc = dt_declare_xattr_set(env, child, &linkea_buf, @@ -4515,9 +4819,17 @@ int lfsck_namespace_repair_dangling(const struct lu_env *env, rc = dt_ref_add(env, child, th); if (rc != 0) GOTO(unlock, rc); + + /* 5b. generate slave LMV EA. */ + if (lnr->lnr_lmv != NULL && lnr->lnr_lmv->ll_lmv_master) { + rc = dt_xattr_set(env, child, &lmv_buf, XATTR_NAME_LMV, + 0, th, BYPASS_CAPA); + if (rc != 0) + GOTO(unlock, rc); + } } - /* 5b. insert linkEA for child. */ + /* 6b. insert linkEA for child. */ rc = dt_xattr_set(env, child, &linkea_buf, XATTR_NAME_LINK, 0, th, BYPASS_CAPA); @@ -4572,6 +4884,7 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env, bool remove; bool newdata; bool log = false; + bool bad_hash = false; int idx = 0; int count = 0; int rc; @@ -4598,6 +4911,12 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env, GOTO(out, rc); } + if (unlikely(lnr->lnr_dir_cookie == MDS_DIR_END_OFF)) { + rc = lfsck_namespace_striped_dir_rescan(env, com, lnr); + + RETURN(rc); + } + if (lnr->lnr_name[0] == '.' && (lnr->lnr_namelen == 1 || fid_seq_is_dot(fid_seq(&lnr->lnr_fid)))) GOTO(out, rc = 0); @@ -4647,6 +4966,13 @@ static int lfsck_namespace_assistant_handler_p1(const struct lu_env *env, dangling: 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, + lnr->lnr_name, lnr->lnr_namelen)) { + type = LNIT_BAD_DIRENT; + + GOTO(out, rc); + } + type = LNIT_DANGLING; rc = lfsck_namespace_repair_dangling(env, com, obj, lnr); @@ -4717,6 +5043,16 @@ again: 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)) { + type = LNIT_BAD_DIRENT; + + GOTO(stop, rc = 0); + } + /* If the file type stored in the name entry does not match * the file type claimed by the object, and the object does * not recognize the name entry, then it is quite possible @@ -4871,6 +5207,19 @@ stop: out: lfsck_ibits_unlock(&lh, LCK_EX); + if (!name_is_dot_or_dotdot(lnr->lnr_name, lnr->lnr_namelen) && + !lfsck_is_valid_slave_name_entry(env, lnr->lnr_lmv, + lnr->lnr_name, lnr->lnr_namelen) && + type != LNIT_BAD_DIRENT) { + ns->ln_flags |= LF_INCONSISTENT; + + log = false; + rc = lfsck_namespace_repair_bad_name_hash(env, com, dir, + lnr->lnr_lmv, lnr->lnr_name); + if (rc >= 0) + bad_hash = true; + } + if (rc >= 0) { switch (type) { case LNIT_BAD_TYPE: @@ -4948,6 +5297,21 @@ out: false); } + if (bad_hash) { + ns->ln_name_hash_repaired++; + + /* Not count repeatedly. */ + if (!repaired) + ns->ln_items_repaired++; + + if (bk->lb_param & LPF_DRYRUN && + lfsck_pos_is_zero(&ns->ln_pos_first_inconsistent)) + lfsck_pos_fill(env, lfsck, + &ns->ln_pos_first_inconsistent, + false); + } + + rc = 0; } up_write(&com->lc_sem); @@ -5203,9 +5567,7 @@ static void lfsck_namespace_scan_local_lpf(const struct lu_env *env, } /* skip dot and dotdot entries */ - if (ent->lde_name[0] == '.' && - (ent->lde_namelen == 1 || - (ent->lde_namelen == 2 && ent->lde_name[1] == '.'))) + if (name_is_dot_or_dotdot(ent->lde_name, ent->lde_namelen)) goto next; if (!fid_seq_in_fldb(fid_seq(&ent->lde_fid))) @@ -5350,7 +5712,7 @@ static int lfsck_namespace_assistant_handler_p2(const struct lu_env *env, goto checkpoint; } - target = lfsck_object_find(env, lfsck, &fid); + target = lfsck_object_find_by_dev(env, lfsck->li_bottom, &fid); if (IS_ERR(target)) { rc = PTR_ERR(target); goto checkpoint;