+ struct lfsck_thread_info *info = lfsck_env_info(env);
+ struct lfsck_namespace *ns = com->lc_file_ram;
+ struct lfsck_instance *lfsck = com->lc_lfsck;
+ const struct lu_fid *fid = lfsck_dto2fid(obj);
+ struct lu_attr *la = &info->lti_la;
+ struct lu_fid *pfid = &info->lti_fid2;
+ struct lu_name *cname = &info->lti_name;
+ struct lu_seq_range *range = &info->lti_range;
+ struct dt_device *dev = lfsck->li_bottom;
+ struct seq_server_site *ss =
+ lu_site2seq(dev->dd_lu_dev.ld_site);
+ struct linkea_data ldata = { 0 };
+ __u32 idx = lfsck_dev_idx(dev);
+ int rc;
+ ENTRY;
+
+ rc = lfsck_links_read(env, obj, &ldata);
+ if (rc == -ENOENT)
+ GOTO(out, rc = 0);
+
+ /* -EINVAL means crashed linkEA, should be verified. */
+ if (rc == -EINVAL) {
+ rc = lfsck_namespace_trace_update(env, com, fid,
+ LNTF_CHECK_LINKEA, true);
+ if (rc == 0) {
+ struct lustre_handle lh = { 0 };
+
+ rc = lfsck_ibits_lock(env, lfsck, obj, &lh,
+ MDS_INODELOCK_UPDATE |
+ MDS_INODELOCK_XATTR, LCK_EX);
+ if (rc == 0) {
+ rc = lfsck_namespace_links_remove(env, com,
+ obj);
+ lfsck_ibits_unlock(&lh, LCK_EX);
+ }
+ }
+
+ GOTO(out, rc = (rc == -ENOENT ? 0 : rc));
+ }
+
+ /* zero-linkEA object may be orphan, but it also maybe because
+ * of upgrading. Currently, we cannot record it for double scan.
+ * Because it may cause the LFSCK tracing file to be too large. */
+ if (rc == -ENODATA) {
+ if (S_ISDIR(lfsck_object_type(obj)))
+ GOTO(out, rc = 0);
+
+ rc = dt_attr_get(env, obj, la, BYPASS_CAPA);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ if (la->la_nlink > 1)
+ rc = lfsck_namespace_trace_update(env, com, fid,
+ LNTF_CHECK_LINKEA, true);
+
+ GOTO(out, rc);
+ }
+
+ if (rc != 0)
+ GOTO(out, rc);
+
+ /* Record multiple-linked object. */
+ if (ldata.ld_leh->leh_reccount > 1) {
+ rc = lfsck_namespace_trace_update(env, com, fid,
+ LNTF_CHECK_LINKEA, true);
+
+ GOTO(out, rc);
+ }
+
+ linkea_first_entry(&ldata);
+ linkea_entry_unpack(ldata.ld_lee, &ldata.ld_reclen, cname, pfid);
+ if (!fid_is_sane(pfid)) {
+ rc = lfsck_namespace_trace_update(env, com, fid,
+ LNTF_CHECK_PARENT, true);
+ } else {
+ fld_range_set_mdt(range);
+ rc = fld_local_lookup(env, ss->ss_server_fld,
+ fid_seq(pfid), range);
+ if ((rc == -ENOENT) ||
+ (rc == 0 && range->lsr_index != idx)) {
+ rc = lfsck_namespace_trace_update(env, com, fid,
+ LNTF_CHECK_LINKEA, true);
+ } else {
+ if (S_ISDIR(lfsck_object_type(obj)))
+ GOTO(out, rc = 0);
+
+ rc = dt_attr_get(env, obj, la, BYPASS_CAPA);
+ if (rc != 0)
+ GOTO(out, rc);
+
+ if (la->la_nlink > 1)
+ rc = lfsck_namespace_trace_update(env, com,
+ fid, LNTF_CHECK_LINKEA, true);
+ }
+ }
+
+ GOTO(out, rc);
+
+out: