Whamcloud - gitweb
LU-17703 lod: check the inherited pool for conflicts 61/54661/5
authorVitaly Fertman <c17818@cray.com>
Wed, 3 Apr 2024 20:33:20 +0000 (23:33 +0300)
committerOleg Drokin <green@whamcloud.com>
Tue, 30 Apr 2024 06:56:25 +0000 (06:56 +0000)
In addition to LU-15658, the start index could be inherited from
parent and the pool from root: drop the pool in case of conflict
as well.

Another case of a problem inheritance is saving the inherited LOVEA
to subdir, when all the parameters are inherited but the ost list.

HPE-bug-id: LUS-11330, LUS-11631
Signed-off-by: Vitaly Fertman <vitaly.fertman@hpe.com>
Change-Id: Ief1dbd8c1ee0433bb625cbff1834b248d4fb2992
Reviewed-on: https://es-gerrit.hpc.amslabs.hpecorp.net/161800
Tested-by: Alexander Lezhoev <alexander.lezhoev@hpe.com>
Reviewed-by: Alexander Boyko <alexander.boyko@hpe.com>
Reviewed-by: Andriy Skulysh <c17819@cray.com>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54661
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Andriy Skulysh <andriy.skulysh@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/lod/lod_internal.h
lustre/lod/lod_lov.c
lustre/lod/lod_object.c
lustre/lod/lod_pool.c
lustre/lod/lod_qos.c
lustre/tests/sanity.sh
lustre/tests/test-framework.sh

index c5c5bd5..9bdba93 100644 (file)
@@ -1287,12 +1287,12 @@ static inline __u32 lov_mds_md_size(__u16 stripes, __u32 lmm_magic)
        if (stripes == LOV_ALL_STRIPES)
                stripes = 0;
 
-       if (lmm_magic == LOV_MAGIC_V3)
-               return sizeof(struct lov_mds_md_v3) +
-                               stripes * sizeof(struct lov_ost_data_v1);
-       else
+       if (lmm_magic == LOV_MAGIC_V1)
                return sizeof(struct lov_mds_md_v1) +
                                stripes * sizeof(struct lov_ost_data_v1);
+       else /* LOV_MAGIC_V3 and LOV_MAGIC_SPECIFIC */
+               return sizeof(struct lov_mds_md_v3) +
+                               stripes * sizeof(struct lov_ost_data_v1);
 }
 
 static inline __u32
index 36552ec..81ba892 100644 (file)
@@ -761,7 +761,7 @@ int lod_fill_mirrors(struct lod_object *lo);
 int lod_init_comp_foreign(struct lod_layout_component *lod_comp, void *lmm);
 
 /* lod_pool.c */
-struct lod_pool_desc *lod_find_pool(struct lod_device *lod, char *poolname);
+struct lod_pool_desc *lod_find_pool(struct lod_device *lod, const char *poolname);
 void lod_pool_putref(struct lod_pool_desc *pool);
 int lod_pool_del(struct obd_device *obd, char *poolname);
 int lod_check_index_in_pool(__u32 idx, struct lod_pool_desc *pool);
@@ -807,6 +807,7 @@ int lod_use_defined_striping(const struct lu_env *, struct lod_object *,
                             const struct lu_buf *);
 int lod_qos_parse_config(const struct lu_env *env, struct lod_object *lo,
                         const struct lu_buf *buf);
+void lod_qos_set_pool(struct lod_object *lo, int pos, const char *pool_name);
 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);
@@ -915,7 +916,7 @@ void lod_check_and_spill_pool(const struct lu_env *env, struct lod_device *lod,
                              char **poolname);
 void lod_spill_target_refresh(const struct lu_env *env, struct lod_device *lod,
                              struct lod_pool_desc *pool);
