+ *stripe_count = le32_to_cpu(lmm->lmm_stripe_count);
+
+ if (*stripe_count == 0) {
+ CERROR("bad stripe count %d\n", *stripe_count);
+ lov_dump_lmm_v1(D_WARNING, lmm);
+ return -EINVAL;
+ }
+
+ if (lmm_bytes < lov_mds_md_v1_size(*stripe_count)) {
+ CERROR("LOV EA too small: %d, need %d\n",
+ lmm_bytes, lov_mds_md_v1_size(*stripe_count));
+ lov_dump_lmm_v1(D_WARNING, lmm);
+ return -EINVAL;
+ }
+
+ if (lmm->lmm_object_id == 0) {
+ CERROR("zero object id\n");
+ lov_dump_lmm_v1(D_WARNING, lmm);
+ return -EINVAL;
+ }
+
+ if (lmm->lmm_pattern != cpu_to_le32(LOV_PATTERN_RAID0)) {
+ CERROR("bad striping pattern\n");
+ lov_dump_lmm_v1(D_WARNING, lmm);
+ return -EINVAL;
+ }
+
+ if (lmm->lmm_stripe_size == 0 ||
+ (__u64)le32_to_cpu(lmm->lmm_stripe_size) * *stripe_count > ~0UL) {
+ CERROR("bad stripe size %u\n",
+ le32_to_cpu(lmm->lmm_stripe_size));
+ lov_dump_lmm_v1(D_WARNING, lmm);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int lov_verify_lmm(void *lmm, int lmm_bytes, int *stripe_count)
+{
+ switch (le32_to_cpu(*(__u32 *)lmm)) {
+ case LOV_MAGIC_V1:
+ return lov_verify_lmm_v1(lmm, lmm_bytes, stripe_count);
+ case LOV_MAGIC_V0:
+ return lov_verify_lmm_v0(lmm, lmm_bytes, stripe_count);
+ default:
+ CERROR("bad disk LOV MAGIC: 0x%08X\n",
+ le32_to_cpu(*(__u32 *)lmm));
+ return -EINVAL;
+ }
+}
+
+int lov_alloc_memmd(struct lov_stripe_md **lsmp, int stripe_count, int pattern)
+{
+ int lsm_size = lov_stripe_md_size(stripe_count);
+ struct lov_oinfo *loi;
+ int i;
+
+ OBD_ALLOC(*lsmp, lsm_size);
+ if (!*lsmp)
+ return -ENOMEM;
+
+ (*lsmp)->lsm_magic = LOV_MAGIC;
+ (*lsmp)->lsm_stripe_count = stripe_count;
+ (*lsmp)->lsm_maxbytes = LUSTRE_STRIPE_MAXBYTES * stripe_count;
+ (*lsmp)->lsm_xfersize = PTLRPC_MAX_BRW_SIZE * stripe_count;
+ (*lsmp)->lsm_pattern = pattern;
+ (*lsmp)->lsm_oinfo[0].loi_ost_idx = ~0;
+
+ for (i = 0, loi = (*lsmp)->lsm_oinfo; i < stripe_count; i++, loi++)
+ loi_init(loi);
+
+ return lsm_size;
+}
+
+void lov_free_memmd(struct lov_stripe_md **lsmp)
+{
+ OBD_FREE(*lsmp, lov_stripe_md_size((*lsmp)->lsm_stripe_count));
+ *lsmp = NULL;
+}
+
+int lov_unpackmd_v0(struct lov_obd *lov, struct lov_stripe_md *lsm,
+ struct lov_mds_md_v0 *lmm)
+{
+ struct lov_oinfo *loi;
+ int i, ost_offset, ost_count;
+
+ lsm->lsm_object_id = le64_to_cpu(lmm->lmm_object_id);
+ /* lsm->lsm_object_gr = 0; implicit */
+ lsm->lsm_stripe_size = le32_to_cpu(lmm->lmm_stripe_size);
+ lsm->lsm_xfersize = lsm->lsm_stripe_size * lsm->lsm_stripe_count;
+ lsm->lsm_pattern = LOV_PATTERN_RAID0;
+ ost_offset = le32_to_cpu(lmm->lmm_stripe_offset);
+ ost_count = le16_to_cpu(lmm->lmm_ost_count);