From 05cdb71ba6813570123613993f3cfcf74fc83561 Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Sun, 23 Apr 2023 04:09:02 -0400 Subject: [PATCH] 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. Signed-off-by: Lai Siyao Change-Id: Ieffc0808d1db989d0bf9723f05cddb06f349e208 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50796 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Hongchao Zhang Reviewed-by: Oleg Drokin --- lustre/include/lustre_lmv.h | 4 ++-- lustre/include/obd_support.h | 1 + lustre/include/uapi/linux/lustre/lustre_user.h | 10 ++++++++++ lustre/mdt/mdt_reint.c | 18 ++++++++++++++++++ lustre/tests/sanity.sh | 25 +++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/lustre/include/lustre_lmv.h b/lustre/include/lustre_lmv.h index 74d79375..f29dc50 100644 --- a/lustre/include/lustre_lmv.h +++ b/lustre/include/lustre_lmv.h @@ -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; diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 1619780..6dd4c59 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -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 diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index 151dbf8..25a3642 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -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) { diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 7b85c00..67bf2f4 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -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. */ diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 83383de..0e48b7e 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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 -- 1.8.3.1