From: Lai Siyao Date: Mon, 12 Apr 2021 03:30:13 +0000 (+0800) Subject: LU-14459 mdt: restripe parent may be a stripe X-Git-Tag: 2.14.53~50 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=a84efc8607ae8057499a8800699f336e821b03d8 LU-14459 mdt: restripe parent may be a stripe mdt_restripe() check parent LMV sanity with lmv_is_sane(), but parent may be a stripe, use lmv_is_sane2() instead. Clear lmv_migrate_hash/offset in layout shrink/update, though it won't cause any issue, it's strange to see values set in debug logs. Add more race check between directory restripe, auto-split and migration. Signed-off-by: Lai Siyao Change-Id: I38950a07a8c9a8b4b20a2fd7aff229d27dbb403c Reviewed-on: https://review.whamcloud.com/43290 Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo Reviewed-by: Hongchao Zhang Reviewed-by: Oleg Drokin --- diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index 858831f..c1f4c32 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -8523,6 +8523,8 @@ static int lod_dir_layout_shrink(const struct lu_env *env, cpu_to_le32(LMV_HASH_TYPE_MASK); lmv->lmv_layout_version = cpu_to_le32(lo->ldo_dir_layout_version + 1); + lmv->lmv_migrate_offset = 0; + lmv->lmv_migrate_hash = 0; for (i = 0; i < lo->ldo_dir_stripe_count; i++) { dto = lo->ldo_stripe[i]; diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index f2952d2..78fcdbd 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -381,7 +381,7 @@ static int mdt_restripe(struct mdt_thread_info *info, if (ma->ma_valid & MA_LMV) { /* don't allow restripe if parent dir layout is changing */ lmv = &ma->ma_lmv->lmv_md_v1; - if (!lmv_is_sane(lmv)) + if (!lmv_is_sane2(lmv)) GOTO(unlock_parent, rc = -EBADF); if (lmv_is_layout_changing(lmv)) @@ -412,6 +412,18 @@ static int mdt_restripe(struct mdt_thread_info *info, GOTO(out_child, rc = -EREMOTE); } + if (!S_ISDIR(lu_object_attr(&child->mot_obj))) + GOTO(out_child, rc = -ENOTDIR); + + rc = mdt_stripe_get(info, child, ma, XATTR_NAME_LMV); + if (rc) + GOTO(out_child, rc); + + /* race with migrate? */ + if ((ma->ma_valid & MA_LMV) && + lmv_is_migrating(&ma->ma_lmv->lmv_md_v1)) + GOTO(out_child, rc = -EBUSY); + /* lock object */ lhc = &info->mti_lh[MDT_LH_CHILD]; mdt_lock_reg_init(lhc, LCK_EX); @@ -2265,6 +2277,15 @@ lock_parent: if (ma->ma_valid & MA_LOV && mdt_lmm_dom_stripesize(ma->ma_lmm)) info->mti_spec.sp_migrate_nsonly = 1; + } else if (S_ISDIR(lu_object_attr(&sobj->mot_obj))) { + rc = mdt_stripe_get(info, sobj, ma, XATTR_NAME_LMV); + if (rc) + GOTO(unlock_links, rc); + + /* race with restripe/auto-split? */ + if ((ma->ma_valid & MA_LMV) && + lmv_is_restriping(&ma->ma_lmv->lmv_md_v1)) + GOTO(unlock_links, rc = -EBUSY); } /* if migration HSM is allowed */ diff --git a/lustre/mdt/mdt_restripe.c b/lustre/mdt/mdt_restripe.c index 9d5abea..794ca4e 100644 --- a/lustre/mdt/mdt_restripe.c +++ b/lustre/mdt/mdt_restripe.c @@ -317,6 +317,10 @@ static int mdt_auto_split(struct mdt_thread_info *info) if (le32_to_cpu(lmv->lmv_magic) != LMV_MAGIC_STRIPE) GOTO(out, rc = -EINVAL); + /* race with migrate? */ + if (lmv_hash_is_migrating(cpu_to_le32(lmv->lmv_hash_type))) + GOTO(out, rc = -EBUSY); + lmv_stripe_count = le32_to_cpu(lmv->lmv_stripe_count); /* save stripe to clear 'restriping' flag in the end to avoid diff --git a/lustre/mdt/mdt_xattr.c b/lustre/mdt/mdt_xattr.c index 848c6c4..f8d9911 100644 --- a/lustre/mdt/mdt_xattr.c +++ b/lustre/mdt/mdt_xattr.c @@ -502,6 +502,8 @@ int mdt_dir_layout_update(struct mdt_thread_info *info) lmv->lmv_hash_type &= ~LMV_HASH_FLAG_LAYOUT_CHANGE; lmv->lmv_layout_version = cpu_to_le32(++version); + lmv->lmv_migrate_offset = 0; + lmv->lmv_migrate_hash = 0; buf->lb_buf = lmv; buf->lb_len = sizeof(*lmv); rc = mo_xattr_set(env, mdt_object_child(obj), buf,