Whamcloud - gitweb
LU-14191 lod: comp stripe count limit check 95/40895/2
authorVitaly Fertman <c17818@cray.com>
Thu, 26 Nov 2020 18:37:43 +0000 (21:37 +0300)
committerOleg Drokin <green@whamcloud.com>
Tue, 22 Dec 2020 05:28:22 +0000 (05:28 +0000)
when creating a PFL file of 2K stripes, they are shrinked to 700+,
because lod_get_stripe_count() checks the space left after taking
given 2K stripes into account, and the total amount of stripes that
fits into EA is 2700+.

when creating a SEL file of 2K stipes, it fails because the extension
component is also taking into account despite the fact it is never
initialised and due to the above logic 2x2k stripes leaves no space
in EA.

HPE-bug-id: LUS-9589
Signed-off-by: Vitaly Fertman <c17818@cray.com>
Change-Id: Ibeb063472d477e393646860010823fed5acb8382
Reviewed-by: Alexander Boyko <c17825@cray.com>
Reviewed-by: Artem Blagodarenko <c17828@cray.com>
Tested-by: Elena Gryaznova <c17455@cray.com>
Reviewed-on: https://review.whamcloud.com/40895
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Alexander Boyko <alexander.boyko@hpe.com>
Reviewed-by: Artem Blagodarenko <artem.blagodarenko@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/lod/lod_internal.h
lustre/lod/lod_lov.c
lustre/lod/lod_object.c
lustre/lod/lod_qos.c
lustre/tests/sanity-pfl.sh

index 6140166..4bf037b 100644 (file)
@@ -688,10 +688,9 @@ int lod_qos_prep_create(const struct lu_env *env, struct lod_object *lo,
                        struct lu_attr *attr, struct thandle *th,
                        int comp_idx, __u64 reserve);
 __u16 lod_comp_entry_stripe_count(struct lod_object *lo,
                        struct lu_attr *attr, struct thandle *th,
                        int comp_idx, __u64 reserve);
 __u16 lod_comp_entry_stripe_count(struct lod_object *lo,
-                                 struct lod_layout_component *entry,
-                                 bool is_dir);
+                                 int comp_idx, bool is_dir);
 __u16 lod_get_stripe_count(struct lod_device *lod, struct lod_object *lo,
 __u16 lod_get_stripe_count(struct lod_device *lod, struct lod_object *lo,
-                          __u16 stripe_count, bool overstriping);
+                          int comp_idx, __u16 stripe_count, bool overstriping);
 void lod_qos_statfs_update(const struct lu_env *env, struct lod_device *lod,
                           struct lu_tgt_descs *ltd);
 
 void lod_qos_statfs_update(const struct lu_env *env, struct lod_device *lod,
                           struct lu_tgt_descs *ltd);
 
index d3f6390..76f41f1 100644 (file)
@@ -704,7 +704,7 @@ static int lod_gen_component_ea(const struct lu_env *env,
                        RETURN(-E2BIG);
                objs = &v3->lmm_objects[0];
        }
                        RETURN(-E2BIG);
                objs = &v3->lmm_objects[0];
        }
-       stripe_count = lod_comp_entry_stripe_count(lo, lod_comp, is_dir);
+       stripe_count = lod_comp_entry_stripe_count(lo, comp_idx, is_dir);
        if (stripe_count == 0 && !is_dir &&
            !(lod_comp->llc_pattern & LOV_PATTERN_F_RELEASED) &&
            !(lod_comp->llc_pattern & LOV_PATTERN_MDT))
        if (stripe_count == 0 && !is_dir &&
            !(lod_comp->llc_pattern & LOV_PATTERN_F_RELEASED) &&
            !(lod_comp->llc_pattern & LOV_PATTERN_MDT))
