+ if (le32_to_cpu(lum->lmm_magic) == LOV_MAGIC_FOREIGN) {
+ struct lov_foreign_md *lfm;
+ struct lov_hsm_md *lhm;
+ u32 hsmsize;
+ u32 ftype;
+
+ /*
+ * Currently when the foreign layout is used as a basic
+ * layout component, it only supports HSM foreign types:
+ * LU_FOREIGN_TYPE_{POSIX, S3, PCCRW, PCCRO}.
+ */
+ lfm = (struct lov_foreign_md *)lum;
+ ftype = le32_to_cpu(lfm->lfm_type);
+ if (!lov_hsm_type_supported(ftype)) {
+ CDEBUG(D_LAYOUT,
+ "Foreign type %#x is not HSM\n", ftype);
+ RETURN(-EINVAL);
+ }
+
+ /* Current HSM component must cover [0, EOF]. */
+ if (le64_to_cpu(ext->e_start) > 0) {
+ CDEBUG(D_LAYOUT, "Invalid HSM component with %llu extent start\n",
+ le64_to_cpu(ext->e_start));
+ RETURN(-EINVAL);
+ }
+ if (le64_to_cpu(ext->e_end) != LUSTRE_EOF) {
+ CDEBUG(D_LAYOUT, "Invalid HSM component with %llu extent end\n",
+ le64_to_cpu(ext->e_end));
+ RETURN(-EINVAL);
+ }
+
+ lhm = (struct lov_hsm_md *)lfm;
+ if (le32_to_cpu(lhm->lhm_length) !=
+ sizeof(struct lov_hsm_base)) {
+ CDEBUG(D_LAYOUT,
+ "Invalid HSM component size %u != %u\n",
+ le32_to_cpu(ent->lcme_size), hsmsize);
+ RETURN(-EINVAL);
+ }
+
+ hsmsize = lov_foreign_size_le(lhm);
+ if (le32_to_cpu(ent->lcme_size) < hsmsize) {
+ CDEBUG(D_LAYOUT,
+ "Invalid HSM component size %u != %u\n",
+ le32_to_cpu(ent->lcme_size), hsmsize);
+ RETURN(-EINVAL);
+ }
+ if (le32_to_cpu(lhm->lhm_flags) & ~HSM_FLAGS_MASK ||
+ !(le32_to_cpu(lhm->lhm_flags) & HSM_FLAGS_MASK)) {
+ CDEBUG(D_LAYOUT,
+ "Invalid HSM component flags %#x\n",
+ le32_to_cpu(lhm->lhm_flags));
+ RETURN(-EINVAL);
+ }
+ continue;
+ }
+
+ /* Check DoM entry is always the first one */