+int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd,
+ const struct lu_fid *fid, const struct osd_inode_id *id,
+ handle_t *th, enum oi_check_flags flags)
+{
+ struct lu_fid *oi_fid = &info->oti_fid2;
+ struct osd_inode_id *oi_id = &info->oti_id2;
+ int rc = 0;
+
+ if (unlikely(fid_is_last_id(fid)))
+ return osd_obj_spec_insert(info, osd, fid, id, th);
+
+ if (fid_is_on_ost(info, osd, fid, flags) || fid_is_llog(fid))
+ return osd_obj_map_insert(info, osd, fid, id, th);
+
+ fid_cpu_to_be(oi_fid, fid);
+ osd_id_pack(oi_id, id);
+ rc = osd_oi_iam_refresh(info, osd_fid2oi(osd, fid),
+ (const struct dt_rec *)oi_id,
+ (const struct dt_key *)oi_fid, th, true);
+ if (rc != 0) {
+ struct inode *inode;
+ struct lustre_mdt_attrs *lma = &info->oti_mdt_attrs;
+
+ if (rc != -EEXIST)
+ return rc;
+
+ rc = osd_oi_lookup(info, osd, fid, oi_id, 0);
+ if (rc != 0)
+ return rc;
+
+ if (unlikely(osd_id_eq(id, oi_id)))
+ return 1;
+
+ /* Check whether the mapping for oi_id is valid or not. */
+ inode = osd_iget(info, osd, oi_id);
+ if (IS_ERR(inode)) {
+ rc = PTR_ERR(inode);
+ if (rc == -ENOENT || rc == -ESTALE)
+ goto update;
+ return rc;
+ }
+
+ /* The EA inode should NOT be in OI, old OI scrub may added
+ * such OI mapping by wrong, replace it. */
+ if (unlikely(osd_is_ea_inode(inode))) {
+ iput(inode);
+ goto update;
+ }
+
+ rc = osd_get_lma(info, inode, &info->oti_obj_dentry, lma);
+ iput(inode);
+ if (rc == -ENODATA)
+ goto update;
+
+ if (rc != 0)
+ return rc;
+
+ if (!(lma->lma_compat & LMAC_NOT_IN_OI) &&
+ lu_fid_eq(fid, &lma->lma_self_fid)) {
+ CERROR("%.16s: the FID "DFID" is used by two objects: "
+ "%u/%u %u/%u\n",
+ LDISKFS_SB(osd_sb(osd))->s_es->s_volume_name,
+ PFID(fid), oi_id->oii_ino, oi_id->oii_gen,
+ id->oii_ino, id->oii_gen);
+ return -EEXIST;
+ }
+
+update:
+ osd_id_pack(oi_id, id);
+ rc = osd_oi_iam_refresh(info, osd_fid2oi(osd, fid),
+ (const struct dt_rec *)oi_id,
+ (const struct dt_key *)oi_fid, th, false);
+ if (rc != 0)
+ return rc;
+ }
+
+ if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE))
+ rc = osd_obj_spec_insert(info, osd, fid, id, th);
+ return rc;