+ /* The original LOVEA maybe re-generated via old filter_fid, at
+ * that time, we do not know the stripe count and stripe size. */
+ if (ol->ol_stripe_count > count)
+ count = ol->ol_stripe_count;
+ if (ol->ol_stripe_size != 0 &&
+ ol->ol_stripe_size != le32_to_cpu(lmm->lmm_stripe_size))
+ lmm->lmm_stripe_size = cpu_to_le32(ol->ol_stripe_size);
+
+ if (magic == LOV_MAGIC_V1)
+ objs = &lmm->lmm_objects[count];
+ else
+ objs = &((struct lov_mds_md_v3 *)lmm)->lmm_objects[count];
+
+ gap = ea_off - count;
+ if (gap >= 0)
+ count = ea_off + 1;
+
+ size = lov_mds_md_size(count, magic);
+ LASSERTF(buf->lb_len >= size,
+ "buffer len %d is less than real size %d\n",
+ (int)buf->lb_len, size);
+
+ if (gap > 0) {
+ memset(objs, 0, gap * sizeof(*objs));
+ lmm->lmm_pattern |= cpu_to_le32(LOV_PATTERN_F_HOLE);
+ }
+
+ lmm->lmm_layout_gen = cpu_to_le16(le16_to_cpu(lmm->lmm_layout_gen) + 1);
+ lmm->lmm_stripe_count = cpu_to_le16(count);
+ objs += gap;
+
+ rc = lfsck_layout_refill_lovea(env, lfsck, handle, parent, cfid, buf,
+ lmm, objs, LU_XATTR_REPLACE, ost_idx, size);
+
+ CDEBUG(D_LFSCK, "%s: layout LFSCK assistant extend layout EA for "
+ DFID": parent "DFID", OST-index %u, stripe-index %u, "
+ "stripe_size %u, stripe_count %u, comp_id %u, comp_start %llu, "
+ "comp_end %llu, %s LOV EA hole: rc = %d\n",
+ lfsck_lfsck2name(lfsck), PFID(cfid), PFID(lfsck_dto2fid(parent)),
+ ost_idx, ea_off, ol->ol_stripe_size, ol->ol_stripe_count,
+ ol->ol_comp_id, ol->ol_comp_start, ol->ol_comp_end,
+ le32_to_cpu(lmm->lmm_pattern) & LOV_PATTERN_F_HOLE ?
+ "with" : "without", rc);
+
+ RETURN(rc);
+}
+
+/**
+ * \retval +1: repaired
+ * \retval 0: did nothing
+ * \retval -ve: on error
+ */
+static int lfsck_layout_update_lovea(const struct lu_env *env,
+ struct lfsck_instance *lfsck,
+ struct thandle *handle,
+ struct lu_orphan_rec_v3 *rec,
+ struct dt_object *parent,
+ const struct lu_fid *cfid,
+ struct lu_buf *buf, int fl,
+ __u32 ost_idx, __u32 ea_off)
+{
+ struct ost_layout *ol = &rec->lor_layout;
+ struct lov_mds_md_v1 *lmm = NULL;
+ struct lov_ost_data_v1 *objs = NULL;
+ int rc = 0;
+ ENTRY;
+
+ if (ol->ol_comp_id != 0)
+ rc = lfsck_layout_new_comp_lovea(env, rec, parent, buf, ea_off,
+ &lmm, &objs);
+ else
+ rc = lfsck_layout_new_v1_lovea(env, lfsck, &rec->lor_layout,
+ parent, buf, ea_off, &lmm,
+ &objs);
+ if (rc > 0)
+ rc = lfsck_layout_refill_lovea(env, lfsck, handle, parent, cfid,
+ buf, lmm, objs, fl, ost_idx, rc);
+
+ CDEBUG(D_LFSCK, "%s: layout LFSCK assistant created layout EA for "
+ DFID": parent "DFID", OST-index %u, stripe-index %u, "
+ "stripe_size %u, stripe_count %u, comp_id %u, comp_start %llu, "
+ "comp_end %llu, layout version %u, range %u, fl %d, "
+ "%s LOV EA hole: rc = %d\n",
+ lfsck_lfsck2name(lfsck), PFID(cfid), PFID(lfsck_dto2fid(parent)),
+ ost_idx, ea_off, ol->ol_stripe_size, ol->ol_stripe_count,
+ ol->ol_comp_id, ol->ol_comp_start, ol->ol_comp_end,
+ rec->lor_layout_version, rec->lor_range, fl,
+ le32_to_cpu(lmm->lmm_pattern) & LOV_PATTERN_F_HOLE ?
+ "with" : "without", rc);
+
+ RETURN(rc);
+}
+
+static int __lfsck_layout_update_pfid(const struct lu_env *env,
+ struct dt_object *child,
+ const struct lu_fid *pfid,
+ const struct ost_layout *ol, __u32 offset,
+ __u32 version, __u32 range)
+{
+ struct dt_device *dev = lfsck_obj2dev(child);
+ struct filter_fid *ff = &lfsck_env_info(env)->lti_ff;
+ struct thandle *handle;
+ struct lu_buf buf = { NULL };
+ int rc;
+
+ ff->ff_parent.f_seq = cpu_to_le64(pfid->f_seq);
+ ff->ff_parent.f_oid = cpu_to_le32(pfid->f_oid);
+ /* Currently, the filter_fid::ff_parent::f_ver is not the real parent
+ * MDT-object's FID::f_ver, instead it is the OST-object index in its