Whamcloud - gitweb
LU-12624 obdclass: lu_tgt_descs cleanup
[fs/lustre-release.git] / lustre / lmv / lmv_obd.c
index 6747995..a01505b 100644 (file)
@@ -63,11 +63,12 @@ static int lmv_check_connect(struct obd_device *obd);
 void lmv_activate_target(struct lmv_obd *lmv, struct lmv_tgt_desc *tgt,
                         int activate)
 {
-        if (tgt->ltd_active == activate)
-                return;
+       if (tgt->ltd_active == activate)
+               return;
 
-        tgt->ltd_active = activate;
-        lmv->desc.ld_active_tgt_count += (activate ? 1 : -1);
+       tgt->ltd_active = activate;
+       lmv->lmv_mdt_descs.ltd_lmv_desc.ld_active_tgt_count +=
+               (activate ? 1 : -1);
 
        tgt->ltd_exp->exp_obd->obd_inactive = !activate;
 }
@@ -343,11 +344,11 @@ int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
 
        tgt->ltd_active = 1;
        tgt->ltd_exp = mdc_exp;
-       lmv->desc.ld_active_tgt_count++;
+       lmv->lmv_mdt_descs.ltd_lmv_desc.ld_active_tgt_count++;
 
        md_init_ea_size(tgt->ltd_exp, lmv->max_easize, lmv->max_def_easize);
 
