From 3ddcf5b4a13851805f15b39aa1e95aee9b291132 Mon Sep 17 00:00:00 2001 From: Nathaniel Clark Date: Tue, 22 Mar 2016 12:52:53 -0400 Subject: [PATCH] LU-7890 lov: Ensure correct operation for large object sizes If a backing filesystem (ZFS) returns that it supports very large (LLONG_MAX) object sizes, that should be correctly supported. This fixes the check for unitialized stripe_maxbytes in lsm_unpackmd_common(), so that ZFS can return LLONG_MAX and it will be okay. This issue is excersized by writing to or past the 2TB boundry of a singly stripped file. A regression test is added to check for this. Signed-off-by: Nathaniel Clark Change-Id: I669096281bd826d69b5e86ada50077740412d268 Reviewed-on: http://review.whamcloud.com/19066 Reviewed-by: Andreas Dilger Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Jinshan Xiong Reviewed-by: Oleg Drokin --- lustre/lov/lov_ea.c | 22 +++++++++++++--------- lustre/tests/sanity.sh | 13 +++++++++++++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/lustre/lov/lov_ea.c b/lustre/lov/lov_ea.c index 05bf270..e39acc3 100644 --- a/lustre/lov/lov_ea.c +++ b/lustre/lov/lov_ea.c @@ -157,7 +157,8 @@ static int lsm_unpackmd_common(struct lov_obd *lov, struct lov_ost_data_v1 *objects) { struct lov_oinfo *loi; - loff_t stripe_maxbytes = LLONG_MAX; + loff_t min_stripe_maxbytes = 0; + loff_t lov_bytes; unsigned int stripe_count; unsigned int i; @@ -197,18 +198,21 @@ static int lsm_unpackmd_common(struct lov_obd *lov, continue; } - stripe_maxbytes = min_t(loff_t, stripe_maxbytes, - lov_tgt_maxbytes( - lov->lov_tgts[loi->loi_ost_idx])); + lov_bytes = lov_tgt_maxbytes(lov->lov_tgts[loi->loi_ost_idx]); + if (min_stripe_maxbytes == 0 || lov_bytes < min_stripe_maxbytes) + min_stripe_maxbytes = lov_bytes; } - if (stripe_maxbytes == LLONG_MAX) - stripe_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES; + if (min_stripe_maxbytes == 0) + min_stripe_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES; - if (lsm->lsm_stripe_count == 0) - lsm->lsm_maxbytes = stripe_maxbytes * lov->desc.ld_tgt_count; + stripe_count = lsm->lsm_stripe_count ?: lov->desc.ld_tgt_count; + lov_bytes = min_stripe_maxbytes * stripe_count; + + if (lov_bytes < min_stripe_maxbytes) /* handle overflow */ + lsm->lsm_maxbytes = MAX_LFS_FILESIZE; else - lsm->lsm_maxbytes = stripe_maxbytes * lsm->lsm_stripe_count; + lsm->lsm_maxbytes = lov_bytes; return 0; } diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 0d8ec04..fdfca1f 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -13773,6 +13773,19 @@ test_248() { } run_test 248 "fast read verification" +test_249() { # LU-7890 + rm -f $DIR/$tfile + $SETSTRIPE -c 1 $DIR/$tfile + + [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.8.53) ] && + skip "Need at least version 2.8.54" + + # Offset 2T == 4k * 512M + dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M || + error "dd to 2T offset failed" +} +run_test 249 "Write above 2T file size" + test_250() { [ "$(facet_fstype ost$(($($GETSTRIPE -i $DIR/$tfile) + 1)))" = "zfs" ] \ && skip "no 16TB file size limit on ZFS" && return -- 1.8.3.1