Whamcloud - gitweb
LU-6826 lod: validate stripe_count and offset 30/16130/3
authorwang di <di.wang@intel.com>
Thu, 27 Aug 2015 10:35:18 +0000 (03:35 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 10 Sep 2015 04:17:26 +0000 (04:17 +0000)
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 <di.wang@intel.com>
Change-Id: I3d36b29079a36355eb4a8d645b70c04aa6d80a40
Reviewed-on: http://review.whamcloud.com/16130
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/lod/lod_object.c
lustre/tests/sanity.sh

index f9a6cb2..9e3e800 100644 (file)
@@ -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);
                        }
                }
 
index b3ca363..656df81 100644 (file)
@@ -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"