Whamcloud - gitweb
LU-8264 lod: lfs setstripe fix for pool. 49/20849/13
authorHongchao Zhang <hongchao.zhang@intel.com>
Sat, 13 Jan 2018 09:01:54 +0000 (17:01 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 25 Jan 2018 04:45:45 +0000 (04:45 +0000)
If a file is created (with lfs) in the directory associated
with pool without -p pool_name option then limit stripe count
to number of osts in the pool as that directory is associated
with the pool. This patch fixes this problem.

Also removed the wrong check from ost-pools.sh, test_20 where
we were creating file in a directory associated with pool and
checking it as not part of the pool.

Add test cases in ost_pool.sh test_20.

Signed-off-by: Rahul Deshmukh <rahul.deshmukh@seagate.com>
Signed-off-by: Lai Siyao <lai.siyao@intel.com>
Signed-off-by: Hongchao Zhang <hongchao.zhang@intel.com>
Seagate-bug-id: MRP-3615
Change-Id: Id6dd5126856db7fc773a1fe9c837a214db8d6d70
Reviewed-on: https://review.whamcloud.com/20849
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/lod/lod_internal.h
lustre/lod/lod_object.c
lustre/lod/lod_qos.c
lustre/mdt/mdt_open.c
lustre/tests/ost-pools.sh
lustre/tests/sanity.sh

index 0063026..9cab1e3 100644 (file)
@@ -518,6 +518,19 @@ lod_name_get(const struct lu_env *env, const void *area, int len)
        return lname;
 }
 
+static inline void lod_layout_get_pool(struct lod_layout_component *entries,
+                                      int count, char *pool, int len)
+{
+       int i;
+
+       for (i = 0; i < count; i++) {
+               if (entries[i].llc_pool != NULL) {
+                       strlcpy(pool, entries[i].llc_pool, len);
+                       break;
+               }
+       }
+}
+
 #define lod_foreach_ost(__dev, index)  \
        if ((__dev)->lod_osts_size > 0) \
                cfs_foreach_bit((__dev)->lod_ost_bitmap, (index))
index f7cb2a3..ad19c6b 100644 (file)
@@ -3694,6 +3694,10 @@ out:
        return rc;
 }
 
