Whamcloud - gitweb
LU-14996 lov: prefer mirrors on non-rotational OSTs
[fs/lustre-release.git] / lustre / lov / lov_object.c
index 3da2c49..f8a7522 100644 (file)
@@ -232,6 +232,7 @@ static int lov_init_raid0(const struct lu_env *env, struct lov_device *dev,
                struct cl_device *subdev;
                struct lov_oinfo *oinfo = lse->lsme_oinfo[i];
                int ost_idx = oinfo->loi_ost_idx;
+               struct obd_export *exp;
 
                if (lov_oinfo_is_dummy(oinfo))
                        continue;
@@ -246,6 +247,13 @@ static int lov_init_raid0(const struct lu_env *env, struct lov_device *dev,
                        GOTO(out, result = -EIO);
                }
 
+               exp = dev->ld_lov->lov_tgts[ost_idx]->ltd_exp;
+               if (likely(exp)) {
+                       /* the more fast OSTs the better */
+                       if (exp->exp_obd->obd_osfs.os_state & OS_STATFS_NONROT)
+                               lle->lle_preference++;
+               }
+
                subdev = lovsub2cl_dev(dev->ld_target[ost_idx]);
                subconf->u.coc_oinfo = oinfo;
                LASSERTF(subdev != NULL, "not init ost %d\n", ost_idx);
@@ -624,7 +632,7 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
        int flr_state = lsm->lsm_flags & LCM_FL_FLR_MASK;
        int result = 0;
        unsigned int seq;
-       int i, j;
+       int i, j, preference;
        bool dom_size = 0;
 
        ENTRY;
@@ -663,6 +671,7 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
 
                lle->lle_lsme = lsm->lsm_entries[i];
                lle->lle_type = lov_entry_type(lle->lle_lsme);
+               lle->lle_preference = 0;
                switch (lle->lle_type) {
                case LOV_PATTERN_RAID0:
                        lle->lle_comp_ops = &raid0_ops;
@@ -723,8 +732,8 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
                /* entries must be sorted by mirrors */
                lre->lre_mirror_id = mirror_id;
                lre->lre_start = lre->lre_end = i;
-               lre->lre_preferred = !!(lle->lle_lsme->lsme_flags &
-                                       LCME_FL_PREF_RD);
+               lre->lre_preference = lle->lle_lsme->lsme_flags &
+                                       LCME_FL_PREF_RD ? 1000 : 0;
                lre->lre_valid = lle->lle_valid;
                lre->lre_stale = !lle->lle_valid;
                lre->lre_foreign = lsme_is_foreign(lle->lle_lsme);
@@ -769,6 +778,7 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
        /* decide the preferred mirror. It uses the hash value of lov_object
         * so that different clients would use different mirrors for read. */
        mirror_count = 0;
+       preference = -1;
        seq = hash_long((unsigned long)lov, 8);
        for (i = 0; i < comp->lo_mirror_count; i++) {
                unsigned int idx = (i + seq) % comp->lo_mirror_count;
@@ -782,8 +792,16 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
 
                mirror_count++; /* valid mirror */
 
-               if (lre->lre_preferred || comp->lo_preferred_mirror < 0)
+               /* aggregated preference of all involved OSTs */
+               for (j = lre->lre_start; j <= lre->lre_end; j++) {
+                       lre->lre_preference +=
+                               comp->lo_entries[j].lle_preference;
+               }
+
+               if (lre->lre_preference > preference) {
+                       preference = lre->lre_preference;
                        comp->lo_preferred_mirror = idx;
+               }
        }
        if (!mirror_count) {
                CDEBUG(D_INODE, DFID