From: Lai Siyao Date: Sun, 23 Apr 2023 08:09:02 +0000 (-0400) Subject: LU-16717 mdt: treat unknown hash type as sane type X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=3b86cc112238e7c5c96edca604af29a1631bf277;p=fs%2Flustre-release.git LU-16717 mdt: treat unknown hash type as sane type 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 Change-Id: Ieffc0808d1db989d0bf9723f05cddb06f349e208 Reviewed-by: Andreas Dilger Reviewed-by: Hongchao Zhang Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/51202 Tested-by: jenkins Tested-by: Maloo --- diff --git a/lustre/include/lustre_lmv.h b/lustre/include/lustre_lmv.h index 7702831..e68c853 100644 --- a/lustre/include/lustre_lmv.h +++ b/lustre/include/lustre_lmv.h @@ -424,7 +424,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; @@ -446,7 +446,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; diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 7368b97..2065b14 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -693,6 +693,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 diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index 4ba65d3..572c8aa 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -1077,6 +1077,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) { diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 24fef33..c8af826 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -2339,6 +2339,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]; diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 4f615e3..b9b2aa1 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -20896,6 +20896,31 @@ test_230x() { } run_test 230x "dir migration check space" +test_230y() { + (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs" + (( MDS1_VERSION >= $(version_code 2.14.0.88) )) || + skip "Need MDS version at least 2.14.0.88" + + 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