Whamcloud - gitweb
LU-15502 llite: set default LMV hash type with 2.12 MDS
authorLai Siyao <lai.siyao@whamcloud.com>
Sat, 29 Jan 2022 05:14:40 +0000 (00:14 -0500)
committerAndreas Dilger <adilger@whamcloud.com>
Tue, 1 Feb 2022 08:25:48 +0000 (08:25 +0000)
If default LMV hash type is CRUSH, or unset, it should be converted
to fnv_16_64, because 2.12 MDS doesn't understand this.

Fix LMV_HASH_FLAG_KNOWN to match actual known flags.

Lustre-change: https://review.whamcloud.com/46378/
Lustre-commit: TBD (from 420337ba103433cc194822aec0da3516638ade6b)

Test-Parameters: testlist=sanity env=ONLY=300 mdtcount=2 serverversion=2.12.6-ddn42
Fixes: 0a1cf8da8069 ("LU-11025 dne: introduce new directory hash type: "crush")
Fixes: bb60caa1c6e7 ("LU-14459 lmv: change default hash type to crush")
Signed-off-by: Lai Siyao <lai.siyao@whamcloud.com>
Change-Id: Ie2ad5a456040dcd01bc2c5ab96db52bf944abbd2
Reviewed-on: https://review.whamcloud.com/46381
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/dir.c

index ab5796b..5d6fa40 100644 (file)
@@ -1055,7 +1055,7 @@ static inline bool lmv_is_known_hash_type(__u32 type)
 #define LMV_HASH_FLAG_LAYOUT_CHANGE    \
        (LMV_HASH_FLAG_MIGRATION | LMV_HASH_FLAG_SPLIT | LMV_HASH_FLAG_MERGE)
 
-#define LMV_HASH_FLAG_KNOWN            0xfe000000
+#define LMV_HASH_FLAG_KNOWN            0xbe000000
 
 /* both SPLIT and MIGRATION are set for directory split */
 static inline bool lmv_hash_is_splitting(__u32 hash)
index 4cec91f..19fcb1e 100644 (file)
@@ -420,9 +420,10 @@ static int ll_dir_setdirstripe(struct dentry *dparent, struct lmv_user_md *lump,
                },
        };
        bool encrypt = false;
+       int hash_flags;
        int err;
-       ENTRY;
 
+       ENTRY;
        if (unlikely(!lmv_user_magic_supported(lump->lum_magic)))
                RETURN(-EINVAL);
 
@@ -448,25 +449,23 @@ static int ll_dir_setdirstripe(struct dentry *dparent, struct lmv_user_md *lump,
            !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);
 
@@ -582,12 +581,29 @@ int ll_dir_setstripe(struct inode *inode, struct lov_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;