From c66a7dea859d2da595e723db19df181374c900fe Mon Sep 17 00:00:00 2001 From: Alex Zhuravlev Date: Sun, 10 Nov 2024 10:17:37 +0300 Subject: [PATCH] LU-18435 lod: recover layout generation from replay The offset of the layout generation is different between struct lov_mds_md_v1/v3.lmm_layout_gen and lov_comp_md.lcm_layout_gen. When checking/setting layout gen, we must use layout-specific field. Otherwise layout generation can be set to 0 (or other random value) after replay and client can't apply new layout during later update. Fixes: 13557aa86904 ("LU-15300 mdt: refresh LOVEA with LL granted") Signed-off-by: Alex Zhuravlev Change-Id: I5e4a63cd097d157317e0e8d1a0fca4a46817d118 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56950 Reviewed-by: Oleg Drokin Reviewed-by: Qian Yingjin Reviewed-by: Alexey Lyashkov Tested-by: jenkins Tested-by: Maloo --- lustre/lod/lod_qos.c | 15 ++++++++++----- lustre/tests/replay-single.sh | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/lustre/lod/lod_qos.c b/lustre/lod/lod_qos.c index aa8c20b..3290642 100644 --- a/lustre/lod/lod_qos.c +++ b/lustre/lod/lod_qos.c @@ -2174,7 +2174,14 @@ int lod_use_defined_striping(const struct lu_env *env, magic != LOV_MAGIC_COMP_V1 && magic != LOV_MAGIC_FOREIGN) GOTO(unlock, rc = -EINVAL); - if (magic == LOV_MAGIC_COMP_V1) { + /* layout generation must be preserved, otherwise client won't + * be able to refresh it having a more recent generation */ + if (magic == LOV_MAGIC_V1 || magic == LOV_MAGIC_V3) { + mo->ldo_is_composite = 0; + comp_cnt = 1; + mirror_cnt = 0; + mo->ldo_layout_gen = le16_to_cpu(v1->lmm_layout_gen); + } else if (magic == LOV_MAGIC_COMP_V1) { comp_v1 = buf->lb_buf; comp_cnt = le16_to_cpu(comp_v1->lcm_entry_count); if (comp_cnt == 0) @@ -2183,6 +2190,7 @@ int lod_use_defined_striping(const struct lu_env *env, mo->ldo_flr_state = le16_to_cpu(comp_v1->lcm_flags) & LCM_FL_FLR_MASK; mo->ldo_is_composite = 1; + mo->ldo_layout_gen = le32_to_cpu(comp_v1->lcm_layout_gen); } else if (magic == LOV_MAGIC_FOREIGN) { struct lov_foreign_md *foreign; size_t length; @@ -2210,11 +2218,8 @@ int lod_use_defined_striping(const struct lu_env *env, memcpy(mo->ldo_foreign_lov, buf->lb_buf, length); GOTO(out, rc); } else { - mo->ldo_is_composite = 0; - comp_cnt = 1; - mirror_cnt = 0; + GOTO(out, rc = -EINVAL); } - mo->ldo_layout_gen = le16_to_cpu(v1->lmm_layout_gen); rc = lod_alloc_comp_entries(mo, mirror_cnt, comp_cnt); if (rc) diff --git a/lustre/tests/replay-single.sh b/lustre/tests/replay-single.sh index a3212e4..3695f2b 100755 --- a/lustre/tests/replay-single.sh +++ b/lustre/tests/replay-single.sh @@ -5342,6 +5342,28 @@ test_201() { } run_test 201 "MDT umount cascading disconnects timeouts" +test_202() { + local td=$DIR/$tdir + local tf=$td/$tfile + + (( $MDS1_VERSION >= $(version_code 2.16.0) )) || + (( $MDS1_VERSION < $(version_code v2_15_55-64-g13557aa869) && + $MDS1_VERSION >= $(version_code 2.14.0-ddn178) )) || + (( $MDS1_VERSION < $(version_code 2.14.0-ddn87-14-gf1bd967799) )) || + skip "need MDS with LU-18416 fix for layout version" + + mkdir_on_mdt0 $td || error "can't mkdir" + $LFS setstripe -E128M -c1 -Eeof -c2 $td || error "can't setstripe" + replay_barrier mds1 + touch $tf + local before=$($LFS getstripe -v $tf|awk '/lcm_layout_gen:/{print $2}') + fail mds1 + cancel_lru_locks mdc + local after=$($LFS getstripe -v $tf|awk '/lcm_layout_gen:/{print $2}') + (( $before == $after )) || error "layout gen changed: $before -> $after" +} +run_test 202 "pfl replay should recovery layout generation" + complete_test $SECONDS check_and_cleanup_lustre -- 1.8.3.1