#include "lmv_internal.h"
static int lmv_check_connect(struct obd_device *obd);
+static inline bool lmv_op_default_rr_mkdir(const struct md_op_data *op_data);
void lmv_activate_target(struct lmv_obd *lmv, struct lmv_tgt_desc *tgt,
int activate)
RETURN(rc);
}
-static struct lu_tgt_desc *lmv_locate_tgt_qos(struct lmv_obd *lmv, __u32 mdt,
- unsigned short dir_depth)
+static struct lu_tgt_desc *lmv_locate_tgt_qos(struct lmv_obd *lmv,
+ struct md_op_data *op_data)
{
struct lu_tgt_desc *tgt, *cur = NULL;
__u64 total_avail = 0;
tgt->ltd_qos.ltq_usable = 1;
lu_tgt_qos_weight_calc(tgt);
- if (tgt->ltd_index == mdt)
+ if (tgt->ltd_index == op_data->op_mds)
cur = tgt;
total_avail += tgt->ltd_qos.ltq_avail;
total_weight += tgt->ltd_qos.ltq_weight;
total_usable++;
}
- /* if current MDT has above-average space, within range of the QOS
- * threshold, stay on the same MDT to avoid creating needless remote
- * MDT directories. It's more likely for low level directories
- * "16 / (dir_depth + 10)" is the factor to make it more unlikely for
- * top level directories, while more likely for low levels.
+ /* If current MDT has above-average space and dir is not aleady using
+ * round-robin to spread across more MDTs, stay on the parent MDT
+ * to avoid creating needless remote MDT directories. Remote dirs
+ * close to the root balance space more effectively than bottom dirs,
+ * so prefer to create remote dirs at top level of directory tree.
+ * "16 / (dir_depth + 10)" is the factor to make it less likely
+ * for top-level directories to stay local unless they have more than
+ * average free space, while deep dirs prefer local until more full.
+ * depth=0 -> 160%, depth=3 -> 123%, depth=6 -> 100%,
+ * depth=9 -> 84%, depth=12 -> 73%, depth=15 -> 64%
*/
- rand = total_avail * 16 / (total_usable * (dir_depth + 10));
- if (cur && cur->ltd_qos.ltq_avail >= rand) {
- tgt = cur;
- GOTO(unlock, tgt);
+ if (!lmv_op_default_rr_mkdir(op_data)) {
+ rand = total_avail * 16 /
+ (total_usable * (op_data->op_dir_depth + 10));
+ if (cur && cur->ltd_qos.ltq_avail >= rand) {
+ tgt = cur;
+ GOTO(unlock, tgt);
+ }
}
rand = lu_prandom_u64_max(total_weight);
{
const struct lmv_stripe_md *lsm = op_data->op_default_mea1;
- if (!lmv_op_default_qos_mkdir(op_data))
- return false;
-
return (op_data->op_flags & MF_RR_MKDIR) ||
(lsm && lsm->lsm_md_max_inherit_rr != LMV_INHERIT_RR_NONE) ||
fid_is_root(&op_data->op_fid1);
{
struct lmv_tgt_desc *tmp = tgt;
- tgt = lmv_locate_tgt_qos(lmv, op_data->op_mds, op_data->op_dir_depth);
+ tgt = lmv_locate_tgt_qos(lmv, op_data);
if (tgt == ERR_PTR(-EAGAIN)) {
if (ltd_qos_is_balanced(&lmv->lmv_mdt_descs) &&
!lmv_op_default_rr_mkdir(op_data) &&