if (OBD_FAIL_CHECK(OBD_FAIL_OST_ENOENT))
RETURN(-ENOENT);
+ /* Objects are created as locking anchors or place holders for objects
+ * yet to be created. No need to osd_oi_lookup() at here because FID
+ * shouldn't never be re-used, if it's really a duplicate FID from
+ * unexpected reason, we should be able to detect it later by calling
+ * do_create->osd_oi_insert()
+ */
+ if (conf != NULL && conf->loc_flags & LOC_F_NEW)
+ GOTO(out, result = 0);
+
/* Search order: 1. per-thread cache. */
if (lu_fid_eq(fid, &oic->oic_fid)) {
id = &oic->oic_lid;
goto iget;
}
- if (sf->sf_flags & SF_INCONSISTENT)
+ /* One corner case that if the OI_scrub file crashed or lost and we
+ * regard it as upgrade, then we allow IGIF lookup to bypass OI files.
+ *
+ * The risk is that osd_fid_lookup() may found a wrong inode with the
+ * given IGIF especially when the MDT has performed file-level backup
+ * and restored after former upgrading from 1.8 to 2.x.
+ *
+ * To decrease the risk, we force the osd_fid_lookup() to verify the
+ * inode for such case. */
+ if ((sf->sf_flags & SF_INCONSISTENT) ||
+ (!dev->od_igif_inoi && fid_is_igif(fid)))
verify = true;
- /*
- * Objects are created as locking anchors or place holders for objects
- * yet to be created. No need to osd_oi_lookup() at here because FID
- * shouldn't never be re-used, if it's really a duplicate FID from
- * unexpected reason, we should be able to detect it later by calling
- * do_create->osd_oi_insert()
- */
- if (conf != NULL && conf->loc_flags & LOC_F_NEW)
- GOTO(out, result = 0);
-
/* Search order: 3. OI files. */
result = osd_oi_lookup(info, dev, fid, id, true);
if (result == -ENOENT) {
if (result == -ENOENT || result == -ESTALE) {
if (!in_oi) {
fid_zero(&oic->oic_fid);
- GOTO(out, result = 0);
+ GOTO(out, result = -ENOENT);
}
/* XXX: There are three possible cases:
if (result == 0)
/* It is the case 1 or 2. */
goto trigger;
-
- if (result == -ENOENT)
- /* It is the case 3. */
- result = 0;
} else if (result == -EREMCHG) {
trigger:
/* if previous failed then try found single OI from old filesystem */
rc = osd_oi_open(info, osd, OSD_OI_NAME_BASE, &oi[0], false);
if (rc == 0) { /* found single OI from old filesystem */
+ if (sf->sf_success_count == 0)
+ /* XXX: There is one corner case that if the OI_scrub
+ * file crashed or lost and we regard it upgrade,
+ * then we allow IGIF lookup to bypass OI files.
+ *
+ * The risk is that osd_fid_lookup() may found
+ * a wrong inode with the given IGIF especially
+ * when the MDT has performed file-level backup
+ * and restored after former upgrading from 1.8
+ * to 2.x. To decrease the risk, we will force
+ * the osd_fid_lookup() to verify the inode for
+ * such case. */
+ osd_scrub_file_reset(scrub,
+ LDISKFS_SB(osd_sb(osd))->s_es->s_uuid,
+ SF_UPGRADE);
GOTO(out, rc = 1);
} else if (rc != -ENOENT) {
CERROR("%.16s: can't open %s: rc = %d\n",
LASSERT((rc & (rc - 1)) == 0);
osd->od_oi_table = oi;
osd->od_oi_count = rc;
- rc = 0;
+ if (sf->sf_oi_count != rc) {
+ sf->sf_oi_count = rc;
+ rc = osd_scrub_file_store(scrub);
+ if (rc < 0) {
+ osd_oi_table_put(info, oi, sf->sf_oi_count);
+ OBD_FREE(oi, sizeof(*oi) * OSD_OI_FID_NR_MAX);
+ }
+ } else {
+ rc = 0;
+ }
}
mutex_unlock(&oi_init_lock);