@@ -1239,7 +1239,7 @@ int lod_parse_striping(const struct lu_env *env, struct lod_object *lo,
                                int j;
 
                                stripe_count = lod_comp_entry_stripe_count(
                                int j;
 
                                stripe_count = lod_comp_entry_stripe_count(
-                                                       lo, lod_comp, false);
+                                                       lo, i, false);
                                if (stripe_count == 0 &&
                                    !(lod_comp->llc_pattern & LOV_PATTERN_F_RELEASED) &&
                                    !(lod_comp->llc_pattern & LOV_PATTERN_MDT))
                                if (stripe_count == 0 &&
                                    !(lod_comp->llc_pattern & LOV_PATTERN_F_RELEASED) &&
                                    !(lod_comp->llc_pattern & LOV_PATTERN_MDT))
index fc9efb5..7851961 100644 (file)
@@ -2632,19 +2632,21 @@ static int lod_replace_parent_fid(const struct lu_env *env,
 }
 
 inline __u16 lod_comp_entry_stripe_count(struct lod_object *lo,
 }
 
 inline __u16 lod_comp_entry_stripe_count(struct lod_object *lo,
-                                        struct lod_layout_component *entry,
-                                        bool is_dir)
+                                        int comp_idx, bool is_dir)
 {
        struct lod_device *lod = lu2lod_dev(lod2lu_obj(lo)->lo_dev);
 {
        struct lod_device *lod = lu2lod_dev(lod2lu_obj(lo)->lo_dev);
+       struct lod_layout_component *entry;
 
        if (is_dir)
                return  0;
 
        if (is_dir)
                return  0;
-       else if (lod_comp_inited(entry))
+
+       entry = &lo->ldo_comp_entries[comp_idx];
+       if (lod_comp_inited(entry))
                return entry->llc_stripe_count;
        else if ((__u16)-1 == entry->llc_stripe_count)
                return lod->lod_ost_count;
        else
                return entry->llc_stripe_count;
        else if ((__u16)-1 == entry->llc_stripe_count)
                return lod->lod_ost_count;
        else
-               return lod_get_stripe_count(lod, lo,
+               return lod_get_stripe_count(lod, lo, comp_idx,
                                            entry->llc_stripe_count, false);
 }
 
                                            entry->llc_stripe_count, false);
 }
 
@@ -2681,8 +2683,7 @@ static int lod_comp_md_size(struct lod_object *lo, bool is_dir)
                __u16 stripe_count;
 
                magic = comp_entries[i].llc_pool ? LOV_MAGIC_V3 : LOV_MAGIC_V1;
                __u16 stripe_count;
 
                magic = comp_entries[i].llc_pool ? LOV_MAGIC_V3 : LOV_MAGIC_V1;
-               stripe_count = lod_comp_entry_stripe_count(lo, &comp_entries[i],
-                                                          is_dir);
+               stripe_count = lod_comp_entry_stripe_count(lo, i, is_dir);
                if (!is_dir && is_composite)
                        lod_comp_shrink_stripe_count(&comp_entries[i],
                                                     &stripe_count);
                if (!is_dir && is_composite)
                        lod_comp_shrink_stripe_count(&comp_entries[i],
                                                     &stripe_count);
index 644ced9..7075732 100644 (file)
@@ -1851,19 +1851,20 @@ unlock:
  *
  * \param[in] lod      LOD device
  * \param[in] lo       The lod_object
  *
  * \param[in] lod      LOD device
  * \param[in] lo       The lod_object
