From c62ba699c51237ae1a04b59dd23201d8fe852a67 Mon Sep 17 00:00:00 2001 From: Hongchao Zhang Date: Sat, 13 Jan 2018 17:01:54 +0800 Subject: [PATCH] LU-8264 lod: lfs setstripe fix for pool. 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 Signed-off-by: Lai Siyao Signed-off-by: Hongchao Zhang Seagate-bug-id: MRP-3615 Change-Id: Id6dd5126856db7fc773a1fe9c837a214db8d6d70 Reviewed-on: https://review.whamcloud.com/20849 Reviewed-by: Andreas Dilger Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/lod/lod_internal.h | 13 ++++++++++++ lustre/lod/lod_object.c | 52 +++++++++++++++++++++++++++++++++++++++++++++-- lustre/lod/lod_qos.c | 11 ++++++++++ lustre/mdt/mdt_open.c | 2 +- lustre/tests/ost-pools.sh | 39 +++++++++++++++++++---------------- lustre/tests/sanity.sh | 2 +- 6 files changed, 97 insertions(+), 22 deletions(-) diff --git a/lustre/lod/lod_internal.h b/lustre/lod/lod_internal.h index 0063026..9cab1e3 100644 --- a/lustre/lod/lod_internal.h +++ b/lustre/lod/lod_internal.h @@ -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)) diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index f7cb2a3..ad19c6b 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -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) { diff --git a/lustre/lod/lod_qos.c b/lustre/lod/lod_qos.c index 840db03..91420d5 100644 --- a/lustre/lod/lod_qos.c +++ b/lustre/lod/lod_qos.c @@ -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 && diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index a428ea9..e67f496 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -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)) { diff --git a/lustre/tests/ost-pools.sh b/lustre/tests/ost-pools.sh index 7773e3b..2ff5084 100755 --- a/lustre/tests/ost-pools.sh +++ b/lustre/tests/ost-pools.sh @@ -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 diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 65d7461..10cee38 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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 -- 1.8.3.1