+
+static int lod_get_default_lov_striping(const struct lu_env *env,
+                                       struct lod_object *lo,
+                                       struct lod_default_striping *lds);
 /**
  * Implementation of dt_object_operations::do_xattr_set.
  *
@@ -3735,8 +3739,52 @@ static int lod_xattr_set(const struct lu_env *env,
 
        if (S_ISDIR(dt->do_lu.lo_header->loh_attr) &&
            strcmp(name, XATTR_NAME_LOV) == 0) {
-               /* default LOVEA */
-               rc = lod_xattr_set_lov_on_dir(env, dt, buf, name, fl, th);
+               struct lod_thread_info *info = lod_env_info(env);
+               struct lod_default_striping *lds = &info->lti_def_striping;
+               struct lov_user_md_v1 *v1 = buf->lb_buf;
+               char pool[LOV_MAXPOOLNAME + 1];
+
+               /* get existing striping config */
+               rc = lod_get_default_lov_striping(env, lod_dt_obj(dt), lds);
+               if (rc)
+                       RETURN(rc);
+
+               memset(pool, 0, sizeof(pool));
+               if (lds->lds_def_striping_set == 1)
+                       lod_layout_get_pool(lds->lds_def_comp_entries,
+                                           lds->lds_def_comp_cnt, pool,
+                                           sizeof(pool));
+
+               /* Retain the pool name if it is not given */
+               if (v1->lmm_magic == LOV_USER_MAGIC_V1 && pool[0] != '\0') {
+                       struct lod_thread_info *info = lod_env_info(env);
+                       struct lov_user_md_v3 *v3  = info->lti_ea_store;
+
+                       memset(v3, 0, sizeof(*v3));
+                       v3->lmm_magic = cpu_to_le32(LOV_USER_MAGIC_V3);
+                       v3->lmm_pattern = cpu_to_le32(v1->lmm_pattern);
+                       v3->lmm_stripe_count =
+                                       cpu_to_le32(v1->lmm_stripe_count);
+                       v3->lmm_stripe_offset =
+                                       cpu_to_le32(v1->lmm_stripe_offset);
+                       v3->lmm_stripe_size = cpu_to_le32(v1->lmm_stripe_size);
+
+                       strlcpy(v3->lmm_pool_name, pool,
+                               sizeof(v3->lmm_pool_name));
+
+                       info->lti_buf.lb_buf = v3;
+                       info->lti_buf.lb_len = sizeof(*v3);
+                       rc = lod_xattr_set_lov_on_dir(env, dt, &info->lti_buf,
+                                                     name, fl, th);
+               } else {
+                       rc = lod_xattr_set_lov_on_dir(env, dt, buf, name,
+                                                     fl, th);
+               }
+
+               if (lds->lds_def_striping_set == 1 &&
+                   lds->lds_def_comp_entries != NULL)
+                       lod_free_def_comp_entries(lds);
+
                RETURN(rc);
        } else if (S_ISDIR(dt->do_lu.lo_header->loh_attr) &&
                   strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) {
index 840db03..91420d5 100644 (file)
@@ -1849,6 +1849,7 @@ int lod_qos_parse_config(const struct lu_env *env, struct lod_object *lo,
        struct lov_user_md_v1   *v1 = NULL;
        struct lov_user_md_v3   *v3 = NULL;
        struct lov_comp_md_v1   *comp_v1 = NULL;
+       char    def_pool[LOV_MAXPOOLNAME + 1];
        __u32   magic;
        __u16   comp_cnt;
        __u16   mirror_cnt;
@@ -1858,6 +1859,11 @@ int lod_qos_parse_config(const struct lu_env *env, struct lod_object *lo,
        if (buf == NULL || buf->lb_buf == NULL || buf->lb_len == 0)
                RETURN(0);
 
+       memset(def_pool, 0, sizeof(def_pool));
+       if (lo->ldo_comp_entries != NULL)
+               lod_layout_get_pool(lo->ldo_comp_entries, lo->ldo_comp_cnt,
+                                   def_pool, sizeof(def_pool));
+
        /* free default striping info */
        lod_free_comp_entries(lo);
 
@@ -1929,6 +1935,8 @@ int lod_qos_parse_config(const struct lu_env *env, struct lod_object *lo,
        if (rc)
                RETURN(rc);
 
+       LASSERT(lo->ldo_comp_entries);
+
        for (i = 0; i < comp_cnt; i++) {
                struct pool_desc        *pool;
                struct lu_extent        *ext;
@@ -1976,6 +1984,9 @@ int lod_qos_parse_config(const struct lu_env *env, struct lod_object *lo,
                        }
                }
 
+               if (pool_name == NULL && def_pool[0] != '\0')
+                       pool_name = def_pool;
+
                if (v1->lmm_pattern == 0)
                        v1->lmm_pattern = LOV_PATTERN_RAID0;
                if (lov_pattern(v1->lmm_pattern) != LOV_PATTERN_RAID0 &&
index a428ea9..e67f496 100644 (file)
@@ -1046,7 +1046,7 @@ static int mdt_open_by_fid_lock(struct mdt_thread_info *info,
        __u64                    ibits = 0;
         ENTRY;
 
-       if (md_should_create(flags) && !(flags & MDS_OPEN_HAS_EA)) {
+       if (md_should_create(flags)) {
                 if (!lu_fid_eq(rr->rr_fid1, rr->rr_fid2)) {
                         parent = mdt_object_find(env, mdt, rr->rr_fid1);
                         if (IS_ERR(parent)) {
index 7773e3b..2ff5084 100755 (executable)
@@ -607,9 +607,9 @@ test_6() {
 
        # lfs setstripe should work as before if a pool name is not specified.
        $SETSTRIPE -c -1 $POOL_DIR
-       [[ $? -eq 0 ]] || error "$SETSTRIPE -p $POOL_DIR failed."
+       [[ $? -eq 0 ]] || error "$SETSTRIPE -c -1 $POOL_DIR failed."
        $SETSTRIPE -c -1 $POOL_FILE
-       [[ $? -eq 0 ]] || error "$SETSTRIPE -p $POOL_FILE failed."
+       [[ $? -eq 0 ]] || error "$SETSTRIPE -c -1 $POOL_FILE failed."
 
        # lfs setstripe should fail if a start index that is outside the
        # pool is specified.
@@ -629,15 +629,15 @@ helper_test_7a()
        pool_add $pool || error "pool_add failed"
        pool_add_targets $pool 0 1 || error "pool_add_targets failed"
 
-       $SETSTRIPE -c 1 $DIR/$tdir/testfile1 --pool "$pool" || \
+       $SETSTRIPE -c 1 $DIR/$tdir/testfile1 --pool "$pool" ||
                error "setstripe failed"
-       $SETSTRIPE -c 1 $DIR/$tdir/testfile2 --pool "$FSNAME.$pool" || \
+       $SETSTRIPE -c 1 $DIR/$tdir/testfile2 --pool "$FSNAME.$pool" ||
                error "setstripe failed"
 
        mkdir $DIR/$tdir/testdir
-       $SETSTRIPE -c 1 $DIR/$tdir/testdir  -p "$pool" || \
+       $SETSTRIPE -c 1 $DIR/$tdir/testdir  -p "$pool" ||
                error "setstripe failed"
-       $SETSTRIPE -c 1 $DIR/$tdir/testdir  -p "$FSNAME.$pool" || \
+       $SETSTRIPE -c 1 $DIR/$tdir/testdir  -p "$FSNAME.$pool" ||
                error "setstripe failed"
 
        rm -f $DIR/$tdir/testfile1
@@ -1131,25 +1131,28 @@ test_20() {
        add_pool $POOL2 "$FSNAME-OST[$start-$TGT_MAX/2]" "$TGT"
 
        create_dir $dir1 $POOL
-       create_file $dir1/file1 $POOL2
+       create_file $dir1/file1 $POOL2  # Should replace $dir1 pool with $POOL2
        create_dir $dir2 $POOL2
-       touch $dir2/file2
-       mkdir $dir3
-       $SETSTRIPE -c 1 $dir3 # No pool assignment
-       touch $dir3/file3
-       $SETSTRIPE -c 1 $dir2/file4 # No pool assignment
+       touch $dir2/file2               # Should inherit $POOL2 from $dir2
+       mkdir $dir3                     # Should inherit $POOL from $dir1
+       $SETSTRIPE -c 1 $dir3           # Should remain existing $POOL
+       touch $dir3/file3               # Should inherit $POOL from $dir3
+       $SETSTRIPE -c 1 $dir2/file4     # Should inherit $POOL2 from dir2
+       $SETSTRIPE -S 64K $dir1/file5   # Should inderit $POOL from $dir1
 
        check_file_in_pool $dir1/file1 $POOL2
        check_file_in_pool $dir2/file2 $POOL2
-
-       check_dir_not_in_pool $dir3 $POOL
        check_dir_not_in_pool $dir3 $POOL2
-
-       check_file_not_in_pool $dir3/file3 $POOL
        check_file_not_in_pool $dir3/file3 $POOL2
-
        check_file_not_in_pool $dir2/file4 $POOL
-       check_file_not_in_pool $dir2/file4 $POOL2
+       check_file_not_in_pool $dir1/file5 $POOL2
+
+       if [ $(lustre_version_code mds1) -ge $(version_code 2.10.54) ]; then
+               check_dir_in_pool $dir3 $POOL
+               check_file_in_pool $dir3/file3 $POOL
+               check_file_in_pool $dir2/file4 $POOL2
+               check_file_in_pool $dir1/file5 $POOL
+       fi
 
        rm -rf $dir1
 
index 65d7461..10cee38 100755 (executable)
@@ -17497,7 +17497,7 @@ test_406() {
                [ $size -eq $def_stripe_size ] ||
                        error "$f stripe size $size != $def_stripe_size"
                local pool=$($GETSTRIPE -p $f)
-               [ "#$pool" == "#" ] || error "$f pool $pool is set"
+               [ $pool == $test_pool ] || error "$f pool $pool isn't set"
 
        done