-struct lod_pool_desc *lod_pool_find(struct lod_device *lod, char *poolname);
+struct lod_pool_desc *lod_pool_find(struct lod_device *lod, const char *poolname);
 int lod_tgt_weights_seq_show(struct seq_file *m, struct lod_device *lod,
                             struct lu_tgt_pool *tgts, bool mdt);
 int lod_tgt_weights_seq_write(struct seq_file *m, const char __user *buf,
index 626938e..fd0163b 100644 (file)
@@ -753,6 +753,9 @@ static int lod_gen_component_ea(const struct lu_env *env,
                lod_comp = &lo->ldo_comp_entries[comp_idx];
 
        magic = lod_comp->llc_pool != NULL ? LOV_MAGIC_V3 : LOV_MAGIC_V1;
+       if (is_dir && lod_comp->llc_ostlist.op_count)
+               magic = LOV_MAGIC_SPECIFIC;
+
        if (lod_comp->llc_pattern == 0) /* default striping */
                lod_comp->llc_pattern = LOV_PATTERN_RAID0;
 
@@ -779,7 +782,7 @@ static int lod_gen_component_ea(const struct lu_env *env,
        } else {
                struct lov_mds_md_v3 *v3 = (struct lov_mds_md_v3 *)lmm;
                size_t cplen = strscpy(v3->lmm_pool_name,
-                                      lod_comp->llc_pool,
+                                      lod_comp->llc_pool ? : "\0",
                                       sizeof(v3->lmm_pool_name));
                if (cplen < 0)
                        RETURN(cplen);
@@ -801,7 +804,8 @@ static int lod_gen_component_ea(const struct lu_env *env,
        if (!is_dir && lo->ldo_is_composite)
                lod_comp_shrink_stripe_count(lod_comp, &stripe_count);
 
-       if (is_dir || lod_comp->llc_pattern & LOV_PATTERN_F_RELEASED)
+       if ((is_dir && magic != LOV_MAGIC_SPECIFIC) ||
+           lod_comp->llc_pattern & LOV_PATTERN_F_RELEASED)
                GOTO(done, rc = 0);
 
        /* generate ost_idx of this component stripe */
index 6bccd97..3878d3b 100644 (file)
@@ -2721,8 +2721,10 @@ __u16 lod_comp_entry_stripe_count(struct lod_object *lo, int comp_idx,
        struct lod_layout_component *entry;
        enum lod_uses_hint flags = LOD_USES_ASSIGNED_STRIPE;
 
-       if (is_dir)
-               return  0;
+       if (is_dir) {
+               entry = &lo->ldo_def_striping->lds_def_comp_entries[comp_idx];
+               return entry->llc_ostlist.op_count;
+       }
 
        entry = &lo->ldo_comp_entries[comp_idx];
        if (lod_comp_inited(entry))
@@ -2781,6 +2783,8 @@ static int lod_comp_md_size(struct lod_object *lo, bool is_dir)
                        if (!is_dir && is_composite)
                                lod_comp_shrink_stripe_count(&comp_entries[i],
                                                             &stripe_count);
+                       if (is_dir && comp_entries[i].llc_ostlist.op_count)
+                               magic = LOV_MAGIC_SPECIFIC;
 
                        size += lov_user_md_size(stripe_count, magic);
                }
@@ -6042,7 +6046,7 @@ static void lod_ah_init(const struct lu_env *env,
                                lod_comp->llc_stripe_offset =
                                        def_comp->llc_stripe_offset;
                        if (lod_comp->llc_pool == NULL)
-                               lod_obj_set_pool(lc, 0, def_comp->llc_pool);
+                               lod_qos_set_pool(lc, 0, def_comp->llc_pool);
                }
        }
 out:
@@ -6067,7 +6071,7 @@ out:
                lod_adjust_stripe_info(lod_comp, desc,
                                       ah->dah_append_stripe_count);
                if (ah->dah_append_pool && ah->dah_append_pool[0])
-                       lod_obj_set_pool(lc, 0, ah->dah_append_pool);
+                       lod_qos_set_pool(lc, 0, ah->dah_append_pool);
        }
 
        EXIT;
index bd8c589..b7c3380 100644 (file)
@@ -360,7 +360,7 @@ bool lod_pool_exists(struct lod_device *lod, char *poolname)
        return pool != NULL;
 }
 
-struct lod_pool_desc *lod_pool_find(struct lod_device *lod, char *poolname)
+struct lod_pool_desc *lod_pool_find(struct lod_device *lod, const char *poolname)
 {
        struct lod_pool_desc *pool;
 
@@ -712,7 +712,7 @@ int lod_check_index_in_pool(__u32 idx, struct lod_pool_desc *pool)
  * \retval     pointer to pool descriptor on success
  * \retval     NULL if \a poolname could not be found or poolname is empty
  */
-struct lod_pool_desc *lod_find_pool(struct lod_device *lod, char *poolname)
+struct lod_pool_desc *lod_find_pool(struct lod_device *lod, const char *poolname)
 {
        struct lod_pool_desc *pool;
 
index c93cee8..8adc06c 100644 (file)
@@ -2339,8 +2339,7 @@ unlock:
        RETURN(rc);
 }
 
-static void lod_qos_set_pool(struct lod_object *lo, int pos, char *pool_name,
-                            struct lov_user_md_v1 *v1)
+void lod_qos_set_pool(struct lod_object *lo, int pos, const char *pool_name)
 {
        struct lod_device *d = lu2lod_dev(lod2lu_obj(lo)->lo_dev);
        struct lod_layout_component *lod_comp;
@@ -2353,46 +2352,40 @@ static void lod_qos_set_pool(struct lod_object *lo, int pos, char *pool_name,
        if (pool_name)
                pool = lod_find_pool(d, pool_name);
 
-       if (!pool)
-               goto out_setpool;
+       if (!pool) {
+               lod_obj_set_pool(lo, pos, pool_name);
+               return;
+       }
 
        lod_comp = &lo->ldo_comp_entries[pos];
-       if (lod_comp->llc_stripe_offset == LOV_OFFSET_DEFAULT)
-               goto out_checkcount;
-
-       if (v1->lmm_magic == LOV_USER_MAGIC_SPECIFIC) {
-               struct lov_user_md_v3 *v3;
-
-               v3 = (struct lov_user_md_v3 *)v1;
-               for (j = 0; j < v3->lmm_stripe_count; j++) {
-                       idx = lod_comp->llc_ostlist.op_array[j];
+       if (lod_comp->llc_stripe_offset != LOV_OFFSET_DEFAULT) {
+               if (lod_comp->llc_ostlist.op_count) {
+                       for (j = 0; j < lod_comp->llc_ostlist.op_count; j++) {
+                               idx = lod_comp->llc_ostlist.op_array[j];
+                               rc = lod_check_index_in_pool(idx, pool);
+                               if (rc)
+                                       break;
+                       }
+               } else {
+                       idx = lod_comp->llc_stripe_offset;
                        rc = lod_check_index_in_pool(idx, pool);
-                       if (rc)
-                               break;
                }
-       } else {
-               idx = lod_comp->llc_stripe_offset;
-               rc = lod_check_index_in_pool(idx, pool);
-       }
-
-       if (!rc)
-               goto out_checkcount;
 
-       CDEBUG(D_LAYOUT,
-              "%s: index %u is not in the pool %s, dropping the pool\n",
-              lod2obd(d)->obd_name, idx, pool_name);
-       pool_name = NULL;
-       goto out_putref;
+               if (rc) {
+                       CDEBUG(D_LAYOUT, "%s: index %u is not in the pool %s, "
+                              "dropping the pool\n", lod2obd(d)->obd_name,
+                              idx, pool_name);
+                       pool_name = NULL;
+               }
+       }
 
-out_checkcount:
-       if (lod_comp->llc_stripe_count > pool_tgt_count(pool) &&
+       if (pool_name &&
+           lod_comp->llc_stripe_count > pool_tgt_count(pool) &&
            !(lod_comp->llc_pattern & LOV_PATTERN_OVERSTRIPING))
                lod_comp->llc_stripe_count = pool_tgt_count(pool);
-out_putref:
+
        lod_pool_putref(pool);
-out_setpool:
        lod_obj_set_pool(lo, pos, pool_name);
-
 }
 
 /**
@@ -2616,7 +2609,7 @@ int lod_qos_parse_config(const struct lu_env *env, struct lod_object *lo,
                                             lod_comp->llc_stripe_size);
 
                lod_comp->llc_stripe_offset = v1->lmm_stripe_offset;
-               lod_qos_set_pool(lo, i, pool_name, v1);
+               lod_qos_set_pool(lo, i, pool_name);
        }
 
        RETURN(0);
index 7fd3bd2..689a077 100755 (executable)
@@ -2812,6 +2812,40 @@ test_27I() {
 }
 run_test 27I "check that root dir striping does not break parent dir one"
 
+test_27Ia() {
+       (( $MDS1_VERSION >= $(version_code 2.15.61.225) )) ||
+                skip "need MDS >= 2.15.61.255 for pool inheritance fix"
+
+       (( $OSTCOUNT >= 2 )) || skip_env "needs >= 2 OSTs"
+
+       save_layout_restore_at_exit $MOUNT
+       pool_add $TESTNAME || error "pool_add failed"
+       pool_add_targets $TESTNAME 1 || error "pool_add_targets failed"
+
+       $LFS setstripe -p $TESTNAME $MOUNT
+
+       test_mkdir $DIR/$tdir
+       $LFS setstripe -i0 $DIR/$tdir
+       $MULTIOP $DIR/$tdir/$tfile.1 Oc || error_noexit "multiop failed"
+       $LFS getstripe $DIR/$tdir/$tfile.1
+
+       $LFS setstripe -d $DIR/$tdir
+       $LFS setstripe -o 0,1 $DIR/$tdir
+       $MULTIOP $DIR/$tdir/$tfile.2 Oc || error_noexit "multiop failed"
+       $LFS getstripe $DIR/$tdir/$tfile.2
+
+       test_mkdir $DIR/$tdir/d1
+       $MULTIOP $DIR/$tdir/d1/$tfile.3 Oc || error_noexit "multiop failed"
+       $LFS getstripe $DIR/$tdir/d1/$tfile.3
+
+       $LFS setstripe -d $DIR/$tdir
+       $LFS setstripe -E 128G -o 0,1 -E-1 $DIR/$tdir
+       test_mkdir $DIR/$tdir/d2
+       $MULTIOP $DIR/$tdir/d2/$tfile.4 Oc || error_noexit "multiop failed"
+       $LFS getstripe $DIR/$tdir/d2/$tfile.4
+}
+run_test 27Ia "check that root dir pool is dropped with conflict parent dir settings"
+
 test_27J() {
        (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
                skip "Need MDS version newer than 2.12.51"
index d4ff821..15bf137 100755 (executable)
@@ -10039,15 +10039,10 @@ pool_add_targets() {
        echo "Adding targets to pool"
        local pool=$1
        local first=$2
-       local last=$3
+       local last=${3:-$first}
        local step=${4:-1}
 
-       if [ -z $last ]; then
-               local list=$first
-               last=$first
-       else
-               local list=$(seq $first $step $last)
-       fi
+       local list=$(seq $first $step $last)
 
        local t=$(for i in $list; do printf "$FSNAME-OST%04x_UUID " $i; done)
        local tg=$(for i in $list;