+ * \param[in] comp_idx The component id, which the amount of stripes is
+                       calculated for
  * \param[in] stripe_count     count the caller would like to use
  *
  * \retval             the maximum usable stripe count
  */
 __u16 lod_get_stripe_count(struct lod_device *lod, struct lod_object *lo,
  * \param[in] stripe_count     count the caller would like to use
  *
  * \retval             the maximum usable stripe count
  */
 __u16 lod_get_stripe_count(struct lod_device *lod, struct lod_object *lo,
-                          __u16 stripe_count, bool overstriping)
+                          int comp_idx, __u16 stripe_count, bool overstriping)
 {
        __u32 max_stripes = LOV_MAX_STRIPE_COUNT_OLD;
        /* max stripe count is based on OSD ea size */
        unsigned int easize = lod->lod_osd_max_easize;
        int i;
 
 {
        __u32 max_stripes = LOV_MAX_STRIPE_COUNT_OLD;
        /* max stripe count is based on OSD ea size */
        unsigned int easize = lod->lod_osd_max_easize;
        int i;
 
-
        if (!stripe_count)
                stripe_count =
                        lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_count;
        if (!stripe_count)
                stripe_count =
                        lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_count;
@@ -1887,9 +1888,17 @@ __u16 lod_get_stripe_count(struct lod_device *lod, struct lod_object *lo,
                                lo->ldo_comp_cnt;
 
                for (i = 0; i < lo->ldo_comp_cnt; i++) {
                                lo->ldo_comp_cnt;
 
                for (i = 0; i < lo->ldo_comp_cnt; i++) {
+                       unsigned int stripes;
+
+                       if (i == comp_idx)
+                               continue;
+
                        lod_comp = &lo->ldo_comp_entries[i];
                        lod_comp = &lo->ldo_comp_entries[i];
-                       comp_sz = lov_mds_md_size(lod_comp->llc_stripe_count,
-                                                 LOV_MAGIC_V3);
+                       /* Extension comp is never inited - 0 stripes on disk */
+                       stripes = lod_comp->llc_flags & LCME_FL_EXTENSION ? 0 :
+                               lod_comp->llc_stripe_count;
+
+                       comp_sz = lov_mds_md_size(stripes, LOV_MAGIC_V3);
                        total_comp_sz += comp_sz;
                        if (lod_comp->llc_flags & LCME_FL_INIT)
                                init_comp_sz += comp_sz;
                        total_comp_sz += comp_sz;
                        if (lod_comp->llc_flags & LCME_FL_INIT)
                                init_comp_sz += comp_sz;
@@ -2500,7 +2509,7 @@ int lod_qos_prep_create(const struct lu_env *env, struct lod_object *lo,
                 * could be changed if some OSTs are [de]activated manually.
                 */
                lod_qos_statfs_update(env, d, &d->lod_ost_descs);
                 * could be changed if some OSTs are [de]activated manually.
                 */
                lod_qos_statfs_update(env, d, &d->lod_ost_descs);
-               stripe_len = lod_get_stripe_count(d, lo,
+               stripe_len = lod_get_stripe_count(d, lo, comp_idx,
                                                  lod_comp->llc_stripe_count,
                                                  lod_comp->llc_pattern &
                                                  LOV_PATTERN_OVERSTRIPING);
                                                  lod_comp->llc_stripe_count,
                                                  lod_comp->llc_pattern &
                                                  LOV_PATTERN_OVERSTRIPING);
index b39ea7c..d70edaa 100644 (file)
@@ -76,21 +76,58 @@ test_0b() {
 
        test_mkdir $DIR/$tdir
 
 
        test_mkdir $DIR/$tdir
 
+       $LFS setstripe -E -1 -C $LOV_MAX_STRIPE_COUNT $comp_file ||
+               error "Create $comp_file failed"
+
+       local count=$($LFS getstripe -I1 -c $comp_file)
+       [ $count -eq $LOV_MAX_STRIPE_COUNT ] ||
+               error "stripe count of first component is shrinked to $count"
+
+       rm -f $comp_file || error "Delete $comp_file failed"
+
        # Create file with 1.1*LOV_MAX_STRIPE_COUNT stripes should succeed
        $LFS setstripe -E 1m -C $((LOV_MAX_STRIPE_COUNT / 10)) -E -1 \
                -C $LOV_MAX_STRIPE_COUNT $comp_file ||
        # Create file with 1.1*LOV_MAX_STRIPE_COUNT stripes should succeed
        $LFS setstripe -E 1m -C $((LOV_MAX_STRIPE_COUNT / 10)) -E -1 \
                -C $LOV_MAX_STRIPE_COUNT $comp_file ||
-       error "Create $comp_file failed"
+               error "Create $comp_file failed"
+
+       local count=$($LFS getstripe -I2 -c $comp_file)
+       [ $count -eq $LOV_MAX_STRIPE_COUNT ] ||
+               error "stripe count of second component is shrinked to $count"
 
        rm -f $comp_file || error "Delete $comp_file failed"
 
 
        rm -f $comp_file || error "Delete $comp_file failed"
 
-       # Create file with 2*LOV_MAX_STRIPE_COUNT stripes should fail
-       $LFS setstripe -E 1m -C $LOV_MAX_STRIPE_COUNT -E -1 -C $LOV_MAX_STRIPE_COUNT \
-               $comp_file && error "Create $comp_file succeeded"
+       # Create file with 3*LOV_MAX_STRIPE_COUNT stripes should fail
+       $LFS setstripe -E 200G -C $LOV_MAX_STRIPE_COUNT \
+               -E 500G -C $LOV_MAX_STRIPE_COUNT \
+               -E -1 -C $LOV_MAX_STRIPE_COUNT $comp_file &&
+               error "Create $comp_file succeeded"
 
        rm -f $comp_file || error "Delete $comp_file failed"
 }
 run_test 0b "Verify comp stripe count limits"
 
 
        rm -f $comp_file || error "Delete $comp_file failed"
 }
 run_test 0b "Verify comp stripe count limits"
 
+test_0c() {
+       [[ $($LCTL get_param mdc.*.import |
+               grep "connect_flags:.*overstriping") ]] ||
+               skip "server does not support overstriping"
+       [ $(lustre_version_code $SINGLEMDS) -lt $(version_code $SEL_VER) ] &&
+               skip "skipped for lustre < $SEL_VER"
+
+       large_xattr_enabled || skip_env "no large xattr support"
+
+       local comp_file=$DIR/$tdir/$tfile
+
+       test_mkdir $DIR/$tdir
+
+       $LFS setstripe -E -1 -C $LOV_MAX_STRIPE_COUNT -z 128M $comp_file ||
+               error "Create $comp_file failed"
+
+       local count=$($LFS getstripe -I1 -c $comp_file)
+       [ $count -eq $LOV_MAX_STRIPE_COUNT ] ||
+               error "stripe count is shrinked to $count"
+}
+run_test 0c "Verify SEL comp stripe count limits"
+
 test_1a() {
        local comp_file=$DIR/$tdir/$tfile
        local rw_len=$((3 * 1024 * 1024))       # 3M
 test_1a() {
        local comp_file=$DIR/$tdir/$tfile
        local rw_len=$((3 * 1024 * 1024))       # 3M