-       rc = lqos_add_tgt(&lmv->lmv_qos, tgt);
+       rc = lu_qos_add_tgt(&lmv->lmv_qos, tgt);
        if (rc) {
                obd_disconnect(mdc_exp);
                RETURN(rc);
@@ -370,8 +371,7 @@ int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
 static void lmv_del_target(struct lmv_obd *lmv, struct lu_tgt_desc *tgt)
 {
        LASSERT(tgt);
-       lqos_del_tgt(&lmv->lmv_qos, tgt);
-       lu_tgt_descs_del(&lmv->lmv_mdt_descs, tgt);
+       ltd_del_tgt(&lmv->lmv_mdt_descs, tgt);
        OBD_FREE_PTR(tgt);
 }
 
@@ -382,7 +382,6 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
        struct lmv_obd *lmv = &obd->u.lmv;
        struct lmv_tgt_desc *tgt;
        struct lu_tgt_descs *ltd = &lmv->lmv_mdt_descs;
-       int orig_tgt_count = 0;
        int rc = 0;
 
        ENTRY;
@@ -406,11 +405,7 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
        tgt->ltd_active = 0;
 
        mutex_lock(&ltd->ltd_mutex);
-       rc = lu_tgt_descs_add(ltd, tgt);
-       if (!rc && index >= lmv->desc.ld_tgt_count) {
-               orig_tgt_count = lmv->desc.ld_tgt_count;
-               lmv->desc.ld_tgt_count = index + 1;
-       }
+       rc = ltd_add_tgt(ltd, tgt);
        mutex_unlock(&ltd->ltd_mutex);
 
        if (rc)
@@ -421,14 +416,10 @@ static int lmv_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
                RETURN(0);
 
        rc = lmv_connect_mdc(obd, tgt);
-       if (rc != 0) {
-               mutex_lock(&ltd->ltd_mutex);
-               lmv->desc.ld_tgt_count = orig_tgt_count;
-               memset(tgt, 0, sizeof(*tgt));
-               mutex_unlock(&ltd->ltd_mutex);
-       } else {
+       if (!rc) {
                int easize = sizeof(struct lmv_stripe_md) +
-                       lmv->desc.ld_tgt_count * sizeof(struct lu_fid);
+                       lmv->lmv_mdt_count * sizeof(struct lu_fid);
+
                lmv_init_ea_size(obd->obd_self_export, easize, 0);
        }
 
@@ -455,7 +446,7 @@ static int lmv_check_connect(struct obd_device *obd)
        if (lmv->connected)
                GOTO(unlock, rc = 0);
 
-       if (lmv->desc.ld_tgt_count == 0) {
+       if (!lmv->lmv_mdt_count) {
                CERROR("%s: no targets configured: rc = -EINVAL\n",
                       obd->obd_name);
                GOTO(unlock, rc = -EINVAL);
@@ -477,7 +468,7 @@ static int lmv_check_connect(struct obd_device *obd)
        }
 
        lmv->connected = 1;
-       easize = lmv_mds_md_size(lmv->desc.ld_tgt_count, LMV_MAGIC);
+       easize = lmv_mds_md_size(lmv->lmv_mdt_count, LMV_MAGIC);
        lmv_init_ea_size(obd->obd_self_export, easize, 0);
        EXIT;
 unlock:
@@ -491,7 +482,7 @@ out_disc:
                if (!tgt->ltd_exp)
                        continue;
 
-               --lmv->desc.ld_active_tgt_count;
+               --lmv->lmv_mdt_descs.ltd_lmv_desc.ld_active_tgt_count;
                obd_disconnect(tgt->ltd_exp);
        }
 
@@ -827,7 +818,7 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp,
        struct lmv_obd *lmv = &obddev->u.lmv;
        struct lu_tgt_desc *tgt = NULL;
        int set = 0;
-       __u32 count = lmv->desc.ld_tgt_count;
+       __u32 count = lmv->lmv_mdt_count;
        int rc = 0;
 
        ENTRY;
@@ -843,7 +834,8 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp,
                __u32 index;
 
                memcpy(&index, data->ioc_inlbuf2, sizeof(__u32));
-               if (index >= count)
+
+               if (index >= lmv->lmv_mdt_descs.ltd_tgts_size)
                        RETURN(-ENODEV);
 
                tgt = lmv_tgt(lmv, index);
@@ -876,12 +868,7 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp,
                struct obd_quotactl *oqctl;
 
                if (qctl->qc_valid == QC_MDTIDX) {
-                       if (count <= qctl->qc_idx)
-                               RETURN(-EINVAL);
-
                        tgt = lmv_tgt(lmv, qctl->qc_idx);
-                       if (!tgt || !tgt->ltd_exp)
-                               RETURN(-EINVAL);
                } else if (qctl->qc_valid == QC_UUID) {
                        lmv_foreach_tgt(lmv, tgt) {
                                if (!obd_uuid_equals(&tgt->ltd_uuid,
@@ -897,10 +884,9 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp,
                        RETURN(-EINVAL);
                }
 
-               if (tgt->ltd_index >= count)
-                       RETURN(-EAGAIN);
+               if (!tgt || !tgt->ltd_exp)
+                       RETURN(-EINVAL);
 
-               LASSERT(tgt != NULL && tgt->ltd_exp != NULL);
                OBD_ALLOC_PTR(oqctl);
                if (!oqctl)
                        RETURN(-ENOMEM);
@@ -1081,7 +1067,7 @@ static u32 lmv_placement_policy(struct obd_device *obd,
 
        ENTRY;
 
-       if (lmv->desc.ld_tgt_count == 1)
+       if (lmv->lmv_mdt_count == 1)
                RETURN(0);
 
        lum = op_data->op_data;
@@ -1199,27 +1185,17 @@ static int lmv_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
                RETURN(-EINVAL);
        }
 
-       obd_str2uuid(&lmv->desc.ld_uuid, desc->ld_uuid.uuid);
-       lmv->desc.ld_tgt_count = 0;
-       lmv->desc.ld_active_tgt_count = 0;
-       lmv->desc.ld_qos_maxage = LMV_DESC_QOS_MAXAGE_DEFAULT;
+       obd_str2uuid(&lmv->lmv_mdt_descs.ltd_lmv_desc.ld_uuid,
+                    desc->ld_uuid.uuid);
+       lmv->lmv_mdt_descs.ltd_lmv_desc.ld_tgt_count = 0;
+       lmv->lmv_mdt_descs.ltd_lmv_desc.ld_active_tgt_count = 0;
+       lmv->lmv_mdt_descs.ltd_lmv_desc.ld_qos_maxage =
+               LMV_DESC_QOS_MAXAGE_DEFAULT;
        lmv->max_def_easize = 0;
        lmv->max_easize = 0;
 
        spin_lock_init(&lmv->lmv_lock);
 
-       /* Set up allocation policy (QoS and RR) */
-       INIT_LIST_HEAD(&lmv->lmv_qos.lq_svr_list);
-       init_rwsem(&lmv->lmv_qos.lq_rw_sem);
-       lmv->lmv_qos.lq_dirty = 1;
-       lmv->lmv_qos.lq_reset = 1;
-       /* Default priority is toward free space balance */
-       lmv->lmv_qos.lq_prio_free = 232;
-       /* Default threshold for rr (roughly 17%) */
-       lmv->lmv_qos.lq_threshold_rr = 43;
-
-       lu_qos_rr_init(&lmv->lmv_qos.lq_rr);
-
        /*
         * initialize rr_index to lower 32bit of netid, so that client
         * can distribute subdirs evenly from the beginning.
@@ -1241,7 +1217,7 @@ static int lmv_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
        if (rc)
                CERROR("Can't init FLD, err %d\n", rc);
 
-       rc = lu_tgt_descs_init(&lmv->lmv_mdt_descs);
+       rc = lu_tgt_descs_init(&lmv->lmv_mdt_descs, true);
        if (rc)
                CWARN("%s: error initialize target table: rc = %d\n",
                      obd->obd_name, rc);
@@ -1304,7 +1280,7 @@ static int lmv_select_statfs_mdt(struct lmv_obd *lmv, __u32 flags)
        if (flags & OBD_STATFS_FOR_MDT0)
                return 0;
 
-       if (lmv->lmv_statfs_start || lmv->desc.ld_tgt_count == 1)
+       if (lmv->lmv_statfs_start || lmv->lmv_mdt_count == 1)
                return lmv->lmv_statfs_start;
 
        /* choose initial MDT for this client */
@@ -1317,8 +1293,8 @@ static int lmv_select_statfs_mdt(struct lmv_obd *lmv, __u32 flags)
                        /* We dont need a full 64-bit modulus, just enough
                         * to distribute the requests across MDTs evenly.
                         */
-                       lmv->lmv_statfs_start =
-                               (u32)lnet_id.nid % lmv->desc.ld_tgt_count;
+                       lmv->lmv_statfs_start = (u32)lnet_id.nid %
+                                               lmv->lmv_mdt_count;
                        break;
                }
        }
@@ -1346,8 +1322,8 @@ static int lmv_statfs(const struct lu_env *env, struct obd_export *exp,
        /* distribute statfs among MDTs */
        idx = lmv_select_statfs_mdt(lmv, flags);
 
-       for (i = 0; i < lmv->desc.ld_tgt_count; i++, idx++) {
-               idx = idx % lmv->desc.ld_tgt_count;
+       for (i = 0; i < lmv->lmv_mdt_descs.ltd_tgts_size; i++, idx++) {
+               idx = idx % lmv->lmv_mdt_descs.ltd_tgts_size;
                tgt = lmv_tgt(lmv, idx);
                if (!tgt || !tgt->ltd_exp)
                        continue;
@@ -1423,7 +1399,7 @@ int lmv_statfs_check_update(struct obd_device *obd, struct lmv_tgt_desc *tgt)
        int rc;
 
        if (ktime_get_seconds() - tgt->ltd_statfs_age <
-           obd->u.lmv.desc.ld_qos_maxage)
+           obd->u.lmv.lmv_mdt_descs.ltd_lmv_desc.ld_qos_maxage)
                return 0;
 
        rc = obd_statfs_async(tgt->ltd_exp, &oinfo, 0, NULL);
@@ -1555,6 +1531,89 @@ 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)
+{
+       struct lu_tgt_desc *tgt;
+       __u64 total_weight = 0;
+       __u64 cur_weight = 0;
+       __u64 rand;
+       int rc;
+
+       ENTRY;
+
+       if (!ltd_qos_is_usable(&lmv->lmv_mdt_descs))
+               RETURN(ERR_PTR(-EAGAIN));
+
+       down_write(&lmv->lmv_qos.lq_rw_sem);
+
+       if (!ltd_qos_is_usable(&lmv->lmv_mdt_descs))
+               GOTO(unlock, tgt = ERR_PTR(-EAGAIN));
+
+       rc = ltd_qos_penalties_calc(&lmv->lmv_mdt_descs);
+       if (rc)
+               GOTO(unlock, tgt = ERR_PTR(rc));
+
+       lmv_foreach_tgt(lmv, tgt) {
+               tgt->ltd_qos.ltq_usable = 0;
+               if (!tgt->ltd_exp || !tgt->ltd_active)
+                       continue;
+
+               tgt->ltd_qos.ltq_usable = 1;
+               lu_tgt_qos_weight_calc(tgt);
+               total_weight += tgt->ltd_qos.ltq_weight;
+       }
+
+       rand = lu_prandom_u64_max(total_weight);
+
+       lmv_foreach_connected_tgt(lmv, tgt) {
+               if (!tgt->ltd_qos.ltq_usable)
+                       continue;
+
+               cur_weight += tgt->ltd_qos.ltq_weight;
+               if (cur_weight < rand)
+                       continue;
+
+               *mdt = tgt->ltd_index;
+               ltd_qos_update(&lmv->lmv_mdt_descs, tgt, &total_weight);
+               GOTO(unlock, rc = 0);
+       }
+
+       /* no proper target found */
+       GOTO(unlock, tgt = ERR_PTR(-EAGAIN));
+unlock:
+       up_write(&lmv->lmv_qos.lq_rw_sem);
+
+       return tgt;
+}
+
+static struct lu_tgt_desc *lmv_locate_tgt_rr(struct lmv_obd *lmv, __u32 *mdt)
+{
+       struct lu_tgt_desc *tgt;
+       int i;
+       int index;
+
+       ENTRY;
+
+       spin_lock(&lmv->lmv_qos.lq_rr.lqr_alloc);
+       for (i = 0; i < lmv->lmv_mdt_descs.ltd_tgts_size; i++) {
+               index = (i + lmv->lmv_qos_rr_index) %
+                       lmv->lmv_mdt_descs.ltd_tgts_size;
+               tgt = lmv_tgt(lmv, index);
+               if (!tgt || !tgt->ltd_exp || !tgt->ltd_active)
+                       continue;
+
+               *mdt = tgt->ltd_index;
+               lmv->lmv_qos_rr_index = (*mdt + 1) %
+                                       lmv->lmv_mdt_descs.ltd_tgts_size;
+               spin_unlock(&lmv->lmv_qos.lq_rr.lqr_alloc);
+
+               RETURN(tgt);
+       }
+       spin_unlock(&lmv->lmv_qos.lq_rr.lqr_alloc);
+
+       RETURN(ERR_PTR(-ENODEV));
+}
+
 static struct lmv_tgt_desc *
 lmv_locate_tgt_by_name(struct lmv_obd *lmv, struct lmv_stripe_md *lsm,
                       const char *name, int namelen, struct lu_fid *fid,
@@ -1740,7 +1799,7 @@ int lmv_create(struct obd_export *exp, struct md_op_data *op_data,
 
        ENTRY;
 
-       if (!lmv->desc.ld_active_tgt_count)
+       if (!lmv->lmv_mdt_descs.ltd_lmv_desc.ld_active_tgt_count)
                RETURN(-EIO);
 
        if (lmv_dir_bad_hash(op_data->op_mea1))
@@ -2879,7 +2938,7 @@ static int lmv_get_info(const struct lu_env *env, struct obd_export *exp,
                        exp->exp_connect_data = *(struct obd_connect_data *)val;
                RETURN(rc);
        } else if (KEY_IS(KEY_TGT_COUNT)) {
-               *((int *)val) = lmv->desc.ld_tgt_count;
+               *((int *)val) = lmv->lmv_mdt_descs.ltd_tgts_size;
                RETURN(0);
        }
 
@@ -2893,7 +2952,7 @@ static int lmv_rmfid(struct obd_export *exp, struct fid_array *fa,
        struct obd_device *obddev = class_exp2obd(exp);
        struct ptlrpc_request_set *set = _set;
        struct lmv_obd *lmv = &obddev->u.lmv;
-       int tgt_count = lmv->desc.ld_tgt_count;
+       int tgt_count = lmv->lmv_mdt_count;
        struct lu_tgt_desc *tgt;
        struct fid_array *fat, **fas = NULL;
        int i, rc, **rcs = NULL;
@@ -3280,8 +3339,8 @@ enum ldlm_mode lmv_lock_match(struct obd_export *exp, __u64 flags,
         * since this can be easily found, and only try others if that fails.
         */
        for (i = 0, index = lmv_fid2tgt_index(lmv, fid);
-            i < lmv->desc.ld_tgt_count;
-            i++, index = (index + 1) % lmv->desc.ld_tgt_count) {
+            i < lmv->lmv_mdt_descs.ltd_tgts_size;
+            i++, index = (index + 1) % lmv->lmv_mdt_descs.ltd_tgts_size) {
                if (index < 0) {
                        CDEBUG(D_HA, "%s: "DFID" is inaccessible: rc = %d\n",
                               obd->obd_name, PFID(fid), index);