Whamcloud - gitweb
LU-16717 mdt: treat unknown hash type as sane type 35/51235/2
authorLai Siyao <lai.siyao@whamcloud.com>
Sun, 23 Apr 2023 08:09:02 +0000 (04:09 -0400)
committerOleg Drokin <green@whamcloud.com>
Wed, 2 Aug 2023 06:17:19 +0000 (06:17 +0000)
Directory migration failure may leave directory hash type as
LMV_HASH_TYPE_UNKNOWN|LMV_HASH_FLAG_BAD_TYPE, which should be treated
as sane hash type on existing directories, otherwise such directories
can't be unlinked.

Add sanity 230y.

Lustre-change: https://review.whamcloud.com/50796
Lustre-commit: 05cdb71ba6813570123613993f3cfcf74fc83561

Signed-off-by: Lai Siyao <lai.siyao@whamcloud.com>
Change-Id: Ieffc0808d1db989d0bf9723f05cddb06f349e208
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50796
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Hongchao Zhang <hongchao@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51235
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/lustre_lmv.h
lustre/include/obd_support.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/mdt/mdt_reint.c
lustre/tests/sanity.sh

index 2ffd77f..b848408 100644 (file)
@@ -438,7 +438,7 @@ static inline bool lmv_is_sane(const struct lmv_mds_md_v1 *lmv)
        if (le32_to_cpu(lmv->lmv_stripe_count) == 0)
                goto insane;
 
-       if (!lmv_is_known_hash_type(le32_to_cpu(lmv->lmv_hash_type)))
+       if (!lmv_is_sane_hash_type(le32_to_cpu(lmv->lmv_hash_type)))
                goto insane;
 
        return true;
@@ -460,7 +460,7 @@ static inline bool lmv_is_sane2(const struct lmv_mds_md_v1 *lmv)
        if (le32_to_cpu(lmv->lmv_stripe_count) == 0)
                goto insane;
 
-       if (!lmv_is_known_hash_type(le32_to_cpu(lmv->lmv_hash_type)))
+       if (!lmv_is_sane_hash_type(le32_to_cpu(lmv->lmv_hash_type)))
                goto insane;
 
        return true;
index cca40a6..5a69980 100644 (file)
@@ -681,6 +681,7 @@ extern char obd_jobid_var[];
 
 /* MIGRATE */
 #define OBD_FAIL_MIGRATE_ENTRIES               0x1801
+#define OBD_FAIL_MIGRATE_BAD_HASH              0x1802
 
 /* LMV */
 #define OBD_FAIL_UNKNOWN_LMV_STRIPE            0x1901
index b2ae599..25fa6ad 100644 (file)
@@ -1046,6 +1046,16 @@ static inline bool lmv_is_known_hash_type(__u32 type)
 
 #define LMV_HASH_FLAG_KNOWN            0xbe000000
 
+/* migration failure may leave hash type as
+ * LMV_HASH_TYPE_UNKNOWN|LMV_HASH_FLAG_BAD_TYPE, which should be treated as
+ * sane, so such directory can be accessed (resume migration or unlink).
+ */
+static inline bool lmv_is_sane_hash_type(__u32 type)
+{
+       return lmv_is_known_hash_type(type) ||
+              type == (LMV_HASH_TYPE_UNKNOWN | LMV_HASH_FLAG_BAD_TYPE);
+}
+
 /* both SPLIT and MIGRATION are set for directory split */
 static inline bool lmv_hash_is_splitting(__u32 hash)
 {
index c800ca6..a2ddbbc 100644 (file)
@@ -2312,6 +2312,24 @@ int mdt_reint_migrate(struct mdt_thread_info *info,
        if (rc)
                GOTO(put_parent, rc);
 
+       if (CFS_FAIL_CHECK(OBD_FAIL_MIGRATE_BAD_HASH) &&
+           (ma->ma_valid & MA_LMV) &&
+           lmv_is_migrating(&ma->ma_lmv->lmv_md_v1)) {
+               struct lu_buf *buf = &info->mti_buf;
+               struct lmv_mds_md_v1 *lmv = &ma->ma_lmv->lmv_md_v1;
+               __u32 version = le32_to_cpu(lmv->lmv_layout_version);
+
+               lmv->lmv_hash_type = cpu_to_le32(LMV_HASH_TYPE_UNKNOWN |
+                                                LMV_HASH_FLAG_BAD_TYPE);
+               lmv->lmv_layout_version = cpu_to_le32(version + 1);
+               buf->lb_buf = lmv;
+               buf->lb_len = sizeof(*lmv);
+               rc = mo_xattr_set(env, mdt_object_child(pobj), buf,
+                                 XATTR_NAME_LMV, LU_XATTR_REPLACE);
+               mo_invalidate(env, mdt_object_child(pobj));
+               GOTO(put_parent, rc);
+       }
+
 lock_parent:
        /* lock parent object */
        lhp = &info->mti_lh[MDT_LH_PARENT];
index d73b285..6cd539a 100755 (executable)
@@ -20636,6 +20636,31 @@ test_230w() {
 }
 run_test 230w "non-recursive mode dir migration"
 
+test_230y() {
+       (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
+       (( MDS1_VERSION >= $(version_code 2.15.3) )) ||
+               skip "Need MDS version at least 2.15.3"
+
+       local pid
+
+       test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
+       $LFS getdirstripe $DIR/$tdir
+       createmany -d $DIR/$tdir/d 100 || error "createmany failed"
+       $LFS migrate -m 1 -c 2 $DIR/$tdir &
+       pid=$!
+       sleep 1
+
+       #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
+       do_facet mds2 lctl set_param fail_loc=0x1802
+
+       wait $pid
+       do_facet mds2 lctl set_param fail_loc=0
+       $LFS getdirstripe $DIR/$tdir
+       unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
+       rmdir $DIR/$tdir || error "rmdir $tdir failed"
+}
+run_test 230y "unlink dir with bad hash type"
+
 test_231a()
 {
        # For simplicity this test assumes that max_pages_per_rpc