+osd_scrub_convert_ff(struct osd_thread_info *info, struct osd_device *dev,
+ struct inode *inode, const struct lu_fid *fid)
+{
+ struct filter_fid_old *ff = &info->oti_ff;
+ struct dentry *dentry = &info->oti_obj_dentry;
+ handle_t *jh;
+ int size = 0;
+ int rc;
+ bool removed = false;
+ bool reset = true;
+ ENTRY;
+
+ /* We want the LMA to fit into the 256-byte OST inode, so operate
+ * as following:
+ * 1) read old XATTR_NAME_FID and save the parent FID;
+ * 2) delete the old XATTR_NAME_FID;
+ * 3) make new LMA and add it;
+ * 4) generate new XATTR_NAME_FID with the saved parent FID and add it.
+ *
+ * Making the LMA to fit into the 256-byte OST inode can save time for
+ * normal osd_check_lma() and for other OI scrub scanning in future.
+ * So it is worth to make some slow conversion here. */
+ jh = ldiskfs_journal_start_sb(osd_sb(dev),
+ osd_dto_credits_noquota[DTO_XATTR_SET] * 3);
+ if (IS_ERR(jh)) {
+ rc = PTR_ERR(jh);
+ CERROR("%s: fail to start trans for convert ff: "DFID
+ ": rc = %d\n",
+ osd_name(dev), PFID(fid), rc);
+ RETURN(rc);
+ }
+
+ /* 1) read old XATTR_NAME_FID and save the parent FID */
+ rc = __osd_xattr_get(inode, dentry, XATTR_NAME_FID, ff, sizeof(*ff));
+ if (rc == sizeof(*ff)) {
+ /* 2) delete the old XATTR_NAME_FID */
+ ll_vfs_dq_init(inode);
+ rc = inode->i_op->removexattr(dentry, XATTR_NAME_FID);
+ if (rc != 0)
+ GOTO(stop, rc);
+
+ removed = true;
+ } else if (unlikely(rc == -ENODATA)) {
+ reset = false;
+ } else if (rc != sizeof(struct filter_fid)) {
+ GOTO(stop, rc = -EINVAL);
+ }
+
+ /* 3) make new LMA and add it */
+ rc = osd_ea_fid_set(info, inode, fid, LMAC_FID_ON_OST, 0);
+ if (rc == 0 && reset)
+ size = sizeof(struct filter_fid);
+ else if (rc != 0 && removed)
+ /* If failed, we should try to add the old back. */
+ size = sizeof(struct filter_fid_old);
+
+ /* 4) generate new XATTR_NAME_FID with the saved parent FID and add it*/
+ if (size > 0) {
+ int rc1;
+
+ rc1 = __osd_xattr_set(info, inode, XATTR_NAME_FID, ff, size,
+ XATTR_CREATE);
+ if (rc1 != 0 && rc != 0)
+ rc = rc1;
+ }
+
+ GOTO(stop, rc);
+
+stop:
+ ldiskfs_journal_stop(jh);
+ return rc;
+}
+
+static int