From fa795c24f4593e5b974f2ce4e29629cad3a54768 Mon Sep 17 00:00:00 2001 From: wangdi Date: Fri, 29 Sep 2006 09:41:33 +0000 Subject: [PATCH] Branch: b_new_cmd refine mdd credits calculation --- lustre/include/dt_object.h | 5 + lustre/include/lu_object.h | 10 ++ lustre/mdd/mdd_handler.c | 270 ++++++++++++++++++++++++++++----------------- lustre/mdd/mdd_internal.h | 2 + lustre/mdd/mdd_lov.c | 6 +- lustre/osd/osd_handler.c | 56 +++++++++- 6 files changed, 243 insertions(+), 106 deletions(-) diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h index d3d6855..639b865 100644 --- a/lustre/include/dt_object.h +++ b/lustre/include/dt_object.h @@ -96,6 +96,11 @@ struct dt_device_operations { int (*dt_sync)(const struct lu_env *env, struct dt_device *dev); void (*dt_ro)(const struct lu_env *env, struct dt_device *dev); + /* + * dt get credits from osd + */ + int (*dt_credit_get)(const struct lu_env *env, struct dt_device *dev, + int op); }; struct dt_index_features { diff --git a/lustre/include/lu_object.h b/lustre/include/lu_object.h index f74f93f..105154c 100644 --- a/lustre/include/lu_object.h +++ b/lustre/include/lu_object.h @@ -1052,4 +1052,14 @@ int lu_global_init(void); */ void lu_global_fini(void); +/* + * Basic transaction credit op + */ +enum lu_txn_op { + INSERT_IAM = 0, + CREATE_OBJECT = 1, + XATTR_SET = 2, + LOG_REC = 3, + ATTR_SET = 4 +}; #endif /* __LUSTRE_LU_OBJECT_H */ diff --git a/lustre/mdd/mdd_handler.c b/lustre/mdd/mdd_handler.c index 003eb75..2eb14fe 100644 --- a/lustre/mdd/mdd_handler.c +++ b/lustre/mdd/mdd_handler.c @@ -89,6 +89,7 @@ enum mdd_txn_op { MDD_TXN_LINK_OP, MDD_TXN_UNLINK_OP, MDD_TXN_RENAME_OP, + MDD_TXN_RENAME_TGT_OP, MDD_TXN_CREATE_DATA_OP, MDD_TXN_MKDIR_OP }; @@ -98,83 +99,22 @@ struct mdd_txn_op_descr { unsigned int mod_credits; }; -/* Calculate the credits of each transaction here */ -/* Note: we did not count into QUOTA here, If we mount with --data_journal - * we may need more*/ enum { -/* Insert/Delete IAM - * EXT3_INDEX_EXTRA_TRANS_BLOCKS(8) + EXT3_SINGLEDATA_TRANS_BLOCKS 8 - * XXX Note: maybe iam need more,since iam have more level than Ext3 htree - */ - INSERT_IAM_CREDITS = 16, - -/* Insert/Delete Oi - * same as IAM insert/delete 16 - * */ - INSERT_OI_CREDITS = 16, - -/* Create a object - * Same as create object in Ext3 filesystem, but did not count QUOTA i - * EXT3_DATA_TRANS_BLOCKS(12) + INDEX_EXTRA_BLOCKS(8) + - * 3(inode bits,groups, GDT)*/ - CREATE_OBJECT_CREDITS = 23, - -/* XATTR_SET - * SAME AS XATTR of EXT3 EXT3_DATA_TRANS_BLOCKS - * XXX Note: in original MDS implmentation EXT3_INDEX_EXTRA_TRANS_BLOCKS are - * also counted in. Do not know why? */ - XATTR_SET_CREDITS = 12, - - /* A log rec need EXT3_INDEX_EXTRA_TRANS_BLOCKS(8) + - * EXT3_SINGLEDATA_TRANS_BLOCKS(8)) - */ - LOG_REC_CREDIT = 16 -}; - -/* XXX we should know the ost count to calculate the llog */ -#define DEFAULT_LSM_COUNT 4 /* FIXME later */ -enum { - MDD_TXN_OBJECT_DESTROY_CREDITS = 20, - /* OBJECT CREATE :OI_INSERT + CREATE */ - MDD_TXN_OBJECT_CREATE_CREDITS = (INSERT_OI_CREDITS + \ - CREATE_OBJECT_CREDITS), - /* ATTR SET: XATTR_SET + ATTR set(3)*/ - MDD_TXN_ATTR_SET_CREDITS = (XATTR_SET_CREDITS + 3), - - MDD_TXN_XATTR_SET_CREDITS = XATTR_SET_CREDITS, - - MDD_TXN_INDEX_INSERT_CREDITS = INSERT_IAM_CREDITS, - MDD_TXN_INDEX_DELETE_CREDITS = INSERT_IAM_CREDITS, - MDD_TXN_LINK_CREDITS = INSERT_IAM_CREDITS, - -/* - * UNLINK CREDITS - * IAM_INSERT_CREDITS + UNLINK log - * Unlink log = ((EXT3_INDEX_EXTRA_TRANS_BLOCKS(8) + - * EXT3_SINGLEDATA_TRANS_BLOCKS(8)) * lsm stripe count - * XXX we should know the ost count to calculate the llog - */ - MDD_TXN_UNLINK_CREDITS = (INSERT_IAM_CREDITS + - LOG_REC_CREDIT*DEFAULT_LSM_COUNT), -/* - * RENAME CREDITS - * 2 IAM_INSERT + 1 IAM_DELETE + UNLINK LOG - */ - MDD_TXN_RENAME_CREDITS = (3 * INSERT_IAM_CREDITS + \ - LOG_REC_CREDIT * DEFAULT_LSM_COUNT), -/* CREATE_DATA CREDITS - * SET_XATTR - * */ - MDD_TXN_CREATE_DATA_CREDITS = XATTR_SET_CREDITS, -/* CREATE - * IAM_INSERT + OI_INSERT + CREATE_OBJECT_CREDITS - * SET_MD CREDITS is already counted in CREATE_OBJECT CREDITS */ - MDD_TXN_MKDIR_CREDITS = (INSERT_IAM_CREDITS + INSERT_OI_CREDITS \ - + CREATE_OBJECT_CREDITS) + MDD_TXN_OBJECT_DESTROY_CREDITS = 0, + MDD_TXN_OBJECT_CREATE_CREDITS = 0, + MDD_TXN_ATTR_SET_CREDITS = 0, + MDD_TXN_XATTR_SET_CREDITS = 0, + MDD_TXN_INDEX_INSERT_CREDITS = 0, + MDD_TXN_INDEX_DELETE_CREDITS = 0, + MDD_TXN_LINK_CREDITS = 0, + MDD_TXN_UNLINK_CREDITS = 0, + MDD_TXN_RENAME_CREDITS = 0, + MDD_TXN_RENAME_TGT_CREDITS = 0, + MDD_TXN_CREATE_DATA_CREDITS = 0, + MDD_TXN_MKDIR_CREDITS = 0 }; - -#define DEFINE_MDD_TXN_OP_DESC(opname) \ -static const struct mdd_txn_op_descr opname = { \ +#define DEFINE_MDD_TXN_OP_ARRAY(opname, base) \ +[opname ## _OP - base ## _OP]= { \ .mod_op = opname ## _OP, \ .mod_credits = opname ## _CREDITS, \ } @@ -183,22 +123,142 @@ static const struct mdd_txn_op_descr opname = { \ * number of blocks to reserve for particular operations. Should be function * of ... something. Stub for now. */ -DEFINE_MDD_TXN_OP_DESC(MDD_TXN_OBJECT_DESTROY); -DEFINE_MDD_TXN_OP_DESC(MDD_TXN_OBJECT_CREATE); -DEFINE_MDD_TXN_OP_DESC(MDD_TXN_ATTR_SET); -DEFINE_MDD_TXN_OP_DESC(MDD_TXN_XATTR_SET); -DEFINE_MDD_TXN_OP_DESC(MDD_TXN_INDEX_INSERT); -DEFINE_MDD_TXN_OP_DESC(MDD_TXN_INDEX_DELETE); -DEFINE_MDD_TXN_OP_DESC(MDD_TXN_LINK); -DEFINE_MDD_TXN_OP_DESC(MDD_TXN_UNLINK); -DEFINE_MDD_TXN_OP_DESC(MDD_TXN_RENAME); -DEFINE_MDD_TXN_OP_DESC(MDD_TXN_CREATE_DATA); -DEFINE_MDD_TXN_OP_DESC(MDD_TXN_MKDIR); -static void mdd_txn_param_build(const struct lu_env *env, - const struct mdd_txn_op_descr *opd) +#define DEFINE_MDD_TXN_OP_DESC(opname) \ + DEFINE_MDD_TXN_OP_ARRAY(opname, MDD_TXN_OBJECT_DESTROY) + +static struct mdd_txn_op_descr mdd_txn_descrs[] = { + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_OBJECT_DESTROY), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_OBJECT_CREATE), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_ATTR_SET), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_XATTR_SET), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_INDEX_INSERT), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_INDEX_DELETE), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_LINK), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_UNLINK), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_RENAME), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_RENAME_TGT), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_CREATE_DATA), + DEFINE_MDD_TXN_OP_DESC(MDD_TXN_MKDIR) +}; +struct rw_semaphore mdd_txn_sem; + +static void mdd_txn_param_build(const struct lu_env *env, int op) { - mdd_env_info(env)->mti_param.tp_credits = opd->mod_credits; + int num_entries, i; + /* init credits for each ops */ + num_entries = sizeof (mdd_txn_descrs) / sizeof(struct mdd_txn_op_descr); + + LASSERT(num_entries > 0); + + down_read(&mdd_txn_sem); + for (i =0; i < num_entries; i++) { + if (mdd_txn_descrs[i].mod_op == op) { + LASSERT(mdd_txn_descrs[i].mod_credits > 0); + mdd_env_info(env)->mti_param.tp_credits = + mdd_txn_descrs[i].mod_credits; + up_read(&mdd_txn_sem); + return; + } + } + up_read(&mdd_txn_sem); + CERROR("Wrong operation %d \n", op); + LBUG(); +} + +static int mdd_credit_get(const struct lu_env *env, struct mdd_device *mdd, + int op) +{ + int credits; + credits = mdd_child_ops(mdd)->dt_credit_get(env, mdd->mdd_child, + op); + LASSERT(credits > 0); + return credits; +} + +/* FIXME: we should calculate it by lsm count, + * not ost count */ +int mdd_init_txn_credits(const struct lu_env *env, struct mdd_device *mdd) +{ + struct mds_obd *mds = &mdd->mdd_obd_dev->u.mds; + int ost_count = mds->mds_lov_desc.ld_tgt_count; + int iam_credits, xattr_credits, log_credits, create_credits; + int num_entries, i, attr_credits; + + /* init credits for each ops */ + num_entries = sizeof (mdd_txn_descrs) / sizeof(struct mdd_txn_op_descr); + LASSERT(num_entries > 0); + + /* init the basic credits from osd layer */ + iam_credits = mdd_credit_get(env, mdd, INSERT_IAM); + log_credits = mdd_credit_get(env, mdd, LOG_REC); + attr_credits = mdd_credit_get(env, mdd, ATTR_SET); + xattr_credits = mdd_credit_get(env, mdd, XATTR_SET); + create_credits = mdd_credit_get(env, mdd, CREATE_OBJECT); + /* calculate the mdd credits */ + down_write(&mdd_txn_sem); + for (i =0; i < num_entries; i++) { + int opcode = mdd_txn_descrs[i].mod_op; + switch(opcode) { + case MDD_TXN_OBJECT_DESTROY_OP: + mdd_txn_descrs[i].mod_credits = 20; + break; + case MDD_TXN_OBJECT_CREATE_OP: + /* OI_INSERT + CREATE OBJECT */ + mdd_txn_descrs[i].mod_credits = + iam_credits + create_credits; + break; + case MDD_TXN_ATTR_SET_OP: + /* ATTR set + XATTR(lsm, lmv) set */ + mdd_txn_descrs[i].mod_credits = + attr_credits + xattr_credits; + break; + case MDD_TXN_XATTR_SET_OP: + mdd_txn_descrs[i].mod_credits = xattr_credits; + break; + case MDD_TXN_INDEX_INSERT_OP: + mdd_txn_descrs[i].mod_credits = iam_credits; + break; + case MDD_TXN_INDEX_DELETE_OP: + mdd_txn_descrs[i].mod_credits = iam_credits; + break; + case MDD_TXN_LINK_OP: + mdd_txn_descrs[i].mod_credits = iam_credits; + break; + case MDD_TXN_UNLINK_OP: + /* delete IAM + Unlink log */ + mdd_txn_descrs[i].mod_credits = + iam_credits + log_credits * ost_count; + break; + case MDD_TXN_RENAME_OP: + /* 2 delete IAM + 1 insert + Unlink log */ + mdd_txn_descrs[i].mod_credits = + 3 * iam_credits + log_credits * ost_count; + break; + case MDD_TXN_RENAME_TGT_OP: + /* iam insert + iam delete */ + mdd_txn_descrs[i].mod_credits = 2 * iam_credits; + break; + case MDD_TXN_CREATE_DATA_OP: + /* same as set xattr(lsm) */ + mdd_txn_descrs[i].mod_credits = xattr_credits; + break; + case MDD_TXN_MKDIR_OP: + /* IAM_INSERT + OI_INSERT + CREATE_OBJECT_CREDITS + * SET_MD CREDITS is already counted in + * CREATE_OBJECT CREDITS + */ + mdd_txn_descrs[i].mod_credits = + 2 * iam_credits + create_credits; + break; + default: + CERROR("invalid op %d init its credit\n", opcode); + up_write(&mdd_txn_sem); + LBUG(); + } + } + up_write(&mdd_txn_sem); + RETURN(0); } struct lu_buf *mdd_buf_get(const struct lu_env *env, void *area, ssize_t len) @@ -378,7 +438,7 @@ static void mdd_object_delete(const struct lu_env *env, return; if (test_bit(LU_OBJECT_ORPHAN, &o->lo_header->loh_flags)) { - mdd_txn_param_build(env, &MDD_TXN_MKDIR); + mdd_txn_param_build(env, MDD_TXN_MKDIR_OP); handle = mdd_trans_start(env, lu2mdd_dev(o->lo_dev)); if (IS_ERR(handle)) CERROR("Cannot get thandle\n"); @@ -781,6 +841,8 @@ static int mdd_device_init(const struct lu_env *env, mdd->mdd_txn_cb.dtc_txn_commit = mdd_txn_commit_cb; mdd->mdd_txn_cb.dtc_cookie = mdd; + /* init txn credits */ + init_rwsem(&mdd_txn_sem); RETURN(rc); } @@ -1204,7 +1266,7 @@ static int mdd_attr_set(const struct lu_env *env, struct md_object *obj, struct lu_attr *la_copy = &mdd_env_info(env)->mti_la_for_fix; ENTRY; - mdd_txn_param_build(env, &MDD_TXN_ATTR_SET); + mdd_txn_param_build(env, MDD_TXN_ATTR_SET_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); @@ -1323,7 +1385,7 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj, if (rc) RETURN(rc); - mdd_txn_param_build(env, &MDD_TXN_XATTR_SET); + mdd_txn_param_build(env, MDD_TXN_XATTR_SET_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); @@ -1371,7 +1433,7 @@ int mdd_xattr_del(const struct lu_env *env, struct md_object *obj, if (rc) RETURN(rc); - mdd_txn_param_build(env, &MDD_TXN_XATTR_SET); + mdd_txn_param_build(env, MDD_TXN_XATTR_SET_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); @@ -1484,7 +1546,7 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj, int rc; ENTRY; - mdd_txn_param_build(env, &MDD_TXN_LINK); + mdd_txn_param_build(env, MDD_TXN_LINK_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); @@ -1638,7 +1700,7 @@ static int mdd_unlink(const struct lu_env *env, int rc; ENTRY; - mdd_txn_param_build(env, &MDD_TXN_UNLINK); + mdd_txn_param_build(env, MDD_TXN_UNLINK_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); @@ -1695,7 +1757,7 @@ static int mdd_ref_del(const struct lu_env *env, struct md_object *obj, int rc; ENTRY; - mdd_txn_param_build(env, &MDD_TXN_XATTR_SET); + mdd_txn_param_build(env, MDD_TXN_XATTR_SET_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(-ENOMEM); @@ -1904,7 +1966,7 @@ static int mdd_rename(const struct lu_env *env, if (rc) GOTO(out, rc); - mdd_txn_param_build(env, &MDD_TXN_RENAME); + mdd_txn_param_build(env, MDD_TXN_RENAME_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) GOTO(out, rc = PTR_ERR(handle)); @@ -2148,7 +2210,7 @@ static int mdd_create_data(const struct lu_env *env, if (rc) RETURN(rc); - mdd_txn_param_build(env, &MDD_TXN_CREATE_DATA); + mdd_txn_param_build(env, MDD_TXN_CREATE_DATA_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(rc = PTR_ERR(handle)); @@ -2262,7 +2324,7 @@ static int mdd_create(const struct lu_env *env, RETURN(rc); } - mdd_txn_param_build(env, &MDD_TXN_MKDIR); + mdd_txn_param_build(env, MDD_TXN_MKDIR_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); @@ -2444,7 +2506,7 @@ static int mdd_object_create(const struct lu_env *env, if (rc) RETURN(rc); - mdd_txn_param_build(env, &MDD_TXN_OBJECT_CREATE); + mdd_txn_param_build(env, MDD_TXN_OBJECT_CREATE_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); @@ -2508,7 +2570,7 @@ static int mdd_name_insert(const struct lu_env *env, int rc; ENTRY; - mdd_txn_param_build(env, &MDD_TXN_INDEX_INSERT); + mdd_txn_param_build(env, MDD_TXN_INDEX_INSERT_OP); handle = mdd_trans_start(env, mdo2mdd(pobj)); if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); @@ -2559,7 +2621,7 @@ static int mdd_name_remove(const struct lu_env *env, int rc; ENTRY; - mdd_txn_param_build(env, &MDD_TXN_INDEX_DELETE); + mdd_txn_param_build(env, MDD_TXN_INDEX_DELETE_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); @@ -2621,7 +2683,7 @@ static int mdd_rename_tgt(const struct lu_env *env, int rc; ENTRY; - mdd_txn_param_build(env, &MDD_TXN_RENAME); + mdd_txn_param_build(env, MDD_TXN_RENAME_TGT_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); @@ -2749,7 +2811,7 @@ static int mdd_ref_add(const struct lu_env *env, struct thandle *handle; ENTRY; - mdd_txn_param_build(env, &MDD_TXN_XATTR_SET); + mdd_txn_param_build(env, MDD_TXN_XATTR_SET_OP); handle = mdd_trans_start(env, mdd); if (IS_ERR(handle)) RETURN(-ENOMEM); diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index 11742e4..6c43c20 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -140,6 +140,8 @@ int __mdd_object_kill(const struct lu_env *, struct mdd_object *, struct mdd_object *mdd_object_find(const struct lu_env *, struct mdd_device *, const struct lu_fid *); +int mdd_init_txn_credits(const struct lu_env *env, struct mdd_device *mdd); + static inline void mdd_object_put(const struct lu_env *env, struct mdd_object *o) { diff --git a/lustre/mdd/mdd_lov.c b/lustre/mdd/mdd_lov.c index 48a28ab..a5474e9 100644 --- a/lustre/mdd/mdd_lov.c +++ b/lustre/mdd/mdd_lov.c @@ -60,7 +60,11 @@ static int mdd_lov_update(struct obd_device *host, upcall_dev = mdd->mdd_md_dev.md_upcall.mu_upcall_dev; rc = upcall_dev->md_upcall.mu_upcall(NULL, upcall_dev, MD_LOV_SYNC); - + if (rc) + RETURN(rc); + + rc = mdd_init_txn_credits(NULL, mdd); + RETURN(rc); } diff --git a/lustre/osd/osd_handler.c b/lustre/osd/osd_handler.c index 7aad5d2..a0cae5d 100644 --- a/lustre/osd/osd_handler.c +++ b/lustre/osd/osd_handler.c @@ -666,6 +666,59 @@ static void osd_ro(const struct lu_env *env, struct dt_device *d) EXIT; } +/* Note: we did not count into QUOTA here, If we mount with --data_journal + * we may need more*/ +enum { + /* Insert/Delete IAM + * EXT3_INDEX_EXTRA_TRANS_BLOCKS(8) + EXT3_SINGLEDATA_TRANS_BLOCKS 8 + * XXX Note: maybe iam need more,since iam have more level than Ext3 + * htree + */ + INSERT_IAM_CREDITS = 16, + + /* Create a object + * Same as create object in Ext3 filesystem, but did not count QUOTA i + * EXT3_DATA_TRANS_BLOCKS(12) + INDEX_EXTRA_BLOCKS(8) + + * 3(inode bits,groups, GDT)*/ + CREATE_OBJECT_CREDITS = 23, + + /* XATTR_SET + * SAME AS XATTR of EXT3 EXT3_DATA_TRANS_BLOCKS + * XXX Note: in original MDS implmentation EXT3_INDEX_EXTRA_TRANS_BLOCKS are + * also counted in. Do not know why? */ + XATTR_SET_CREDITS = 12, + + /* A log rec need EXT3_INDEX_EXTRA_TRANS_BLOCKS(8) + + * EXT3_SINGLEDATA_TRANS_BLOCKS(8)) + */ + LOG_REC_CREDIT = 16, + + /* Attr set credits 3 inode, group, GDT */ + ATTR_SET_CREDITS = 3 +}; + +static int osd_credit_get(const struct lu_env *env, struct dt_device *d, + int op) +{ + switch(op) { + case INSERT_IAM: + return INSERT_IAM_CREDITS; + case CREATE_OBJECT: + return CREATE_OBJECT_CREDITS; + case XATTR_SET: + return XATTR_SET_CREDITS; + case LOG_REC: + return LOG_REC_CREDIT; + case ATTR_SET: + return ATTR_SET_CREDITS; + default: + CERROR("Not recorgonized op %d", op); + LBUG(); + return -EINVAL; + } + return (-EINVAL); +} + static struct dt_device_operations osd_dt_ops = { .dt_root_get = osd_root_get, .dt_statfs = osd_statfs, @@ -673,7 +726,8 @@ static struct dt_device_operations osd_dt_ops = { .dt_trans_stop = osd_trans_stop, .dt_conf_get = osd_conf_get, .dt_sync = osd_sync, - .dt_ro = osd_ro + .dt_ro = osd_ro, + .dt_credit_get = osd_credit_get }; static void osd_object_read_lock(const struct lu_env *env, -- 1.8.3.1