+
+ idc = osd_idc_find(env, osd, fid);
+ if (idc && !idc->oic_remote && idc->oic_dnode != ZFS_NO_OBJECT) {
+ oid = idc->oic_dnode;
+ goto zget;
+ }
+
+ rc = -ENOENT;
+ if (!list_empty(&osd->od_scrub.os_inconsistent_items))
+ rc = osd_oii_lookup(osd, fid, &oid);
+
+ if (rc)
+ rc = osd_fid_lookup(env, osd, fid, &oid);
+
+ if (rc == -ENOENT) {
+ if (likely(!(fid_is_norm(fid) || fid_is_igif(fid)) ||
+ fid_is_on_ost(env, osd, fid) ||
+ !zfs_test_bit(osd_oi_fid2idx(osd, fid),
+ scrub->os_file.sf_oi_bitmap)))
+ GOTO(out, rc = 0);
+
+ rc = -EREMCHG;
+ goto trigger;
+ }
+
+ if (rc)
+ GOTO(out, rc);
+
+zget:
+ LASSERT(obj->oo_dn == NULL);
+
+ rc = __osd_obj2dnode(osd->od_os, oid, &obj->oo_dn);
+ /* EEXIST will be returned if object is being deleted in ZFS */
+ if (rc == -EEXIST)
+ GOTO(out, rc = 0);
+
+ if (rc) {
+ CERROR("%s: lookup "DFID"/%#llx failed: rc = %d\n",
+ osd->od_svname, PFID(lu_object_fid(l)), oid, rc);
+ GOTO(out, rc);
+ }
+
+ rc = osd_object_init0(env, obj);
+ if (rc)
+ GOTO(out, rc);
+
+ if (unlikely(obj->oo_header))
+ GOTO(out, rc = 0);
+
+ rc = osd_check_lma(env, obj);
+ if ((!rc && !remote) || (rc != -EREMCHG))
+ GOTO(out, rc);
+
+trigger:
+ /* We still have chance to get the valid dnode: for the object that is
+ * referenced by remote name entry, the object on the local MDT will be
+ * linked under the dir /REMOTE_PARENT_DIR with its FID string as name.
+ *
+ * During the OI scrub, if we cannot find the OI mapping, we may still
+ * have change to map the FID to local OID via lookup the dir
+ * /REMOTE_PARENT_DIR. */
+ if (!remote && !fid_is_on_ost(env, osd, fid)) {
+ osd_fid2str(name, fid, sizeof(info->oti_str));
+ rc = osd_zap_lookup(osd, osd->od_remote_parent_dir,
+ NULL, name, 8, 3, (void *)zde);
+ if (!rc) {
+ oid = zde->lzd_reg.zde_dnode;
+ osd_dnode_rele(obj->oo_dn);
+ obj->oo_dn = NULL;
+ remote = true;
+ goto zget;
+ }
+ }
+
+ /* The case someone triggered the OI scrub already. */
+ if (thread_is_running(&scrub->os_thread)) {
+ if (!rc) {
+ LASSERT(remote);
+
+ lu_object_set_agent_entry(l);
+ osd_oii_insert(env, osd, fid, oid, false);
+ } else {
+ rc = -EINPROGRESS;
+ }
+
+ GOTO(out, rc);
+ }
+
+ /* The case NOT allow to trigger OI scrub automatically. */
+ if (osd->od_auto_scrub_interval == AS_NEVER)
+ GOTO(out, rc);
+
+ /* It is me to trigger the OI scrub. */
+ rc1 = osd_scrub_start(env, osd, SS_CLEAR_DRYRUN |
+ SS_CLEAR_FAILOUT | SS_AUTO_FULL);
+ LCONSOLE_WARN("%s: trigger OI scrub by RPC for the "DFID": rc = %d\n",
+ osd_name(osd), PFID(fid), rc1);
+ if (!rc) {
+ LASSERT(remote);
+
+ lu_object_set_agent_entry(l);
+ if (!rc1)
+ osd_oii_insert(env, osd, fid, oid, false);
+ } else {
+ if (!rc1)
+ rc = -EINPROGRESS;
+ else
+ rc = -EREMCHG;
+ }
+
+ GOTO(out, rc);
+