lov_obd.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 1,866 行 · 第 1/5 页

C
1,866
字号
        if (tgt->ltd_exp)                lov_disconnect_obd(obd, index);        /* XXX - right now there is a dependency on ld_tgt_count being the         * maximum tgt index for computing the mds_max_easize. So we can't         * shrink it. */        lov->lov_tgts[index] = NULL;        OBD_FREE_PTR(tgt);                /* Manual cleanup - no cleanup logs to clean up the osc's.  We must           do it ourselves. And we can't do it from lov_cleanup,           because we just lost our only reference to it. */        if (osc_obd) {                /* Use lov's force/fail flags. */                osc_obd->obd_force = obd->obd_force;                osc_obd->obd_fail = obd->obd_fail;                class_manual_cleanup(osc_obd);        }}void lov_fix_desc_stripe_size(__u64 *val){        if (*val < PTLRPC_MAX_BRW_SIZE) {                LCONSOLE_WARN("Increasing default stripe size to min %u\n",                              PTLRPC_MAX_BRW_SIZE);                *val = PTLRPC_MAX_BRW_SIZE;        } else if (*val & (LOV_MIN_STRIPE_SIZE - 1)) {                *val &= ~(LOV_MIN_STRIPE_SIZE - 1);                LCONSOLE_WARN("Changing default stripe size to "LPU64" (a "                              "multiple of %u)\n",                              *val, LOV_MIN_STRIPE_SIZE);        }}void lov_fix_desc_stripe_count(__u32 *val){        if (*val == 0)                *val = 1;}void lov_fix_desc_pattern(__u32 *val){        /* from lov_setstripe */        if ((*val != 0) && (*val != LOV_PATTERN_RAID0)) {                LCONSOLE_WARN("Unknown stripe pattern: %#x\n", *val);                *val = 0;        }}void lov_fix_desc_qos_maxage(__u32 *val){        /* fix qos_maxage */        if (*val == 0)                *val = QOS_DEFAULT_MAXAGE;}void lov_fix_desc(struct lov_desc *desc){        lov_fix_desc_stripe_size(&desc->ld_default_stripe_size);        lov_fix_desc_stripe_count(&desc->ld_default_stripe_count);        lov_fix_desc_pattern(&desc->ld_pattern);        lov_fix_desc_qos_maxage(&desc->ld_qos_maxage);}static int lov_setup(struct obd_device *obd, obd_count len, void *buf){        struct lprocfs_static_vars lvars = { 0 };        struct lustre_cfg *lcfg = buf;        struct lov_desc *desc;        struct lov_obd *lov = &obd->u.lov;        int count;        ENTRY;        if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1) {                CERROR("LOV setup requires a descriptor\n");                RETURN(-EINVAL);        }        desc = (struct lov_desc *)lustre_cfg_buf(lcfg, 1);        if (sizeof(*desc) > LUSTRE_CFG_BUFLEN(lcfg, 1)) {                CERROR("descriptor size wrong: %d > %d\n",                       (int)sizeof(*desc), LUSTRE_CFG_BUFLEN(lcfg, 1));                RETURN(-EINVAL);        }        if (desc->ld_magic != LOV_DESC_MAGIC) {                if (desc->ld_magic == __swab32(LOV_DESC_MAGIC)) {                            CDEBUG(D_OTHER, "%s: Swabbing lov desc %p\n",                                   obd->obd_name, desc);                            lustre_swab_lov_desc(desc);                } else {                        CERROR("%s: Bad lov desc magic: %#x\n",                               obd->obd_name, desc->ld_magic);                        RETURN(-EINVAL);                }        }        lov_fix_desc(desc);        /* Because of 64-bit divide/mod operations only work with a 32-bit         * divisor in a 32-bit kernel, we cannot support a stripe width         * of 4GB or larger on 32-bit CPUs. */        count = desc->ld_default_stripe_count;        if ((count > 0 ? count : desc->ld_tgt_count) *            desc->ld_default_stripe_size > 0xffffffff) {                CERROR("LOV: stripe width "LPU64"x%u > 4294967295 bytes\n",                       desc->ld_default_stripe_size, count);                RETURN(-EINVAL);        }        desc->ld_active_tgt_count = 0;        lov->desc = *desc;        lov->lov_tgt_size = 0;        sema_init(&lov->lov_lock, 1);        atomic_set(&lov->lov_refcount, 0);        CFS_INIT_LIST_HEAD(&lov->lov_qos.lq_oss_list);        init_rwsem(&lov->lov_qos.lq_rw_sem);        lov->lov_qos.lq_dirty = 1;        lov->lov_qos.lq_dirty_rr = 1;        lov->lov_qos.lq_reset = 1;        /* Default priority is toward free space balance */        lov->lov_qos.lq_prio_free = 232;        lprocfs_lov_init_vars(&lvars);        lprocfs_obd_setup(obd, lvars.obd_vars);#ifdef LPROCFS        {                cfs_proc_dir_entry_t *entry;                entry = create_proc_entry("target_obd", 0444,                                          obd->obd_proc_entry);                if (entry != NULL) {                        entry->proc_fops = &lov_proc_target_fops;                        entry->data = obd;                }        }#endif        RETURN(0);}static int lov_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage){        int rc = 0;        ENTRY;        switch (stage) {        case OBD_CLEANUP_EARLY: {                struct lov_obd *lov = &obd->u.lov;                int i;                for (i = 0; i < lov->desc.ld_tgt_count; i++) {                        if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active)                                continue;                        obd_precleanup(class_exp2obd(lov->lov_tgts[i]->ltd_exp),                                       OBD_CLEANUP_EARLY);                }                break;        }        case OBD_CLEANUP_EXPORTS:                break;        case OBD_CLEANUP_SELF_EXP:                rc = obd_llog_finish(obd, 0);                if (rc != 0)                        CERROR("failed to cleanup llogging subsystems\n");                break;        case OBD_CLEANUP_OBD:                break;        }        RETURN(rc);}static int lov_cleanup(struct obd_device *obd){        struct lov_obd *lov = &obd->u.lov;        lprocfs_obd_cleanup(obd);        if (lov->lov_tgts) {                int i;                for (i = 0; i < lov->desc.ld_tgt_count; i++) {                        if (lov->lov_tgts[i]) {                                /* Inactive targets may never have connected */                                if (lov->lov_tgts[i]->ltd_active ||                                    atomic_read(&lov->lov_refcount))                                         /* We should never get here - these                                            should have been removed in the                                            disconnect. */                                        CERROR("lov tgt %d not cleaned!"                                               " deathrow=%d, lovrc=%d\n",                                               i, lov->lov_death_row,                                                atomic_read(&lov->lov_refcount));                                lov_del_target(obd, i, 0, 0);                        }                }                OBD_FREE(lov->lov_tgts, sizeof(*lov->lov_tgts) *                          lov->lov_tgt_size);                lov->lov_tgt_size = 0;        }                if (lov->lov_qos.lq_rr_size)                 OBD_FREE(lov->lov_qos.lq_rr_array, lov->lov_qos.lq_rr_size);        RETURN(0);}static int lov_process_config(struct obd_device *obd, obd_count len, void *buf){        struct lustre_cfg *lcfg = buf;        struct obd_uuid obd_uuid;        int cmd;        int rc = 0;        ENTRY;        switch(cmd = lcfg->lcfg_command) {        case LCFG_LOV_ADD_OBD:        case LCFG_LOV_ADD_INA:        case LCFG_LOV_DEL_OBD: {                __u32 index;                int gen;                /* lov_modify_tgts add  0:lov_mdsA  1:ost1_UUID  2:0  3:1 */                if (LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(obd_uuid.uuid))                        GOTO(out, rc = -EINVAL);                obd_str2uuid(&obd_uuid,  lustre_cfg_buf(lcfg, 1));                if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)                        GOTO(out, rc = -EINVAL);                if (sscanf(lustre_cfg_buf(lcfg, 3), "%d", &gen) != 1)                        GOTO(out, rc = -EINVAL);                if (cmd == LCFG_LOV_ADD_OBD)                        rc = lov_add_target(obd, &obd_uuid, index, gen, 1);                else if (cmd == LCFG_LOV_ADD_INA)                        rc = lov_add_target(obd, &obd_uuid, index, gen, 0);                else                        rc = lov_del_target(obd, index, &obd_uuid, gen);                GOTO(out, rc);        }        case LCFG_PARAM: {                struct lprocfs_static_vars lvars = { 0 };                struct lov_desc *desc = &(obd->u.lov.desc);                                if (!desc)                        GOTO(out, rc = -EINVAL);                                lprocfs_lov_init_vars(&lvars);                                rc = class_process_proc_param(PARAM_LOV, lvars.obd_vars,                                              lcfg, obd);                GOTO(out, rc);        }        default: {                CERROR("Unknown command: %d\n", lcfg->lcfg_command);                GOTO(out, rc = -EINVAL);        }        }out:        RETURN(rc);}#ifndef log2#define log2(n) ffz(~(n))#endifstatic int lov_clear_orphans(struct obd_export *export, struct obdo *src_oa,                             struct lov_stripe_md **ea,                             struct obd_trans_info *oti){        struct lov_obd *lov;        struct obdo *tmp_oa;        struct obd_uuid *ost_uuid = NULL;        int rc = 0, i;        ENTRY;        LASSERT(src_oa->o_valid & OBD_MD_FLFLAGS &&                src_oa->o_flags == OBD_FL_DELORPHAN);        lov = &export->exp_obd->u.lov;        OBDO_ALLOC(tmp_oa);        if (tmp_oa == NULL)                RETURN(-ENOMEM);        if (oti->oti_ost_uuid) {                ost_uuid = oti->oti_ost_uuid;                CDEBUG(D_HA, "clearing orphans only for %s\n",                       ost_uuid->uuid);        }        lov_getref(export->exp_obd);        for (i = 0; i < lov->desc.ld_tgt_count; i++) {                struct lov_stripe_md obj_md;                struct lov_stripe_md *obj_mdp = &obj_md;                struct lov_tgt_desc *tgt;                int err;                tgt = lov->lov_tgts[i];                if (!tgt)                        continue;                /* if called for a specific target, we don't                   care if it is not active. */                if (!lov->lov_tgts[i]->ltd_active && ost_uuid == NULL) {                        CDEBUG(D_HA, "lov idx %d inactive\n", i);                        continue;                }                if (ost_uuid && !obd_uuid_equals(ost_uuid, &tgt->ltd_uuid))                        continue;                CDEBUG(D_CONFIG,"Clear orphans for %d:%s\n", i,                        obd_uuid2str(ost_uuid));                memcpy(tmp_oa, src_oa, sizeof(*tmp_oa));                LASSERT(lov->lov_tgts[i]->ltd_exp);                /* XXX: LOV STACKING: use real "obj_mdp" sub-data */                err = obd_create(lov->lov_tgts[i]->ltd_exp,                                  tmp_oa, &obj_mdp, oti);                if (err)                        /* This export will be disabled until it is recovered,                           and then orphan recovery will be completed. */                        CERROR("error in orphan recovery on OST idx %d/%d: "                               "rc = %d\n", i, lov->desc.ld_tgt_count, err);                if (ost_uuid)                        break;        }        lov_putref(export->exp_obd);        OBDO_FREE(tmp_oa);        RETURN(rc);}static int lov_recreate(struct obd_export *exp, struct obdo *src_oa,                        struct lov_stripe_md **ea, struct obd_trans_info *oti){        struct lov_stripe_md *obj_mdp, *lsm;        struct lov_obd *lov = &exp->exp_obd->u.lov;        unsigned ost_idx;        int rc, i;        ENTRY;        LASSERT(src_oa->o_valid & OBD_MD_FLFLAGS &&                src_oa->o_flags & OBD_FL_RECREATE_OBJS);        OBD_ALLOC(obj_mdp, sizeof(*obj_mdp));        if (obj_mdp == NULL)                RETURN(-ENOMEM);        ost_idx = src_oa->o_nlink;        lsm = *ea;        if (lsm == NULL)                GOTO(out, rc = -EINVAL);        if (ost_idx >= lov->desc.ld_tgt_count ||            !lov->lov_tgts[ost_idx])                GOTO(out, rc = -EINVAL);        for (i = 0; i < lsm->lsm_stripe_count; i++) {                if (lsm->lsm_oinfo[i]->loi_ost_idx == ost_idx) {                        if (lsm->lsm_oinfo[i]->loi_id != src_oa->o_id)                                GOTO(out, rc = -EINVAL);                        break;                }        }        if (i == lsm->lsm_stripe_count)                GOTO(out, rc = -EINVAL);        rc = obd_create(lov->lov_tgts[ost_idx]->ltd_exp, src_oa, &obj_mdp, oti);out:        OBD_FREE(obj_mdp, sizeof(*obj_mdp));        RETURN(rc);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?