},
};
bool encrypt = false;
+ int hash_flags;
int err;
- ENTRY;
+ ENTRY;
if (unlikely(!lmv_user_magic_supported(lump->lum_magic)))
RETURN(-EINVAL);
!OBD_FAIL_CHECK(OBD_FAIL_LLITE_NO_CHECK_DEAD))
RETURN(-ENOENT);
+ /* MDS < 2.14 doesn't support 'crush' hash type, and cannot handle
+ * unknown hash if client doesn't set a valid one. switch to fnv_1a_64.
+ */
if (!(exp_connect_flags2(sbi->ll_md_exp) & OBD_CONNECT2_CRUSH)) {
- if ((lump->lum_hash_type & LMV_HASH_TYPE_MASK) ==
- LMV_HASH_TYPE_CRUSH) {
- /* if server doesn't support 'crush' hash type,
- * switch to fnv_1a_64.
- */
- lump->lum_hash_type &= ~LMV_HASH_TYPE_MASK;
- lump->lum_hash_type |= LMV_HASH_TYPE_FNV_1A_64;
- } else if ((lump->lum_hash_type & LMV_HASH_TYPE_MASK) ==
- LMV_HASH_TYPE_UNKNOWN) {
- /* from 2.14 MDT will choose default hash type if client
- * doesn't set a valid one, while old server doesn't
- * handle it.
- */
- lump->lum_hash_type &= ~LMV_HASH_TYPE_MASK;
- lump->lum_hash_type |= LMV_HASH_TYPE_DEFAULT;
- }
+ enum lmv_hash_type type = lump->lum_hash_type &
+ LMV_HASH_TYPE_MASK;
+
+ if (type >= LMV_HASH_TYPE_CRUSH ||
+ type == LMV_HASH_TYPE_UNKNOWN)
+ lump->lum_hash_type = (lump->lum_hash_type ^ type) |
+ LMV_HASH_TYPE_FNV_1A_64;
}
+ hash_flags = lump->lum_hash_type & ~LMV_HASH_TYPE_MASK;
+ if (hash_flags & ~LMV_HASH_FLAG_KNOWN)
+ RETURN(-EINVAL);
+
if (unlikely(!lmv_user_magic_supported(cpu_to_le32(lump->lum_magic))))
lustre_swab_lmv_user_md(lump);
case LOV_USER_MAGIC_COMP_V1:
lum_size = ((struct lov_comp_md_v1 *)lump)->lcm_size;
break;
- case LMV_USER_MAGIC:
- if (lump->lmm_magic != cpu_to_le32(LMV_USER_MAGIC))
- lustre_swab_lmv_user_md(
- (struct lmv_user_md *)lump);
- lum_size = sizeof(struct lmv_user_md);
+ case LMV_USER_MAGIC: {
+ struct lmv_user_md *lmv = (struct lmv_user_md *)lump;
+
+ /* MDS < 2.14 doesn't support 'crush' hash type, and
+ * cannot handle unknown hash if client doesn't set a
+ * valid one. switch to fnv_1a_64.
+ */
+ if (!(exp_connect_flags2(sbi->ll_md_exp) &
+ OBD_CONNECT2_CRUSH)) {
+ enum lmv_hash_type type = lmv->lum_hash_type &
+ LMV_HASH_TYPE_MASK;
+
+ if (type >= LMV_HASH_TYPE_CRUSH ||
+ type == LMV_HASH_TYPE_UNKNOWN)
+ lmv->lum_hash_type =
+ (lmv->lum_hash_type ^ type) |
+ LMV_HASH_TYPE_FNV_1A_64;
+ }
+ if (lmv->lum_magic != cpu_to_le32(LMV_USER_MAGIC))
+ lustre_swab_lmv_user_md(lmv);
+ lum_size = sizeof(*lmv);
break;
+ }
case LOV_USER_MAGIC_SPECIFIC: {
struct lov_user_md_v3 *v3 =
(struct lov_user_md_v3 *)lump;