From be009cb4a73b3bef7302083bec7d1d6289d515b7 Mon Sep 17 00:00:00 2001 From: Mikhail Pershin Date: Tue, 12 May 2020 23:32:22 +0300 Subject: [PATCH] LU-13535 lfsck: fix possible PFL layout corruption While checking lmm_oi in composite layout the pointer to 'lmm' is re-assigned to component entry but the same pointer is used for LOV EA buffer to update EA. Therefore if lmm_oi was fixed in some component then just current entry is saved as new layout. Signed-off-by: Mikhail Pershin Change-Id: Ifbd984a71b383ab4ca35ad59ed9cd8cf57b6d7cc Reviewed-on: https://review.whamcloud.com/38584 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Stephan Thiell --- lustre/lfsck/lfsck_layout.c | 10 ++++++---- lustre/tests/sanity-lfsck.sh | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/lustre/lfsck/lfsck_layout.c b/lustre/lfsck/lfsck_layout.c index 9f1ad92..68ca022 100644 --- a/lustre/lfsck/lfsck_layout.c +++ b/lustre/lfsck/lfsck_layout.c @@ -5671,14 +5671,15 @@ again: lmm = buf->lb_buf; magic = le32_to_cpu(lmm->lmm_magic); if (magic == LOV_MAGIC_COMP_V1) { + struct lov_mds_md_v1 *v1; int i; lcm = buf->lb_buf; count = le16_to_cpu(lcm->lcm_entry_count); for (i = 0; i < count; i++) { lcme = &lcm->lcm_entries[i]; - lmm = buf->lb_buf + le32_to_cpu(lcme->lcme_offset); - if (memcmp(oi, &lmm->lmm_oi, sizeof(*oi)) != 0) + v1 = buf->lb_buf + le32_to_cpu(lcme->lcme_offset); + if (memcmp(oi, &v1->lmm_oi, sizeof(*oi)) != 0) goto fix; } @@ -5727,12 +5728,13 @@ fix: } if (magic == LOV_MAGIC_COMP_V1) { + struct lov_mds_md_v1 *v1; int i; for (i = 0; i < count; i++) { lcme = &lcm->lcm_entries[i]; - lmm = buf->lb_buf + le32_to_cpu(lcme->lcme_offset); - lmm->lmm_oi = *oi; + v1 = buf->lb_buf + le32_to_cpu(lcme->lcme_offset); + v1->lmm_oi = *oi; } } else { lmm->lmm_oi = *oi; diff --git a/lustre/tests/sanity-lfsck.sh b/lustre/tests/sanity-lfsck.sh index 46642d2..f19d464 100644 --- a/lustre/tests/sanity-lfsck.sh +++ b/lustre/tests/sanity-lfsck.sh @@ -5787,6 +5787,35 @@ test_39() } run_test 39 "LFSCK does not break foreign dir and reverse is also true" +test_40a() { + [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs" + + check_mount_and_prep + $LFS mkdir -i 1 $DIR/$tdir/dir1 + $LFS setstripe -E 1M -c1 -S 1M -E 128M -c2 -S 4M -E eof $DIR/$tdir/dir1 + + touch $DIR/$tdir/dir1/f1 + local layout1=$(get_layout_param $DIR/$tdir/dir1/f1) + + echo "Migrate $DIR/$tdir/dir1 from MDT1 to MDT0" + $LFS migrate -m 0 $DIR/$tdir/dir1 + + echo "trigger LFSCK for layout" + do_facet $SINGLEMDS $LCTL lfsck_start -M ${MDT_DEV} -t layout -r + + wait_update_facet $SINGLEMDS "$LCTL get_param -n \ + mdd.${MDT_DEV}.lfsck_layout | + awk '/^status/ { print \\\$2 }'" "completed" 32 || { + $SHOW_LAYOUT + error "(2) unexpected status" + } + + local layout2=$(get_layout_param $DIR/$tdir/dir1/f1) + + [[ "$layout1" == "$layout2" ]] || error "layout lost after lfsck" +} +run_test 40a "LFSCK correctly fixes lmm_oi in composite layout" + # restore MDS/OST size MDSSIZE=${SAVED_MDSSIZE} OSTSIZE=${SAVED_OSTSIZE} -- 1.8.3.1