- struct dt_device *dev = &osd->od_dt_dev;
- struct osd_oi **oi;
- int rc;
-
- OBD_ALLOC(oi, sizeof(*oi) * OSD_OI_FID_NR_MAX);
- if (oi == NULL)
- return -ENOMEM;
-
- cfs_mutex_lock(&oi_init_lock);
- /* try to open existing multiple OIs first */
- rc = osd_oi_table_open(info, osd, oi, 0, false);
- if (rc != 0)
- goto out;
-
- /* 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 */
- rc = 1;
- goto out;
- } else if (rc != -ENOENT) {
- CERROR("%s: can't open %s: rc = %d\n",
- dev->dd_lu_dev.ld_obd->obd_name, OSD_OI_NAME_BASE, rc);
- goto out;
- }
+ struct osd_scrub *scrub = &osd->od_scrub;
+ struct scrub_file *sf = &scrub->os_file;
+ struct osd_oi **oi;
+ int rc;
+ ENTRY;
+
+ OBD_ALLOC(oi, sizeof(*oi) * OSD_OI_FID_NR_MAX);
+ if (oi == NULL)
+ RETURN(-ENOMEM);
+
+ mutex_lock(&oi_init_lock);
+ /* try to open existing multiple OIs first */
+ rc = osd_oi_table_open(info, osd, oi, sf->sf_oi_count, false);
+ if (rc < 0)
+ GOTO(out, rc);
+
+ if (rc > 0) {
+ if (rc == sf->sf_oi_count || sf->sf_oi_count == 0)
+ GOTO(out, rc);
+
+ osd_scrub_file_reset(scrub,
+ LDISKFS_SB(osd_sb(osd))->s_es->s_uuid,
+ SF_RECREATED);
+ osd_oi_count = sf->sf_oi_count;
+ goto create;
+ }
+
+ /* 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 */
+ ldiskfs_clear_bit(0, sf->sf_oi_bitmap);
+ 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. Fortunately, the osd_fid_lookup()can
+ * verify the inode to decrease the risk. */
+ 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",
+ LDISKFS_SB(osd_sb(osd))->s_es->s_volume_name,
+ OSD_OI_NAME_BASE, rc);
+ GOTO(out, rc);
+ }
+
+ if (sf->sf_oi_count > 0) {
+ int i;
+
+ memset(sf->sf_oi_bitmap, 0, SCRUB_OI_BITMAP_SIZE);
+ for (i = 0; i < osd_oi_count; i++)
+ ldiskfs_set_bit(i, sf->sf_oi_bitmap);
+ osd_scrub_file_reset(scrub,
+ LDISKFS_SB(osd_sb(osd))->s_es->s_uuid,
+ SF_RECREATED);
+ }
+ sf->sf_oi_count = osd_oi_count;
+
+create:
+ rc = osd_scrub_file_store(scrub);
+ if (rc < 0) {
+ osd_oi_table_put(info, oi, sf->sf_oi_count);
+ GOTO(out, rc);
+ }
+
+ /* No OIs exist, new filesystem, create OI objects */
+ rc = osd_oi_table_open(info, osd, oi, osd_oi_count, true);
+ LASSERT(ergo(rc >= 0, rc == osd_oi_count));
+
+ GOTO(out, rc);