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 ||
}
/* 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
#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
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 {
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;
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 &&
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))
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;
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",
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))
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);
}
/**
*/
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)
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);
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",
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;
}
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);
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) {
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) {
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[] = {
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)
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;
}
/*
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
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",