+/**
+ * \retval SCRUB_NEXT_OSTOBJ_OLD: FID-on-OST
+ * \retval 0: FID-on-MDT
+ */
+static int osd_scrub_check_local_fldb(struct osd_thread_info *info,
+ struct osd_device *dev,
+ struct lu_fid *fid)
+{
+ /* XXX: The initial OI scrub will scan the top level /O to generate
+ * a small local FLDB according to the <seq>. If the given FID
+ * is in the local FLDB, then it is FID-on-OST; otherwise it's
+ * quite possible for FID-on-MDT. */
+ if (dev->od_is_ost)
+ return SCRUB_NEXT_OSTOBJ_OLD;
+ else
+ return 0;
+}
+
+static int osd_scrub_get_fid(struct osd_thread_info *info,
+ struct osd_device *dev, struct inode *inode,
+ struct lu_fid *fid, bool scrub)
+{
+ struct lustre_mdt_attrs *lma = &info->oti_mdt_attrs;
+ int rc;
+ bool has_lma = false;
+
+ rc = osd_get_lma(info, inode, &info->oti_obj_dentry, lma);
+ if (rc == 0) {
+ has_lma = true;
+ if (lma->lma_compat & LMAC_NOT_IN_OI ||
+ lma->lma_incompat & LMAI_AGENT)
+ return SCRUB_NEXT_CONTINUE;
+
+ *fid = lma->lma_self_fid;
+ if (!scrub)
+ return 0;
+
+ if (lma->lma_compat & LMAC_FID_ON_OST)
+ return SCRUB_NEXT_OSTOBJ;
+
+ if (fid_is_idif(fid))
+ return SCRUB_NEXT_OSTOBJ_OLD;
+
+ /* For local object. */
+ if (fid_is_internal(fid))
+ return 0;
+
+ /* For external visible MDT-object with non-normal FID. */
+ if (fid_is_namespace_visible(fid) && !fid_is_norm(fid))
+ return 0;
+
+ /* For the object with normal FID, it may be MDT-object,
+ * or may be 2.4 OST-object, need further distinguish.
+ * Fall through to next section. */
+ }
+
+ if (rc == -ENODATA || rc == 0) {
+ rc = osd_get_idif(info, inode, &info->oti_obj_dentry, fid);
+ if (rc == 0) {
+ if (scrub)
+ /* It is old 2.x (x <= 3) or 1.8 OST-object. */
+ rc = SCRUB_NEXT_OSTOBJ_OLD;
+ return rc;
+ }
+
+ if (rc > 0) {
+ if (!has_lma)
+ /* It is FID-on-OST, but we do not know how
+ * to generate its FID, ignore it directly. */
+ rc = SCRUB_NEXT_CONTINUE;
+ else
+ /* It is 2.4 OST-object. */
+ rc = SCRUB_NEXT_OSTOBJ_OLD;
+ return rc;
+ }
+
+ if (rc != -ENODATA)
+ return rc;
+
+ if (!has_lma) {
+ if (dev->od_scrub.os_convert_igif) {
+ lu_igif_build(fid, inode->i_ino,
+ inode->i_generation);
+ if (scrub)
+ rc = SCRUB_NEXT_NOLMA;
+ else
+ rc = 0;
+ } else {
+ /* It may be FID-on-OST, or may be FID for
+ * non-MDT0, anyway, we do not know how to
+ * generate its FID, ignore it directly. */
+ rc = SCRUB_NEXT_CONTINUE;
+ }
+ return rc;
+ }
+
+ /* For OI scrub case only: the object has LMA but has no ff
+ * (or ff crashed). It may be MDT-object, may be OST-object
+ * with crashed ff. The last check is local FLDB. */
+ rc = osd_scrub_check_local_fldb(info, dev, fid);
+ }
+
+ return rc;
+}
+