From 46ebfdd558dbe57db6cf51351246ca81bd38e4c9 Mon Sep 17 00:00:00 2001 From: wang di Date: Thu, 27 Aug 2015 03:35:18 -0700 Subject: [PATCH] LU-6826 lod: validate stripe_count and offset Validate stripe_offset and stripe_count in lod_ah_init, so these two values will not cause unexpected failures in the following creation. Add sanity.sh 300m to verify the case. Signed-off-by: wang di Change-Id: I3d36b29079a36355eb4a8d645b70c04aa6d80a40 Reviewed-on: http://review.whamcloud.com/16130 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Lai Siyao Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- lustre/lod/lod_object.c | 46 +++++++++++++++++++++++++++++++++++++--------- lustre/tests/sanity.sh | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index f9a6cb2..9e3e800 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -1799,11 +1799,6 @@ static int lod_prep_md_striped_create(const struct lu_env *env, stripe_count = le32_to_cpu(lum->lum_stripe_count); - /* shrink the stripe_count to the avaible MDT count */ - if (stripe_count > lod->lod_remote_mdt_count + 1 && - !OBD_FAIL_CHECK(OBD_FAIL_LARGE_STRIPE)) - stripe_count = lod->lod_remote_mdt_count + 1; - OBD_ALLOC(stripe, sizeof(stripe[0]) * stripe_count); if (stripe == NULL) RETURN(-ENOMEM); @@ -1997,7 +1992,6 @@ out: RETURN(rc); } - /** * Implementation of dt_object_operations::do_declare_xattr_set. * @@ -3254,8 +3248,6 @@ static void lod_ah_init(const struct lu_env *env, rc = lod_verify_md_striping(d, lum1); if (rc == 0 && le32_to_cpu(lum1->lum_stripe_count) > 1) { - /* Directory will be striped only if - * stripe_count > 1 */ lc->ldo_stripenr = le32_to_cpu(lum1->lum_stripe_count); lc->ldo_dir_stripe_offset = @@ -3283,6 +3275,18 @@ static void lod_ah_init(const struct lu_env *env, lc->ldo_dir_stripe_offset = -1; } + /* shrink the stripe_count to the avaible MDT count */ + if (lc->ldo_stripenr > d->lod_remote_mdt_count + 1 && + !OBD_FAIL_CHECK(OBD_FAIL_LARGE_STRIPE)) + lc->ldo_stripenr = d->lod_remote_mdt_count + 1; + + /* Directory will be striped only if stripe_count > 1, if + * stripe_count == 1, let's reset stripenr = 0 to avoid + * create single master stripe and also help to unify the + * stripe handling of directories and files */ + if (lc->ldo_stripenr == 1) + lc->ldo_stripenr = 0; + CDEBUG(D_INFO, "final striping count:%hu, offset:%d\n", lc->ldo_stripenr, (int)lc->ldo_dir_stripe_offset); @@ -3550,7 +3554,31 @@ static int lod_declare_object_create(const struct lu_env *env, GOTO(out, rc = -EREMOTE); } else if (lo->ldo_dir_stripe_offset != ss->ss_node_id) { - GOTO(out, rc = -EREMOTE); + struct lod_device *lod; + struct lod_tgt_descs *ltd; + struct lod_tgt_desc *tgt = NULL; + bool found_mdt = false; + int i; + + lod = lu2lod_dev(lo->ldo_obj.do_lu.lo_dev); + ltd = &lod->lod_mdt_descs; + cfs_foreach_bit(ltd->ltd_tgt_bitmap, i) { + tgt = LTD_TGT(ltd, i); + if (tgt->ltd_index == + lo->ldo_dir_stripe_offset) { + found_mdt = true; + break; + } + } + + /* If the MDT indicated by stripe_offset can be + * found, then tell client to resend the create + * request to the correct MDT, otherwise return + * error to client */ + if (found_mdt) + GOTO(out, rc = -EREMOTE); + else + GOTO(out, rc = -EINVAL); } } diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index b3ca363..656df81 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -13538,6 +13538,7 @@ test_300_check_default_striped_dir() for dir in $(find $DIR/$tdir/$dirname/*); do stripe_count=$($LFS getdirstripe -c $dir) [ $stripe_count -eq $default_count ] || + [ $stripe_count -eq 0 -o $default_count -eq 1 ] || error "stripe count $default_count != $stripe_count for $dir" stripe_index=$($LFS getdirstripe -i $dir) @@ -13727,6 +13728,39 @@ test_300l() { } run_test 300l "non-root user to create dir under striped dir with stale layout" +test_300m() { + [ $PARALLEL == "yes" ] && skip "skip parallel run" && return + [ $MDSCOUNT -ge 2 ] && skip "Only for single MDT" && return + + mkdir -p $DIR/$tdir/striped_dir + $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir || + error "set default stripes dir error" + + mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails" + + stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a) + [ $stripe_count -eq 0 ] || + error "expect 0 get $stripe_count for a" + + $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir || + error "set default stripes dir error" + + mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails" + + stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b) + [ $stripe_count -eq 0 ] || + error "expect 0 get $stripe_count for b" + + $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir || + error "set default stripes dir error" + + mkdir $DIR/$tdir/striped_dir/c && + error "default stripe_index is invalid, mkdir c should fails" + + rm -rf $DIR/$tdir || error "rmdir fails" +} +run_test 300m "setstriped directory on single MDT FS" + prepare_remote_file() { mkdir $DIR/$tdir/src_dir || error "create remote source failed" -- 1.8.3.1