Whamcloud - gitweb
LU-15850 lmv: always space-balance r-r directories
[fs/lustre-release.git] / lustre / lmv / lmv_obd.c
index 4fded87..da6e9e0 100644 (file)
@@ -56,6 +56,7 @@
 #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)
@@ -1479,8 +1480,8 @@ static int lmv_close(struct obd_export *exp, struct md_op_data *op_data,
        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;
@@ -1512,23 +1513,31 @@ static struct lu_tgt_desc *lmv_locate_tgt_qos(struct lmv_obd *lmv, __u32 mdt,
 
                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);
@@ -1863,9 +1872,6 @@ static inline bool lmv_op_default_rr_mkdir(const struct md_op_data *op_data)
 {
        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);
@@ -1900,7 +1906,7 @@ static struct lu_tgt_desc *lmv_locate_tgt_by_space(struct lmv_obd *lmv,
 {
        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) &&