Whamcloud - gitweb
LU-16717 mdt: treat unknown hash type as sane type 96/50796/5
authorLai Siyao <lai.siyao@whamcloud.com>
Sun, 23 Apr 2023 08:09:02 +0000 (04:09 -0400)
committerOleg Drokin <green@whamcloud.com>
Wed, 31 May 2023 19:01:37 +0000 (19:01 +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.

Signed-off-by: Lai Siyao <lai.siyao@whamcloud.com>
Change-Id: Ieffc0808d1db989d0bf9723f05cddb06f349e208
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50796
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Hongchao Zhang <hongchao@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 74d7937..f29dc50 100644 (file)
@@ -444,7 +444,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;
@@ -466,7 +466,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 1619780..6dd4c59 100644 (file)
@@ -699,6 +699,7 @@ extern char obd_jobid_var[];
 
 /* MIGRATE */
 #define OBD_FAIL_MIGRATE_ENTRIES               0x1801
+#define OBD_FAIL_MIGRATE_BAD_HASH              0x1802
 
 /* LMV */
 #define OBD_FAIL_LMV_UNKNOWN_STRIPE            0x1901
index 151dbf8..25a3642 100644 (file)
@@ -1106,6 +1106,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 7b85c00..67bf2f4 100644 (file)
@@ -2223,6 +2223,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);
+       }
+
        /* @spobj is the parent stripe of @sobj if @pobj is striped directory,
         * if @pobj is migrating too, tpobj is the target parent stripe.
         */
index 83383de..0e48b7e 100755 (executable)
@@ -21871,6 +21871,31 @@ test_230x() {
 }
 run_test 230x "dir migration check space"
 
+test_230y() {
+       (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
+       (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
+               skip "Need MDS version at least 2.15.55.45"
+
+       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