From 0d1831c9e9ba456e44c984cd3f31d8cbe054745f Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Mon, 14 Nov 2022 16:25:05 +0800 Subject: [PATCH] EX-6245 csdc: define compress component layout Define a layout containing compress component with a compress pattern so that old client cannot process it. Add a client parameter to enable file compression support. lctl get_param llite.*.enable_compression lctl set_param llite.*.enable_compression={0,1} Signed-off-by: Bobi Jam Change-Id: If88d446fc7425644ea9484004ffa4e6d2a05f7e6 Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/49508 Tested-by: jenkins Tested-by: Andreas Dilger Reviewed-by: Alex Zhuravlev Reviewed-by: Andreas Dilger Reviewed-by: Sebastien Buisson --- lustre/include/lustre_lib.h | 2 ++ lustre/include/uapi/linux/lustre/lustre_user.h | 17 +++++++++------- lustre/llite/lproc_llite.c | 25 +++++++++++++++++++++++ lustre/lod/lod_internal.h | 5 +++++ lustre/lod/lod_lov.c | 7 +++++++ lustre/lod/lod_object.c | 6 ++++++ lustre/lod/lod_qos.c | 28 +++++++++++++++++--------- lustre/lov/lov_ea.c | 19 +++++++++++++++++ lustre/lov/lov_internal.h | 4 ++++ lustre/ptlrpc/pack_generic.c | 12 +++++++++++ lustre/tests/sanity-pfl.sh | 28 ++++++++++++++++++++++++++ lustre/utils/liblustreapi_layout.c | 3 ++- 12 files changed, 139 insertions(+), 17 deletions(-) diff --git a/lustre/include/lustre_lib.h b/lustre/include/lustre_lib.h index fa6306e..5a8ced1 100644 --- a/lustre/include/lustre_lib.h +++ b/lustre/include/lustre_lib.h @@ -67,6 +67,8 @@ struct lu_target; #endif #define LP_POISON ((void *)LL_POISON) +extern int llite_enable_compression; + #ifdef HAVE_SERVER_SUPPORT int rev_import_init(struct obd_export *exp); int target_handle_connect(struct ptlrpc_request *req); diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index 572c8aa..977fc92 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -735,10 +735,12 @@ struct fsxattr { static inline bool lov_pattern_supported(__u32 pattern) { - pattern &= ~LOV_PATTERN_F_RELEASED; - return pattern == LOV_PATTERN_RAID0 || - pattern == (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING) || - pattern == LOV_PATTERN_MDT; + __u32 pattern_base = pattern & ~LOV_PATTERN_F_RELEASED; + + return pattern_base == LOV_PATTERN_RAID0 || + pattern_base == (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING) || + pattern_base == (LOV_PATTERN_RAID0 | LOV_PATTERN_COMPRESS) || + pattern_base == LOV_PATTERN_MDT; } /* RELEASED and MDT patterns are not valid in many places, so rather than @@ -883,7 +885,7 @@ enum lov_comp_md_entry_flags { #define LCME_KNOWN_FLAGS (LCME_FL_NEG | LCME_FL_INIT | LCME_FL_STALE | \ LCME_FL_PREF_RW | LCME_FL_NOSYNC | \ - LCME_FL_EXTENSION) + LCME_FL_EXTENSION | LCME_FL_NOCOMPR) /* The component flags can be set by users at creation/modification time. */ #define LCME_USER_COMP_FLAGS (LCME_FL_PREF_RW | LCME_FL_NOSYNC | \ @@ -893,7 +895,8 @@ enum lov_comp_md_entry_flags { #define LCME_USER_MIRROR_FLAGS (LCME_FL_PREF_RW) /* The allowed flags obtained from the client at component creation time. */ -#define LCME_CL_COMP_FLAGS (LCME_USER_MIRROR_FLAGS | LCME_FL_EXTENSION) +#define LCME_CL_COMP_FLAGS (LCME_USER_MIRROR_FLAGS | LCME_FL_EXTENSION | \ + LCME_FL_NOCOMPR) /* The mirror flags sent by client */ #define LCME_MIRROR_FLAGS (LCME_FL_NOSYNC) @@ -902,7 +905,7 @@ enum lov_comp_md_entry_flags { * from the default/template layout set on a directory. */ #define LCME_TEMPLATE_FLAGS (LCME_FL_PREF_RW | LCME_FL_NOSYNC | \ - LCME_FL_EXTENSION) + LCME_FL_EXTENSION | LCME_FL_NOCOMPR) /* lcme_id can be specified as certain flags, and the the first * bit of lcme_id is used to indicate that the ID is representing diff --git a/lustre/llite/lproc_llite.c b/lustre/llite/lproc_llite.c index e1f781b..cd28ab1 100644 --- a/lustre/llite/lproc_llite.c +++ b/lustre/llite/lproc_llite.c @@ -2016,6 +2016,29 @@ out_free_kernbuff: } LDEBUGFS_SEQ_FOPS(ll_pcc); +static int ll_enable_compression_seq_show(struct seq_file *m, void *v) +{ + seq_printf(m, "%d\n", llite_enable_compression ? 1 : 0); + return 0; +} + +static ssize_t ll_enable_compression_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) +{ + int val; + int rc; + + rc = kstrtoint_from_user(buffer, count, 0, &val); + if (rc < 0) + return rc; + + llite_enable_compression = !!val; + + return count; +} +LDEBUGFS_SEQ_FOPS(ll_enable_compression); + struct ldebugfs_vars lprocfs_llite_obd_vars[] = { { .name = "site", .fops = &ll_site_stats_fops }, @@ -2033,6 +2056,8 @@ struct ldebugfs_vars lprocfs_llite_obd_vars[] = { .fops = &ll_nosquash_nids_fops }, { .name = "pcc", .fops = &ll_pcc_fops, }, + { .name = "enable_compression", + .fops = &ll_enable_compression_fops, }, { NULL } }; diff --git a/lustre/lod/lod_internal.h b/lustre/lod/lod_internal.h index 5218d67..5c8ec48 100644 --- a/lustre/lod/lod_internal.h +++ b/lustre/lod/lod_internal.h @@ -173,6 +173,11 @@ struct lod_layout_component { __u32 llc_flags; __u32 llc_magic; __u64 llc_timestamp; /* snapshot time */ + __u8 llc_compr_type; + __u8 llc_compr_lvl:4; + __u16 llc_compr_chunk_log_bits; /* chunk_size = + * 2^chunk_log_bits + */ union { struct { /* plain layout V1/V3. */ __u32 llc_pattern; diff --git a/lustre/lod/lod_lov.c b/lustre/lod/lod_lov.c index 4686bc3..06bdec1 100644 --- a/lustre/lod/lod_lov.c +++ b/lustre/lod/lod_lov.c @@ -981,6 +981,13 @@ int lod_generate_lovea(const struct lu_env *env, struct lod_object *lo, cpu_to_le64(lod_comp->llc_extent.e_end); lcme->lcme_offset = cpu_to_le32(offset); + if (lod_comp->llc_pattern & LOV_PATTERN_COMPRESS) { + lcme->lcme_compr_type = lod_comp->llc_compr_type; + lcme->lcme_compr_lvl = lod_comp->llc_compr_lvl; + lcme->lcme_compr_chunk_log_bits = + lod_comp->llc_compr_chunk_log_bits - 16; + } + sub_md = (struct lov_mds_md *)((char *)lcm + offset); if (lod_comp->llc_magic == LOV_MAGIC_FOREIGN) { if (!lov_hsm_type_supported(lod_comp->llc_type)) { diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index 8dc7b81..a21f874 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -2971,6 +2971,12 @@ static int lod_declare_layout_set(const struct lu_env *env, &lo->ldo_layout_mutex); RETURN(-EUCLEAN); } + if (flags & LCME_FL_NOCOMPR && + lod_comp->llc_compr_type != 0) { + mutex_unlock( + &lo->ldo_layout_mutex); + RETURN(-EINVAL); + } lod_comp->llc_flags |= flags; } if (mirror_flag) { diff --git a/lustre/lod/lod_qos.c b/lustre/lod/lod_qos.c index daba7b4..3ba7524 100644 --- a/lustre/lod/lod_qos.c +++ b/lustre/lod/lod_qos.c @@ -2381,20 +2381,21 @@ int lod_qos_parse_config(const struct lu_env *env, struct lod_object *lo, LASSERT(lo->ldo_comp_entries); for (i = 0; i < comp_cnt; i++) { - struct pool_desc *pool; - struct lu_extent *ext; - char *pool_name; + struct pool_desc *pool; + struct lu_extent *ext; + char *pool_name; + struct lov_comp_md_entry_v1 *lcme = NULL; lod_comp = &lo->ldo_comp_entries[i]; if (lo->ldo_is_composite) { - v1 = (struct lov_user_md *)((char *)comp_v1 + - comp_v1->lcm_entries[i].lcme_offset); - ext = &comp_v1->lcm_entries[i].lcme_extent; + lcme = &comp_v1->lcm_entries[i]; + v1 = (struct lov_user_md *) + ((char *)comp_v1 + lcme->lcme_offset); + ext = &lcme->lcme_extent; lod_comp->llc_extent = *ext; - lod_comp->llc_flags = - comp_v1->lcm_entries[i].lcme_flags & - LCME_CL_COMP_FLAGS; + lod_comp->llc_flags = lcme->lcme_flags & + LCME_CL_COMP_FLAGS; } pool_name = NULL; @@ -2419,6 +2420,8 @@ int lod_qos_parse_config(const struct lu_env *env, struct lod_object *lo, if (lov_pattern(v1->lmm_pattern) != LOV_PATTERN_RAID0 && lov_pattern(v1->lmm_pattern) != LOV_PATTERN_MDT && lov_pattern(v1->lmm_pattern) != + (LOV_PATTERN_RAID0 | LOV_PATTERN_COMPRESS) && + lov_pattern(v1->lmm_pattern) != (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING)) { CDEBUG(D_LAYOUT, "%s: invalid pattern: %x\n", lod2obd(d)->obd_name, v1->lmm_pattern); @@ -2442,6 +2445,13 @@ int lod_qos_parse_config(const struct lu_env *env, struct lod_object *lo, GOTO(free_comp, rc = -EINVAL); } + if (lov_pattern(lod_comp->llc_pattern) & LOV_PATTERN_COMPRESS) { + lod_comp->llc_compr_type = lcme->lcme_compr_type; + lod_comp->llc_compr_lvl = lcme->lcme_compr_lvl; + lod_comp->llc_compr_chunk_log_bits = + lcme->lcme_compr_chunk_log_bits + 16; + } + lod_comp->llc_stripe_offset = v1->lmm_stripe_offset; lod_obj_set_pool(lo, i, pool_name); diff --git a/lustre/lov/lov_ea.c b/lustre/lov/lov_ea.c index 821c943..cf88734 100644 --- a/lustre/lov/lov_ea.c +++ b/lustre/lov/lov_ea.c @@ -41,8 +41,12 @@ #include #include +#include #include "lov_internal.h" +int llite_enable_compression; +EXPORT_SYMBOL(llite_enable_compression); + static inline void lu_extent_le_to_cpu(struct lu_extent *dst, const struct lu_extent *src) { @@ -106,6 +110,14 @@ static int lsm_lmm_verify_v1v3(struct lov_mds_md *lmm, size_t lmm_size, goto out; } + if ((lov_pattern(pattern) & ~LOV_PATTERN_F_RELEASED & + LOV_PATTERN_COMPRESS) && !llite_enable_compression) { + rc = -EINVAL; + CERROR("lov: file compression not enabled: rc = %d\n", rc); + lov_dump_lmm_common(D_WARNING, lmm); + goto out; + } + if (lmm->lmm_stripe_size == 0 || (le32_to_cpu(lmm->lmm_stripe_size)&(LOV_MIN_STRIPE_SIZE-1)) != 0) { rc = -EINVAL; @@ -573,6 +585,13 @@ lsm_unpackmd_comp_md_v1(struct lov_obd *lov, void *buf, size_t buf_size) le64_to_cpu(lcme->lcme_timestamp); lu_extent_le_to_cpu(&lsme->lsme_extent, &lcme->lcme_extent); + if (lsme->lsme_pattern & LOV_PATTERN_COMPRESS) { + lsme->lsme_compr_type = lcme->lcme_compr_type; + lsme->lsme_compr_lvl = lcme->lcme_compr_lvl; + lsme->lsme_compr_chunk_log_bits = + lcme->lcme_compr_chunk_log_bits; + } + if (i == entry_count - 1) { lsm->lsm_maxbytes = (loff_t)lsme->lsme_extent.e_start + maxbytes; diff --git a/lustre/lov/lov_internal.h b/lustre/lov/lov_internal.h index b05fb56..43a280b 100644 --- a/lustre/lov/lov_internal.h +++ b/lustre/lov/lov_internal.h @@ -48,6 +48,10 @@ struct lov_stripe_md_entry { u32 lsme_flags; u32 lsme_pattern; u64 lsme_timestamp; + u8 lsme_compr_type; + u8 lsme_compr_lvl; + u8 lsme_compr_chunk_log_bits; + /* chunk_size = 2^(16+chunk_log_bits) */ union { struct { /* For stripe objects */ u32 lsme_stripe_size; diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index c273ee8..4838de7 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -2378,6 +2378,15 @@ void lustre_print_user_md(unsigned int lvl, struct lov_user_md *lum, v1 = (struct lov_user_md *)((char *)comp_v1 + comp_v1->lcm_entries[i].lcme_offset); + + if (v1->lmm_pattern & LOV_PATTERN_COMPRESS) { + CDEBUG(lvl, "\tlcme_compr_type: %u\n", + ent->lcme_compr_type); + CDEBUG(lvl, "\tlcme_compr_lvl: %u\n", + ent->lcme_compr_lvl); + CDEBUG(lvl, "\tlcme_compr_chunk_log_bits: %u\n", + ent->lcme_compr_chunk_log_bits); + } if (v1->lmm_magic == LOV_MAGIC_FOREIGN) lustre_print_foreign(lvl, (struct lov_foreign_md *)v1, msg); @@ -2485,6 +2494,9 @@ void lustre_swab_lov_comp_md_v1(struct lov_comp_md_v1 *lum) __swab32s(&ent->lcme_size); __swab32s(&ent->lcme_layout_gen); BUILD_BUG_ON(offsetof(typeof(*ent), lcme_padding_1) == 0); + /* no need to swab lcme_compr_type */ + /* no need to swab lcme_compr_lvl */ + /* no need to swab lcme_compr_chunk_log_bits */ v1 = (struct lov_user_md_v1 *)((char *)lum + off); if (v1->lmm_magic == __swab32(LOV_USER_MAGIC_FOREIGN) || diff --git a/lustre/tests/sanity-pfl.sh b/lustre/tests/sanity-pfl.sh index 5bb04c8..5268d86 100644 --- a/lustre/tests/sanity-pfl.sh +++ b/lustre/tests/sanity-pfl.sh @@ -2432,6 +2432,34 @@ test_25() { } run_test 25 "Verify old lov stripe API with PFL files" +test_100a() { + (( $MDS1_VERSION >= $(version_code 2.14.0.85) )) || + skip "Need MDS >= 2.14.0.85 for compression support" + + local tf=$DIR/$tdir/$tfile + local p="$TMP/$TESTSUITE-$TESTNAME.parameters" + + test_mkdir $DIR/$tdir + save_lustre_params client "llite.*.enable_compression" > $p + stack_trap "restore_lustre_params < $p" EXIT + + $LCTL set_param llite.*.enable_compression=1 + + $LFS setstripe -Eeof --comp-flags=nocompr $tf || + error "set a component with nocompr failed" + $LFS setstripe --comp-set -I1 --comp-flags=compress $tf && + error "setstrpe to set a compress component should not be allowed" + $LFS setstripe --comp-set -I1 --comp-flags=partial $tf && + error "setstrpe to set a partial compress component should not be allowed" + + $LFS getstripe $tf + + local comp_flags=$($LFS getstripe -I1 --comp-flags $tf) + + [[ "$comp_flags" =~ "nocompr" ]] || error "$comp_flags do not have nocompr" +} +run_test 100a "set stripe coponent with nocompr" + complete $SECONDS check_and_cleanup_lustre exit_status diff --git a/lustre/utils/liblustreapi_layout.c b/lustre/utils/liblustreapi_layout.c index d760cf4..f249f63 100644 --- a/lustre/utils/liblustreapi_layout.c +++ b/lustre/utils/liblustreapi_layout.c @@ -3462,7 +3462,8 @@ static int llapi_layout_sanity_cb(struct llapi_layout *layout, args->lsa_rc = LSE_FLAGS; } else { if (comp->llc_flags & - ~(LCME_FL_EXTENSION | LCME_FL_PREF_RW)) + ~(LCME_FL_EXTENSION | LCME_FL_PREF_RW | + LCME_FL_NOCOMPR)) args->lsa_rc = LSE_FLAGS; } } -- 1.8.3.1