Whamcloud - gitweb
LU-10465 lod: adjust component stripe size 61/37661/4
authorMikhail Pershin <mpershin@whamcloud.com>
Fri, 21 Feb 2020 07:07:16 +0000 (10:07 +0300)
committerOleg Drokin <green@whamcloud.com>
Thu, 23 Apr 2020 16:48:36 +0000 (16:48 +0000)
With increased default stripe size to 4MB the problem can
occur when assigning default stripe size to a composite layout
component if stripe size was not specified. There is no strict
requirement to have component boundaries be aligned by default
stripe size, so choosen component end can be not aligned with
system default stripe size, e.g. 3MB end vs 4MB default size.

Patch adds checks for default stripe size assigned to composite
layout components, stripe size should be a multiplier of component
end being the greatest power of two, so check that and reduce it
to the closest valid value when needed.

Fixes: 89693927f0b0 ("LU-8998 lod: accomodate to composite layout")
Signed-off-by: Mikhail Pershin <mpershin@whamcloud.com>
Change-Id: I823307e097fda30f91ff64cc2bc4130d83c1b211
Reviewed-on: https://review.whamcloud.com/37661
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.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

index 0aedc2e..ba807c9 100644 (file)
@@ -691,6 +691,8 @@ int lod_obj_for_each_stripe(const struct lu_env *env, struct lod_object *lo,
                            struct lod_obj_stripe_cb_data *data);
 int lod_comp_copy_ost_lists(struct lod_layout_component *lod_comp,
                            struct lov_user_md_v3 *v3);
+void lod_adjust_stripe_size(struct lod_layout_component *comp,
+                           __u32 def_stripe_size);
 
 /* lod_sub_object.c */
 struct thandle *lod_sub_get_thandle(const struct lu_env *env,
index d70f46f..f146f33 100644 (file)
@@ -1721,7 +1721,6 @@ int lod_fix_dom_stripe(struct lod_device *d, struct lov_comp_md_v1 *comp_v1,
 int lod_verify_striping(struct lod_device *d, struct lod_object *lo,
                        const struct lu_buf *buf, bool is_from_disk)
 {
-       struct lov_desc *desc = &d->lod_ost_descs.ltd_lov_desc;
        struct lov_user_md_v1   *lum;
        struct lov_comp_md_v1   *comp_v1;
        struct lov_comp_md_entry_v1     *ent;
@@ -1933,9 +1932,7 @@ recheck:
 
                /* extent end must be aligned with the stripe_size */
                stripe_size = le32_to_cpu(lum->lmm_stripe_size);
-               if (stripe_size == 0)
-                       stripe_size = desc->ld_default_stripe_size;
-               if (prev_end % stripe_size) {
+               if (stripe_size && prev_end % stripe_size) {
                        CDEBUG(D_LAYOUT, "stripe size isn't aligned, "
                               "stripe_sz: %u, [%llu, %llu)\n",
                               stripe_size, ext->e_start, prev_end);
index 284a577..8850829 100644 (file)
@@ -1075,6 +1075,37 @@ static int lod_attr_get(const struct lu_env *env,
        return dt_attr_get(env, dt_object_child(dt), attr);
 }
 
+void lod_adjust_stripe_size(struct lod_layout_component *comp,
+                           __u32 def_stripe_size)
+{
+       __u64 comp_end = comp->llc_extent.e_end;
+
+       /* Choose stripe size if not set. Note that default stripe size can't
+        * be used as is, because it must be multiplier of given component end.
+        *  - first check if default stripe size can be used
+        *  - if not than select the lowest set bit from component end and use
+        *    that value as stripe size
+        */
+       if (!comp->llc_stripe_size) {
+               if (comp_end == LUSTRE_EOF || !(comp_end % def_stripe_size))
+                       comp->llc_stripe_size = def_stripe_size;
+               else
+                       comp->llc_stripe_size = comp_end & ~(comp_end - 1);
+       } else {
+               /* check stripe size is multiplier of comp_end */
+               if (comp_end != LUSTRE_EOF &&
+                   comp_end % comp->llc_stripe_size) {
+                       /* fix that even for defined stripe size but warn
+                        * about the problem, that must not happen
+                        */
+                       CWARN("Component end %llu is not aligned by the stripe size %u\n",
+                             comp_end, comp->llc_stripe_size);
+                       dump_stack();
+                       comp->llc_stripe_size = comp_end & ~(comp_end - 1);
+               }
+       }
+}
+
 static inline void lod_adjust_stripe_info(struct lod_layout_component *comp,
                                          struct lov_desc *desc,
                                          int append_stripes)
@@ -1087,8 +1118,8 @@ static inline void lod_adjust_stripe_info(struct lod_layout_component *comp,
                                desc->ld_default_stripe_count;
                }
        }
-       if (comp->llc_stripe_size <= 0)
-               comp->llc_stripe_size = desc->ld_default_stripe_size;
+
+       lod_adjust_stripe_size(comp, desc->ld_default_stripe_size);
 }
 
 int lod_obj_for_each_stripe(const struct lu_env *env, struct lod_object *lo,
index a027947..2d6d369 100644 (file)
@@ -2180,9 +2180,8 @@ int lod_qos_parse_config(const struct lu_env *env, struct lod_object *lo,
                }
 
                lod_comp->llc_pattern = v1->lmm_pattern;
-               lod_comp->llc_stripe_size = desc->ld_default_stripe_size;
-               if (v1->lmm_stripe_size)
-                       lod_comp->llc_stripe_size = v1->lmm_stripe_size;
+               lod_comp->llc_stripe_size = v1->lmm_stripe_size;
+               lod_adjust_stripe_size(lod_comp, desc->ld_default_stripe_size);
 
                lod_comp->llc_stripe_count = desc->ld_default_stripe_count;
                if (v1->lmm_stripe_count ||