From c605ef1dbeb401bdff5ab3cfa1c407ea87a7b95d Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Fri, 21 Jun 2019 14:47:42 +0800 Subject: [PATCH] LU-11213 uapi: change "space" hash type to hash flag Change LMV_HASH_TYPE_SPACE to LMV_HASH_FLAG_SPACE to make it flexible in directory layout inheritance in the future. But it's still exposed to user as hash type "space" in "lfs setdirstripe" command to make it easy to understand. Signed-off-by: Lai Siyao Change-Id: Ifa302204ed62dff8cc9d12fdc1f9ea86f8491d40 Reviewed-on: https://review.whamcloud.com/35318 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Hongchao Zhang Reviewed-by: Oleg Drokin --- lustre/include/lustre_lmv.h | 5 +-- lustre/include/uapi/linux/lustre/lustre_idl.h | 22 ----------- lustre/include/uapi/linux/lustre/lustre_user.h | 27 +++++++++++-- lustre/lfsck/lfsck_striped_dir.c | 3 +- lustre/lmv/lmv_obd.c | 4 +- lustre/lod/lod_object.c | 52 ++++++++++++++------------ lustre/mdt/mdt_reint.c | 6 +-- lustre/ptlrpc/wiretest.c | 6 +-- lustre/utils/lfs.c | 17 +++++++-- lustre/utils/liblustreapi.c | 5 +-- lustre/utils/lustreapi_internal.h | 4 +- lustre/utils/wirecheck.c | 6 +-- lustre/utils/wiretest.c | 6 +-- 13 files changed, 88 insertions(+), 75 deletions(-) diff --git a/lustre/include/lustre_lmv.h b/lustre/include/lustre_lmv.h index a3a5120..45c5366 100644 --- a/lustre/include/lustre_lmv.h +++ b/lustre/include/lustre_lmv.h @@ -54,7 +54,6 @@ struct lmv_stripe_md { struct lmv_oinfo lsm_md_oinfo[0]; }; -/* NB: LMV_HASH_TYPE_SPACE is set in default LMV only */ static inline bool lmv_is_known_hash_type(__u32 type) { return (type & LMV_HASH_TYPE_MASK) == LMV_HASH_TYPE_FNV_1A_64 || @@ -90,9 +89,9 @@ static inline bool lmv_dir_bad_hash(const struct lmv_stripe_md *lsm) } /* NB, this is checking directory default LMV */ -static inline bool lmv_dir_space_hashed(const struct lmv_stripe_md *lsm) +static inline bool lmv_dir_qos_mkdir(const struct lmv_stripe_md *lsm) { - return lsm && lsm->lsm_md_hash_type == LMV_HASH_TYPE_SPACE; + return lsm && (lsm->lsm_md_hash_type & LMV_HASH_FLAG_SPACE); } static inline bool diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index defdab7..025734f 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -2231,28 +2231,6 @@ struct lmv_foreign_md { #define LMV_MAGIC_STRIPE 0x0CD40CD0 /* magic for dir sub_stripe */ #define LMV_MAGIC_FOREIGN 0x0CD50CD0 /* magic for lmv foreign */ -/* Right now only the lower part(0-16bits) of lmv_hash_type is being used, - * and the higher part will be the flag to indicate the status of object, - * for example the object is being migrated. And the hash function - * might be interpreted differently with different flags. */ -#define LMV_HASH_TYPE_MASK 0x0000ffff - -#define LMV_HASH_FLAG_MIGRATION 0x80000000 - -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 12, 57, 0) -/* Since lustre 2.8, this flag will not be needed, instead this DEAD - * and orphan flags will be stored in LMA (see LMAI_ORPHAN) - * Keep this flag just for LFSCK, because it still might meet such - * flag when it checks the old FS */ -#define LMV_HASH_FLAG_DEAD 0x40000000 -#endif -#define LMV_HASH_FLAG_BAD_TYPE 0x20000000 - -/* The striped directory has ever lost its master LMV EA, then LFSCK - * re-generated it. This flag is used to indicate such case. It is an - * on-disk flag. */ -#define LMV_HASH_FLAG_LOST_LMV 0x10000000 - /** * The FNV-1a hash algorithm is as follows: * hash = FNV_offset_basis diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index 66c8fd1..a9c7f64 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -810,17 +810,36 @@ enum lmv_hash_type { LMV_HASH_TYPE_UNKNOWN = 0, /* 0 is reserved for testing purpose */ LMV_HASH_TYPE_ALL_CHARS = 1, LMV_HASH_TYPE_FNV_1A_64 = 2, - LMV_HASH_TYPE_SPACE = 3, /* - * distribute subdirs among all MDTs - * with balanced space usage. - */ LMV_HASH_TYPE_MAX, }; +#define LMV_HASH_TYPE_DEFAULT LMV_HASH_TYPE_FNV_1A_64 + #define LMV_HASH_NAME_ALL_CHARS "all_char" #define LMV_HASH_NAME_FNV_1A_64 "fnv_1a_64" + +/* not real hash type, but exposed to user as "space" hash type */ #define LMV_HASH_NAME_SPACE "space" +/* Right now only the lower part(0-16bits) of lmv_hash_type is being used, + * and the higher part will be the flag to indicate the status of object, + * for example the object is being migrated. And the hash function + * might be interpreted differently with different flags. */ +#define LMV_HASH_TYPE_MASK 0x0000ffff + +/* once this is set on a plain directory default layout, newly created + * subdirectories will be distributed on all MDTs by space usage. + */ +#define LMV_HASH_FLAG_SPACE 0x08000000 + +/* The striped directory has ever lost its master LMV EA, then LFSCK + * re-generated it. This flag is used to indicate such case. It is an + * on-disk flag. */ +#define LMV_HASH_FLAG_LOST_LMV 0x10000000 + +#define LMV_HASH_FLAG_BAD_TYPE 0x20000000 +#define LMV_HASH_FLAG_MIGRATION 0x80000000 + extern char *mdt_hash_name[LMV_HASH_TYPE_MAX]; struct lustre_foreign_type { diff --git a/lustre/lfsck/lfsck_striped_dir.c b/lustre/lfsck/lfsck_striped_dir.c index 843381c..2641e95 100644 --- a/lustre/lfsck/lfsck_striped_dir.c +++ b/lustre/lfsck/lfsck_striped_dir.c @@ -900,8 +900,7 @@ int lfsck_read_stripe_lmv(const struct lu_env *env, struct dt_object *obj, lfsck_lmv_header_le_to_cpu(lmv, lmv); if ((lmv->lmv_magic == LMV_MAGIC && !(lmv->lmv_hash_type & LMV_HASH_FLAG_MIGRATION)) || - (lmv->lmv_magic == LMV_MAGIC_STRIPE && - !(lmv->lmv_hash_type & LMV_HASH_FLAG_DEAD))) + lmv->lmv_magic == LMV_MAGIC_STRIPE) return 0; return -ENODATA; diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index f10ca5a..83e82ca 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -1199,7 +1199,7 @@ static u32 lmv_placement_policy(struct obd_device *obd, mdt = le32_to_cpu(lum->lum_stripe_offset); } else if (op_data->op_code == LUSTRE_OPC_MKDIR && !lmv_dir_striped(op_data->op_mea1) && - lmv_dir_space_hashed(op_data->op_default_mea1)) { + lmv_dir_qos_mkdir(op_data->op_default_mea1)) { mdt = op_data->op_mds; } else if (op_data->op_code == LUSTRE_OPC_MKDIR && op_data->op_default_mea1 && @@ -1744,7 +1744,7 @@ lmv_locate_tgt(struct lmv_obd *lmv, struct md_op_data *op_data) op_data->op_mds = oinfo->lmo_mds; tgt = lmv_get_target(lmv, oinfo->lmo_mds, NULL); } else if (op_data->op_code == LUSTRE_OPC_MKDIR && - lmv_dir_space_hashed(op_data->op_default_mea1) && + lmv_dir_qos_mkdir(op_data->op_default_mea1) && !lmv_dir_striped(lsm)) { tgt = lmv_locate_tgt_qos(lmv, &op_data->op_mds); if (tgt == ERR_PTR(-EAGAIN)) diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index 2b6f557..3097952 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -3689,7 +3689,7 @@ static int lod_xattr_set_default_lmv_on_dir(const struct lu_env *env, if (LMVEA_DELETE_VALUES((le32_to_cpu(lum->lum_stripe_count)), le32_to_cpu(lum->lum_stripe_offset)) && le32_to_cpu(lum->lum_magic) == LMV_USER_MAGIC && - le32_to_cpu(lum->lum_hash_type) != LMV_HASH_TYPE_SPACE) { + !(le32_to_cpu(lum->lum_hash_type) & LMV_HASH_FLAG_SPACE)) { rc = lod_xattr_del_internal(env, dt, name, th); if (rc == -ENODATA) rc = 0; @@ -4835,14 +4835,8 @@ static void lod_striping_from_default(struct lod_object *lo, lo->ldo_dir_stripe_offset = lds->lds_dir_def_stripe_offset; if (lo->ldo_dir_hash_type == 0) - lo->ldo_dir_hash_type = lds->lds_dir_def_hash_type; - - /* - * "space" hash type can only be set in default LMV, child use - * FNV_1A_64 in case it's striped. - */ - if (lo->ldo_dir_hash_type == LMV_HASH_TYPE_SPACE) - lo->ldo_dir_hash_type = LMV_HASH_TYPE_FNV_1A_64; + lo->ldo_dir_hash_type = lds->lds_dir_def_hash_type & + ~LMV_HASH_FLAG_SPACE; CDEBUG(D_LAYOUT, "striping from default dir: count:%hu, " "offset:%u, hash_type:%u\n", @@ -5244,14 +5238,29 @@ out: RETURN(rc); } -static inline int dt_object_space_hashed(const struct lu_env *env, - struct lu_device *dev, - struct dt_object *dt) +/* + * Whether subdirectories under \a dt should be created on MDTs by space QoS + * + * If LMV_HASH_FLAG_SPACE is set on directory default layout, its subdirectories + * should be created on MDT by space QoS. + * + * \param[in] env execution environment + * \param[in] dev lu device + * \param[in] dt object + * + * \retval 1 if directory should create subdir by space usage + * \retval 0 if not + * \retval -ev if failed + */ +static inline int dt_object_qos_mkdir(const struct lu_env *env, + struct lu_device *dev, + struct dt_object *dt) { + struct lod_thread_info *info = lod_env_info(env); struct lu_object *obj; struct lod_object *lo; struct lmv_user_md *lmu; - int rc = 0; + int rc; obj = lu_object_find_slice(env, dev, lu_object_fid(&dt->do_lu), NULL); if (IS_ERR(obj)) @@ -5260,18 +5269,15 @@ static inline int dt_object_space_hashed(const struct lu_env *env, lo = lu2lod_obj(obj); rc = lod_get_default_lmv_ea(env, lo); - if (rc < 0) + dt_object_put(env, dt); + if (rc <= 0) return rc; - if (rc >= (int)sizeof(*lmu)) { - struct lod_thread_info *info = lod_env_info(env); - - lmu = info->lti_ea_store; - rc = le32_to_cpu(lmu->lum_hash_type) == LMV_HASH_TYPE_SPACE; - } - dt_object_put(env, dt); + if (rc < (int)sizeof(*lmu)) + return -EINVAL; - return rc; + lmu = info->lti_ea_store; + return !!(le32_to_cpu(lmu->lum_hash_type) & LMV_HASH_FLAG_SPACE); } /** @@ -5344,7 +5350,7 @@ static int lod_declare_create(const struct lu_env *env, struct dt_object *dt, */ if (hint->dah_parent && dt_object_remote(hint->dah_parent)) { - rc = dt_object_space_hashed(env, + rc = dt_object_qos_mkdir(env, lo->ldo_obj.do_lu.lo_dev, hint->dah_parent); if (rc <= 0) diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 97672f3..452a006 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -767,10 +767,10 @@ static int mdt_reint_setattr(struct mdt_thread_info *info, buf->lb_buf = lmu; buf->lb_len = ma->ma_lmv_size; - if (le32_to_cpu(lmu->lum_hash_type) == - LMV_HASH_TYPE_SPACE) { + if (le32_to_cpu(lmu->lum_hash_type) & + LMV_HASH_FLAG_SPACE) { /* - * only allow setting "space" hash type for + * only allow setting "space" hash flag on * plain directory. */ rc = mdt_object_striped(info, mo); diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index ff662fd..9d94ec5 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -1859,10 +1859,10 @@ void lustre_assert_wire_constants(void) CLASSERT(LMV_MAGIC_V1 == 0x0CD20CD0); CLASSERT(LMV_MAGIC_STRIPE == 0x0CD40CD0); CLASSERT(LMV_HASH_TYPE_MASK == 0x0000ffff); - CLASSERT(LMV_HASH_FLAG_MIGRATION == 0x80000000); - CLASSERT(LMV_HASH_FLAG_DEAD == 0x40000000); - CLASSERT(LMV_HASH_FLAG_BAD_TYPE == 0x20000000); + CLASSERT(LMV_HASH_FLAG_SPACE == 0x08000000); CLASSERT(LMV_HASH_FLAG_LOST_LMV == 0x10000000); + CLASSERT(LMV_HASH_FLAG_BAD_TYPE == 0x20000000); + CLASSERT(LMV_HASH_FLAG_MIGRATION == 0x80000000); /* Checks for struct obd_statfs */ LASSERTF((int)sizeof(struct obd_statfs) == 144, "found %lld\n", diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 5e37d9a..9ffb589 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -694,6 +694,9 @@ static int check_hashtype(const char *hashtype) if (strcmp(hashtype, mdt_hash_name[i]) == 0) return i; + if (!strcmp(hashtype, LMV_HASH_NAME_SPACE)) + return LMV_HASH_TYPE_DEFAULT | LMV_HASH_FLAG_SPACE; + return 0; } @@ -3431,7 +3434,7 @@ static int lfs_setstripe_internal(int argc, char **argv, if (lsa.lsa_pattern != LLAPI_LAYOUT_RAID0) lmu->lum_hash_type = lsa.lsa_pattern; else - lmu->lum_hash_type = LMV_HASH_TYPE_FNV_1A_64; + lmu->lum_hash_type = LMV_HASH_TYPE_DEFAULT; if (lsa.lsa_pool_name) strncpy(lmu->lum_pool_name, lsa.lsa_pool_name, sizeof(lmu->lum_pool_name) - 1); @@ -5496,7 +5499,7 @@ static int lfs_setdirstripe(int argc, char **argv) if (lsa.lsa_pattern != LLAPI_LAYOUT_RAID0) param->lsp_stripe_pattern = lsa.lsa_pattern; else - param->lsp_stripe_pattern = LMV_HASH_TYPE_FNV_1A_64; + param->lsp_stripe_pattern = LMV_HASH_TYPE_DEFAULT; param->lsp_pool = lsa.lsa_pool_name; param->lsp_is_specific = false; if (lsa.lsa_nr_tgts > 1) { @@ -5515,13 +5518,21 @@ static int lfs_setdirstripe(int argc, char **argv) memcpy(param->lsp_tgts, mdts, sizeof(*mdts) * lsa.lsa_nr_tgts); } - if (!default_stripe && lsa.lsa_pattern == LMV_HASH_TYPE_SPACE) { + if (!default_stripe && (lsa.lsa_pattern & LMV_HASH_FLAG_SPACE)) { fprintf(stderr, "%s %s: can only specify -H space with -D\n", progname, argv[0]); free(param); return CMD_HELP; } + if (param->lsp_stripe_offset != -1 && + lsa.lsa_pattern & LMV_HASH_FLAG_SPACE) { + fprintf(stderr, "%s %s: can only specify -H space with -i -1\n", + progname, argv[0]); + free(param); + return CMD_HELP; + } + dname = argv[optind]; do { if (default_stripe) { diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index d84bbe2..e3a32e3 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -85,7 +85,6 @@ const char *liblustreapi_cmd; char *mdt_hash_name[] = { "none", LMV_HASH_NAME_ALL_CHARS, LMV_HASH_NAME_FNV_1A_64, - LMV_HASH_NAME_SPACE, }; struct lustre_foreign_type lu_foreign_types[] = { @@ -2990,10 +2989,10 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name, else llapi_printf(LLAPI_MSG_NORMAL, "%#x", type); + if (flags & LMV_HASH_FLAG_SPACE) + llapi_printf(LLAPI_MSG_NORMAL, ",space"); if (flags & LMV_HASH_FLAG_MIGRATION) llapi_printf(LLAPI_MSG_NORMAL, ",migrating"); - if (flags & LMV_HASH_FLAG_DEAD) - llapi_printf(LLAPI_MSG_NORMAL, ",dead"); if (flags & LMV_HASH_FLAG_BAD_TYPE) llapi_printf(LLAPI_MSG_NORMAL, ",bad_type"); if (flags & LMV_HASH_FLAG_LOST_LMV) diff --git a/lustre/utils/lustreapi_internal.h b/lustre/utils/lustreapi_internal.h index 4d636f4..c0662b4 100644 --- a/lustre/utils/lustreapi_internal.h +++ b/lustre/utils/lustreapi_internal.h @@ -144,7 +144,9 @@ static inline bool llapi_dir_stripe_index_is_valid(int64_t index) static inline bool llapi_dir_hash_type_is_valid(int64_t hash) { - return hash > LMV_HASH_TYPE_UNKNOWN && hash < LMV_HASH_TYPE_MAX; + int64_t _hash = hash & LMV_HASH_TYPE_MASK; + + return _hash > LMV_HASH_TYPE_UNKNOWN && _hash < LMV_HASH_TYPE_MAX; } /* diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 0fe923a..72eca34 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -850,10 +850,10 @@ check_lmv_mds_md_v1(void) CHECK_CDEFINE(LMV_MAGIC_V1); CHECK_CDEFINE(LMV_MAGIC_STRIPE); CHECK_CDEFINE(LMV_HASH_TYPE_MASK); - CHECK_CDEFINE(LMV_HASH_FLAG_MIGRATION); - CHECK_CDEFINE(LMV_HASH_FLAG_DEAD); - CHECK_CDEFINE(LMV_HASH_FLAG_BAD_TYPE); + CHECK_CDEFINE(LMV_HASH_FLAG_SPACE); CHECK_CDEFINE(LMV_HASH_FLAG_LOST_LMV); + CHECK_CDEFINE(LMV_HASH_FLAG_BAD_TYPE); + CHECK_CDEFINE(LMV_HASH_FLAG_MIGRATION); } static void diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 2c4478d..dda345b 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -1880,10 +1880,10 @@ void lustre_assert_wire_constants(void) CLASSERT(LMV_MAGIC_V1 == 0x0CD20CD0); CLASSERT(LMV_MAGIC_STRIPE == 0x0CD40CD0); CLASSERT(LMV_HASH_TYPE_MASK == 0x0000ffff); - CLASSERT(LMV_HASH_FLAG_MIGRATION == 0x80000000); - CLASSERT(LMV_HASH_FLAG_DEAD == 0x40000000); - CLASSERT(LMV_HASH_FLAG_BAD_TYPE == 0x20000000); + CLASSERT(LMV_HASH_FLAG_SPACE == 0x08000000); CLASSERT(LMV_HASH_FLAG_LOST_LMV == 0x10000000); + CLASSERT(LMV_HASH_FLAG_BAD_TYPE == 0x20000000); + CLASSERT(LMV_HASH_FLAG_MIGRATION == 0x80000000); /* Checks for struct obd_statfs */ LASSERTF((int)sizeof(struct obd_statfs) == 144, "found %lld\n", -- 1.8.3.1