lov_obd.c

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

C
1,866
字号
                lovset->set_completes = 0;        err = lov_fini_punch_set(lovset);        RETURN(rc ? rc : err);}/* FIXME: maybe we'll just make one node the authoritative attribute node, then * we can send this 'punch' to just the authoritative node and the nodes * that the punch will affect. */static int lov_punch(struct obd_export *exp, struct obd_info *oinfo,                     struct obd_trans_info *oti,                     struct ptlrpc_request_set *rqset){        struct lov_request_set *set;        struct lov_obd *lov;        struct list_head *pos;        struct lov_request *req;        int rc = 0;        ENTRY;        LASSERT(oinfo);        ASSERT_LSM_MAGIC(oinfo->oi_md);        if (!exp || !exp->exp_obd)                RETURN(-ENODEV);        lov = &exp->exp_obd->u.lov;        rc = lov_prep_punch_set(exp, oinfo, oti, &set);        if (rc)                RETURN(rc);        list_for_each (pos, &set->set_list) {                req = list_entry(pos, struct lov_request, rq_link);                rc = obd_punch(lov->lov_tgts[req->rq_idx]->ltd_exp,                               &req->rq_oi, NULL, rqset);                if (rc) {                        CERROR("error: punch objid "LPX64" subobj "LPX64                               " on OST idx %d: rc = %d\n",                               set->set_oi->oi_oa->o_id,                               req->rq_oi.oi_oa->o_id, req->rq_idx, rc);                        break;                }        }        if (rc || list_empty(&rqset->set_requests)) {                int err;                err = lov_fini_punch_set(set);                RETURN(rc ? rc : err);        }        LASSERT(rqset->set_interpret == NULL);        rqset->set_interpret = lov_punch_interpret;        rqset->set_arg = (void *)set;        RETURN(0);}static int lov_sync(struct obd_export *exp, struct obdo *oa,                    struct lov_stripe_md *lsm, obd_off start, obd_off end){        struct lov_request_set *set;        struct obd_info oinfo;        struct lov_obd *lov;        struct list_head *pos;        struct lov_request *req;        int err = 0, rc = 0;        ENTRY;        ASSERT_LSM_MAGIC(lsm);        if (!exp->exp_obd)                RETURN(-ENODEV);        lov = &exp->exp_obd->u.lov;        rc = lov_prep_sync_set(exp, &oinfo, oa, lsm, start, end, &set);        if (rc)                RETURN(rc);        list_for_each (pos, &set->set_list) {                req = list_entry(pos, struct lov_request, rq_link);                rc = obd_sync(lov->lov_tgts[req->rq_idx]->ltd_exp,                               req->rq_oi.oi_oa, NULL,                               req->rq_oi.oi_policy.l_extent.start,                              req->rq_oi.oi_policy.l_extent.end);                err = lov_update_common_set(set, req, rc);                if (err) {                        CERROR("error: fsync objid "LPX64" subobj "LPX64                               " on OST idx %d: rc = %d\n",                               set->set_oi->oi_oa->o_id,                               req->rq_oi.oi_oa->o_id, req->rq_idx, rc);                        if (!rc)                                rc = err;                }        }        err = lov_fini_sync_set(set);        if (!rc)                rc = err;        RETURN(rc);}static int lov_brw_check(struct lov_obd *lov, struct obd_info *lov_oinfo,                         obd_count oa_bufs, struct brw_page *pga){        struct obd_info oinfo = { { { 0 } } };        int i, rc = 0;        oinfo.oi_oa = lov_oinfo->oi_oa;        /* The caller just wants to know if there's a chance that this         * I/O can succeed */        for (i = 0; i < oa_bufs; i++) {                int stripe = lov_stripe_number(lov_oinfo->oi_md, pga[i].off);                int ost = lov_oinfo->oi_md->lsm_oinfo[stripe]->loi_ost_idx;                obd_off start, end;                if (!lov_stripe_intersects(lov_oinfo->oi_md, i, pga[i].off,                                           pga[i].off + pga[i].count,                                           &start, &end))                        continue;                if (!lov->lov_tgts[ost] || !lov->lov_tgts[ost]->ltd_active) {                        CDEBUG(D_HA, "lov idx %d inactive\n", ost);                        return -EIO;                }                rc = obd_brw(OBD_BRW_CHECK, lov->lov_tgts[ost]->ltd_exp, &oinfo,                             1, &pga[i], NULL);                if (rc)                        break;        }        return rc;}static int lov_brw(int cmd, struct obd_export *exp, struct obd_info *oinfo,                   obd_count oa_bufs, struct brw_page *pga,                   struct obd_trans_info *oti){        struct lov_request_set *set;        struct lov_request *req;        struct list_head *pos;        struct lov_obd *lov = &exp->exp_obd->u.lov;        int err, rc = 0;        ENTRY;        ASSERT_LSM_MAGIC(oinfo->oi_md);        if (cmd == OBD_BRW_CHECK) {                rc = lov_brw_check(lov, oinfo, oa_bufs, pga);                RETURN(rc);        }        rc = lov_prep_brw_set(exp, oinfo, oa_bufs, pga, oti, &set);        if (rc)                RETURN(rc);        list_for_each (pos, &set->set_list) {                struct obd_export *sub_exp;                struct brw_page *sub_pga;                req = list_entry(pos, struct lov_request, rq_link);                sub_exp = lov->lov_tgts[req->rq_idx]->ltd_exp;                sub_pga = set->set_pga + req->rq_pgaidx;                rc = obd_brw(cmd, sub_exp, &req->rq_oi, req->rq_oabufs,                             sub_pga, oti);                if (rc)                        break;                lov_update_common_set(set, req, rc);        }        err = lov_fini_brw_set(set);        if (!rc)                rc = err;        RETURN(rc);}static int lov_brw_interpret(struct ptlrpc_request_set *reqset, void *data,                             int rc){        struct lov_request_set *lovset = (struct lov_request_set *)data;        ENTRY;        if (rc) {                lovset->set_completes = 0;                lov_fini_brw_set(lovset);        } else {                rc = lov_fini_brw_set(lovset);        }        RETURN(rc);}static int lov_brw_async(int cmd, struct obd_export *exp,                         struct obd_info *oinfo, obd_count oa_bufs,                         struct brw_page *pga, struct obd_trans_info *oti,                         struct ptlrpc_request_set *set){        struct lov_request_set *lovset;        struct lov_request *req;        struct list_head *pos;        struct lov_obd *lov = &exp->exp_obd->u.lov;        int rc = 0;        ENTRY;        LASSERT(oinfo);        ASSERT_LSM_MAGIC(oinfo->oi_md);        if (cmd == OBD_BRW_CHECK) {                rc = lov_brw_check(lov, oinfo, oa_bufs, pga);                RETURN(rc);        }        rc = lov_prep_brw_set(exp, oinfo, oa_bufs, pga, oti, &lovset);        if (rc)                RETURN(rc);        list_for_each (pos, &lovset->set_list) {                struct obd_export *sub_exp;                struct brw_page *sub_pga;                req = list_entry(pos, struct lov_request, rq_link);                sub_exp = lov->lov_tgts[req->rq_idx]->ltd_exp;                sub_pga = lovset->set_pga + req->rq_pgaidx;                rc = obd_brw_async(cmd, sub_exp, &req->rq_oi, req->rq_oabufs,                                   sub_pga, oti, set);                if (rc)                        GOTO(out, rc);                lov_update_common_set(lovset, req, rc);        }        LASSERT(rc == 0);        LASSERT(set->set_interpret == NULL);        LASSERT(set->set_arg == NULL);        rc = ptlrpc_set_add_cb(set, lov_brw_interpret, lovset);        if (rc)                GOTO(out, rc);        RETURN(rc);out:        lov_fini_brw_set(lovset);        RETURN(rc);}static int lov_ap_make_ready(void *data, int cmd){        struct lov_async_page *lap = LAP_FROM_COOKIE(data);        return lap->lap_caller_ops->ap_make_ready(lap->lap_caller_data, cmd);}static int lov_ap_refresh_count(void *data, int cmd){        struct lov_async_page *lap = LAP_FROM_COOKIE(data);        return lap->lap_caller_ops->ap_refresh_count(lap->lap_caller_data,                                                     cmd);}static void lov_ap_fill_obdo(void *data, int cmd, struct obdo *oa){        struct lov_async_page *lap = LAP_FROM_COOKIE(data);        lap->lap_caller_ops->ap_fill_obdo(lap->lap_caller_data, cmd, oa);        /* XXX woah, shouldn't we be altering more here?  size? */        oa->o_id = lap->lap_loi_id;        oa->o_stripe_idx = lap->lap_stripe;}static void lov_ap_update_obdo(void *data, int cmd, struct obdo *oa,                               obd_valid valid){        struct lov_async_page *lap = LAP_FROM_COOKIE(data);        lap->lap_caller_ops->ap_update_obdo(lap->lap_caller_data, cmd,oa,valid);}static int lov_ap_completion(void *data, int cmd, struct obdo *oa, int rc){        struct lov_async_page *lap = LAP_FROM_COOKIE(data);        /* in a raid1 regime this would down a count of many ios         * in flight, onl calling the caller_ops completion when all         * the raid1 ios are complete */        rc = lap->lap_caller_ops->ap_completion(lap->lap_caller_data,cmd,oa,rc);        return rc;}static struct obd_async_page_ops lov_async_page_ops = {        .ap_make_ready =        lov_ap_make_ready,        .ap_refresh_count =     lov_ap_refresh_count,        .ap_fill_obdo =         lov_ap_fill_obdo,        .ap_update_obdo =       lov_ap_update_obdo,        .ap_completion =        lov_ap_completion,};int lov_prep_async_page(struct obd_export *exp, struct lov_stripe_md *lsm,                           struct lov_oinfo *loi, cfs_page_t *page,                           obd_off offset, struct obd_async_page_ops *ops,                           void *data, void **res, int nocache,                           struct lustre_handle *lockh){        struct lov_obd *lov = &exp->exp_obd->u.lov;        struct lov_async_page *lap;        struct lov_lock_handles *lov_lockh = NULL;        int rc = 0;        ENTRY;        if (!page) {                int i = 0;                /* Find an existing osc so we can get it's stupid sizeof(*oap).                   Only because of this layering limitation will a client                    mount with no osts fail */                while (!lov->lov_tgts || !lov->lov_tgts[i] ||                        !lov->lov_tgts[i]->ltd_exp) {                        i++;                        if (i >= lov->desc.ld_tgt_count)                                 RETURN(-ENOMEDIUM);                }                rc = size_round(sizeof(*lap)) +                        obd_prep_async_page(lov->lov_tgts[i]->ltd_exp, NULL,                                            NULL, NULL, 0, NULL, NULL, NULL, 0,                                            NULL);                RETURN(rc);        }        ASSERT_LSM_MAGIC(lsm);        LASSERT(loi == NULL);        lap = *res;        lap->lap_magic = LOV_AP_MAGIC;        lap->lap_caller_ops = ops;        lap->lap_caller_data = data;        /* for now only raid 0 which passes through */        lap->lap_stripe = lov_stripe_number(lsm, offset);        lov_stripe_offset(lsm, offset, lap->lap_stripe, &lap->lap_sub_offset);        loi = lsm->lsm_oinfo[lap->lap_stripe];        /* so the callback doesn't need the lsm */        lap->lap_loi_id = loi->loi_id;        lap->lap_sub_cookie = (void *)lap + size_round(sizeof(*lap));        if (lockh) {                lov_lockh = lov_handle2llh(lockh);                if (lov_lockh) {                        lockh = lov_lockh->llh_handles + lap->lap_stripe;                }        }        rc = obd_prep_async_page(lov->lov_tgts[loi->loi_ost_idx]->ltd_exp,                                 lsm, loi, page, lap->lap_sub_offset,                                 &lov_async_page_ops, lap,                                 &lap->lap_sub_cookie, nocache, lockh);        if (lov_lockh)                lov_llh_put(lov_lockh);        if (rc)                RETURN(rc);        CDEBUG(D_CACHE, "lap %p page %p cookie %p off "LPU64"\n", lap, page,               lap->lap_sub_cookie, offset);        RETURN(0);}static int lov_queue_async_io(struct obd_export *exp,                              struct lov_stripe_md *lsm,                              struct lov_oinfo *loi, void *cookie,                              int cmd, obd_off off, int count,                              obd_flag brw_flags, obd_flag async_flags){        struct lov_obd *lov = &exp->exp_obd->u.lov;        struct lov_async_page *lap;     

⌨️ 快捷键说明

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