Motr  M0
cm.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_DIXCM
24 #include "lib/memory.h"
25 #include "lib/assert.h"
26 #include "lib/errno.h"
27 #include "lib/trace.h"
28 #include "lib/chan.h"
29 
30 #include "conf/helpers.h" /* m0_conf_service_get */
31 #include "fop/fom.h"
32 #include "reqh/reqh.h"
33 #include "rpc/rpc_machine.h"
34 #include "pool/pool.h"
35 #include "cm/proxy.h"
36 
37 #include "dix/fid_convert.h"
38 #include "dix/cm/cp.h"
39 #include "dix/cm/cm.h"
40 #include "dix/cm/iter.h"
41 
308 M0_INTERNAL struct m0_dix_cm *cm2dix(struct m0_cm *cm)
309 {
310  return container_of(cm, struct m0_dix_cm, dcm_base);
311 }
312 
313 M0_INTERNAL int m0_dix_cm_type_register(void)
314 {
315  int rc;
316 
319  if (rc == 0) {
322  }
323  return M0_RC(rc);
324 }
325 
326 M0_INTERNAL void m0_dix_cm_type_deregister(void)
327 {
330 }
331 
332 M0_INTERNAL int m0_dix_cm_setup(struct m0_cm *cm)
333 {
334  return M0_RC(0);
335 }
336 
337 M0_INTERNAL int m0_dix_cm_prepare(struct m0_cm *cm)
338 {
339  struct m0_dix_cm *dcm = cm2dix(cm);
340 
341  dcm->dcm_stats_key = -1;
342 
343  return M0_RC(0);
344 }
345 
346 static bool dix_cm_proxies_completed_cb(struct m0_clink *cl)
347 {
348  struct m0_dix_cm *dcm = M0_AMB(dcm, cl, dcm_proxies_completed);
349  struct m0_cm *cm = &dcm->dcm_base;
350  struct m0_cm_aggr_group *end_mark;
351  bool completed;
352  M0_ENTRY();
353 
355  completed = (cm->cm_proxy_active_nr == 0);
356  if (completed || cm->cm_abort) {
357  end_mark = m0_cm_aggr_group_locate(cm, &GRP_END_MARK_ID, true);
358  M0_ASSERT(end_mark != NULL);
359  m0_cm_aggr_group_fini(end_mark);
360  m0_clink_del(cl);
361  m0_clink_fini(cl);
362  }
363 
364  return M0_RC(false);
365 }
366 
367 M0_INTERNAL int m0_dix_cm_start(struct m0_cm *cm)
368 {
369  struct m0_dix_cm *dcm = cm2dix(cm);
370  struct m0_cm_aggr_group *ag = NULL;
371  struct m0_reqh *reqh = cm->cm_service.rs_reqh;
372  int rc;
373  M0_ENTRY();
374 
376 
377  if (!proxy_tlist_is_empty(&cm->cm_proxies)) {
378  /* Create end-marker ag and add it into ag incoming list. */
380  if (rc != 0)
381  return M0_ERR(rc);
385  &dcm->dcm_proxies_completed);
386  }
387 
389  sizeof(struct m0_dix_cm_stats),
390  NULL, NULL, NULL);
391  if (dcm->dcm_stats_key < 0)
392  return M0_ERR(dcm->dcm_stats_key);
393 
394  /*
395  * Unlock CM since FOM locality lock is taken during waiting for
396  * iterator to start. It prevents usual locality->CM locking order that
397  * can lead to deadlock.
398  */
399  m0_cm_unlock(cm);
400  rc = m0_dix_cm_iter_start(&dcm->dcm_it, dcm->dcm_type, reqh,
401  m0_cm_rpc_machine_find(reqh)->rm_bulk_cutoff);
402  m0_cm_lock(cm);
403  if (rc != 0) {
404  if (ag != NULL) {
406  m0_free(ag);
407  }
409  }
410  dcm->dcm_start_time = m0_time_now();
411  return M0_RC(rc);
412 }
413 
414 static void dix_cm_tstats_calc(int loc_idx, void *loc_stats, void *total_stats)
415 {
416  M0_PRE(loc_stats != NULL);
417  M0_PRE(total_stats != NULL);
418 
419  ((struct m0_dix_cm_stats *)total_stats)->dcs_read_size +=
420  ((struct m0_dix_cm_stats *)loc_stats)->dcs_read_size;
421  ((struct m0_dix_cm_stats *)total_stats)->dcs_write_size +=
422  ((struct m0_dix_cm_stats *)loc_stats)->dcs_write_size;
423 }
424 
425 M0_INTERNAL void m0_dix_cm_stop(struct m0_cm *cm)
426 {
427  struct m0_dix_cm *dcm = cm2dix(cm);
428  struct m0_cm_aggr_group *end_mark;
429  struct m0_dix_cm_stats total_stats = {};
431 
432  if (!cm->cm_done && !proxy_tlist_is_empty(&cm->cm_proxies)) {
433  end_mark = m0_cm_aggr_group_locate(cm, &GRP_END_MARK_ID, true);
434  M0_ASSERT(end_mark != NULL);
435  m0_cm_aggr_group_fini(end_mark);
438  }
439  /* release the cm lock, because m0_dix_cm_iter_stop() may block. */
440  m0_cm_unlock(cm);
442  m0_cm_lock(cm);
443  M0_SET0(&dcm->dcm_it);
444  dcm->dcm_stop_time = m0_time_now();
445 
446  if (dcm->dcm_stats_key >= 0) {
449  &total_stats);
450 
451  M0_LOG(M0_DEBUG, "Time: %llu Read Size: %llu Write size: %llu",
452  (unsigned long long)m0_time_sub(dcm->dcm_stop_time,
453  dcm->dcm_start_time),
454  (unsigned long long)total_stats.dcs_read_size,
455  (unsigned long long)total_stats.dcs_write_size);
456 
458  }
459 }
460 
461 M0_INTERNAL void m0_dix_cm_fini(struct m0_cm *cm)
462 {
463 }
464 
465 M0_INTERNAL int m0_dix_get_space_for(struct m0_cm *cm,
466  const struct m0_cm_ag_id *id,
467  size_t *count)
468 {
469  *count = 1;
470  return M0_RC(0);
471 }
472 
473 M0_INTERNAL int m0_dix_cm_ag_next(struct m0_cm *cm,
474  const struct m0_cm_ag_id *id_curr,
475  struct m0_cm_ag_id *id_next)
476 {
477  M0_ENTRY();
478  /*
479  * Incoming aggregation group list is not populated in case of DIX
480  * repair/re-balance, because local CM doesn't know which copy packets
481  * it will receive.
482  */
483  return M0_RC(-ENODATA);
484 }
485 
486 M0_INTERNAL struct m0_reqh *m0_dix_cm2reqh(const struct m0_dix_cm *dcm)
487 {
488  return dcm->dcm_base.cm_service.rs_reqh;
489 }
490 
491 static struct m0_cm_proxy *dix_cm_sdev2proxy(struct m0_dix_cm *dcm,
492  uint32_t sdev_id)
493 {
494  struct m0_reqh *reqh;
495  struct m0_confc *confc;
496  struct m0_fid svc_fid;
497  struct m0_conf_service *svc = NULL;
498  int rc;
499 
500  reqh = m0_dix_cm2reqh(dcm);
501  M0_ASSERT(reqh != NULL);
503  M0_ASSERT(confc != NULL);
504  svc_fid = reqh->rh_pools->pc_dev2svc[sdev_id].pds_ctx->sc_fid;
505  rc = m0_conf_service_get(confc, &svc_fid, &svc);
506  M0_ASSERT(rc == 0);
507  M0_ASSERT(svc->cs_type == M0_CST_CAS);
508  M0_ASSERT(svc->cs_endpoints[0] != NULL);
509 
510  return m0_cm_proxy_locate(&dcm->dcm_base, svc->cs_endpoints[0]);
511 }
512 
513 static int dix_cm_ag_setup(struct m0_cm *cm,
514  struct m0_cm_cp *cp,
515  struct m0_fid *cctg_fid,
516  uint64_t recs_nr)
517 {
518  struct m0_cm_ag_id ag_id;
519  struct m0_cm_aggr_group *ag;
520  int rc;
521 
522  M0_ENTRY("cm %p", cp);
523  /* Build aggregation group id. */
524  ag_id.ai_hi.u_hi = cctg_fid->f_container;
525  ag_id.ai_hi.u_lo = cctg_fid->f_key;
526  ag_id.ai_lo.u_hi = 0;
527  ag_id.ai_lo.u_hi = recs_nr;
528  rc = m0_cm_aggr_group_alloc(cm, &ag_id, false, &ag);
529  if (rc == 0)
530  m0_cm_ag_cp_add(ag, cp);
531 
532  return M0_RC(rc);
533 }
534 
535 M0_INTERNAL int m0_dix_cm_data_next(struct m0_cm *cm, struct m0_cm_cp *cp)
536 {
537  struct m0_dix_cm *dcm = cm2dix(cm);
538  struct m0_dix_cm_iter *iter = &dcm->dcm_it;
539  struct m0_fom *pfom = &cm->cm_cp_pump.p_fom;
540  struct m0_dix_cm_cp *dix_cp;
541  struct m0_buf key = {};
542  struct m0_buf val = {};
543  struct m0_cm_proxy *proxy;
544  struct m0_fid local_cctg_fid = {};
545  struct m0_fid remote_cctg_fid = {};
546  struct m0_fid dix_fid = {};
547  uint64_t processed_recs_nr;
548  uint32_t sdev_id = (uint32_t)-1;
549  int rc;
550 
551  /* Inc progress counter. */
552  dcm->dcm_processed_nr++;
553 
554  if (cm->cm_quiesce || cm->cm_abort) {
555  M0_LOG(M0_WARN, "%" PRId64 ": Got %s cmd: returning -ENODATA",
556  cm->cm_id,
557  cm->cm_quiesce ? "QUIESCE" : "ABORT");
558  return M0_RC(-ENODATA);
559  }
560 
561  if (!dcm->dcm_iter_inprogress) {
562  if (!dcm->dcm_cp_in_progress) {
563  m0_chan_lock(&iter->di_completed);
564  m0_fom_wait_on(pfom, &iter->di_completed, &pfom->fo_cb);
566  m0_dix_cm_iter_next(iter);
567  dcm->dcm_iter_inprogress = true;
568  M0_LOG(M0_DEBUG, "pump fom %p going to wait for "
569  "iter fom %p",
570  pfom, &iter->di_fom);
571  }
572  return M0_FSO_WAIT;
573  } else {
574  dcm->dcm_iter_inprogress = false;
575  /* Set proxy for copy packet and fill key/value AT buffers. */
576  rc = m0_dix_cm_iter_get(iter, &key, &val, &sdev_id);
577  if (rc != 0) {
578  if (rc == -ENODATA)
580  return M0_ERR(rc);
581  }
582  /* Setup aggregation group. */
583  m0_dix_cm_iter_cur_pos(iter, &local_cctg_fid,
584  &processed_recs_nr);
585  rc = dix_cm_ag_setup(cm, cp, &local_cctg_fid,
586  processed_recs_nr);
587  if (rc == 0) {
588  dix_cp = M0_AMB(dix_cp, cp, dc_base);
589  M0_ASSERT(dix_cp != NULL);
590  proxy = dix_cm_sdev2proxy(dcm, sdev_id);
591  M0_ASSERT(proxy != NULL);
592  cp->c_cm_proxy = proxy;
593  dix_cp->dc_key = key;
594  dix_cp->dc_val = val;
595 
596  /*
597  * Convert FID of local component catalogue to FID of
598  * remote component catalogue,
599  */
600  m0_dix_fid_convert_cctg2dix(&local_cctg_fid, &dix_fid);
601  m0_dix_fid_convert_dix2cctg(&dix_fid, &remote_cctg_fid,
602  sdev_id);
603 
604  dix_cp->dc_ctg_fid = remote_cctg_fid;
605  dix_cp->dc_ctg_op_flags |= COF_CREATE;
606  dix_cp->dc_is_local = true;
607  dcm->dcm_cp_in_progress = true;
608 
609  rc = M0_FSO_AGAIN;
610  } else {
611  /*
612  * Key/value buffers are not needed anymore in error
613  * case. In case rc == 0 we will destroy these key and
614  * val in dix_cp_fop_release().
615  */
616  m0_buf_free(&key);
617  m0_buf_free(&val);
618  }
619  return rc;
620  }
621 }
622 
623 M0_INTERNAL bool m0_dix_is_peer(struct m0_cm *cm,
624  struct m0_reqh_service_ctx *ctx)
625 {
626  return ctx->sc_type == M0_CST_CAS;
627 }
628 
629 #undef M0_TRACE_SUBSYSTEM
630 
632 /*
633  * Local variables:
634  * c-indentation-style: "K&R"
635  * c-basic-offset: 8
636  * tab-width: 8
637  * fill-column: 80
638  * scroll-step: 1
639  * End:
640  */
M0_INTERNAL struct m0_dix_cm * cm2dix(struct m0_cm *cm)
Definition: cm.c:308
M0_INTERNAL void m0_cm_lock(struct m0_cm *cm)
Definition: cm.c:545
M0_INTERNAL int m0_dix_cm_prepare(struct m0_cm *cm)
Definition: cm.c:337
#define M0_PRE(cond)
M0_EXTERN struct m0_cm_type dix_rebalance_cmt
Definition: cm.h:174
M0_INTERNAL void m0_dix_cm_iter_cur_pos(struct m0_dix_cm_iter *iter, struct m0_fid *cctg_fid, uint64_t *cctg_proc_recs_nr)
Definition: iter.c:1537
M0_INTERNAL void m0_dix_fid_convert_cctg2dix(const struct m0_fid *cctg_fid, struct m0_fid *dix_fid)
Definition: fid_convert.c:69
m0_time_t dcm_start_time
Definition: cm.h:134
M0_INTERNAL struct m0_rpc_machine * m0_cm_rpc_machine_find(struct m0_reqh *reqh)
Definition: cm.c:712
struct m0_fid sc_fid
Definition: reqh_service.h:751
int dcm_stats_key
Definition: cm.h:143
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_clink_init(struct m0_clink *link, m0_chan_cb_t cb)
Definition: chan.c:201
M0_INTERNAL void m0_clink_del(struct m0_clink *link)
Definition: chan.c:267
M0_INTERNAL void m0_clink_del_lock(struct m0_clink *link)
Definition: chan.c:293
Definition: idx_mock.c:52
bool cm_quiesce
Definition: cm.h:277
struct m0_clink dcm_proxies_completed
Definition: cm.h:157
M0_INTERNAL void m0_dix_cm_iter_next(struct m0_dix_cm_iter *iter)
Definition: iter.c:1458
M0_INTERNAL void m0_cm_type_deregister(struct m0_cm_type *cmtype)
Definition: cm.c:1019
#define M0_LOG(level,...)
Definition: trace.h:167
Definition: cp.h:160
m0_time_t dcm_stop_time
Definition: cm.h:140
uint64_t cm_id
Definition: cm.h:174
bool cm_done
Definition: cm.h:265
static void dix_cm_tstats_calc(int loc_idx, void *loc_stats, void *total_stats)
Definition: cm.c:414
M0_INTERNAL int m0_dix_cm_data_next(struct m0_cm *cm, struct m0_cm_cp *cp)
Definition: cm.c:535
struct m0_fid dc_ctg_fid
Definition: cp.h:53
struct m0_fom p_fom
Definition: pump.h:51
static int dix_cm_ag_setup(struct m0_cm *cm, struct m0_cm_cp *cp, struct m0_fid *cctg_fid, uint64_t recs_nr)
Definition: cm.c:513
struct m0_fom di_fom
Definition: iter.h:52
M0_INTERNAL void m0_fom_wait_on(struct m0_fom *fom, struct m0_chan *chan, struct m0_fom_callback *cb)
Definition: fom.c:1490
M0_INTERNAL void m0_dix_cm_fini(struct m0_cm *cm)
Definition: cm.c:461
M0_INTERNAL int m0_dix_cm_iter_start(struct m0_dix_cm_iter *iter, struct m0_dix_cm_type *dcmt, struct m0_reqh *reqh, m0_bcount_t rpc_cutoff)
Definition: iter.c:1429
M0_INTERNAL void m0_chan_lock(struct m0_chan *ch)
Definition: chan.c:68
#define container_of(ptr, type, member)
Definition: misc.h:33
#define M0_SET0(obj)
Definition: misc.h:64
struct m0_buf dc_key
Definition: cp.h:90
static m0_bcount_t count
Definition: xcode.c:167
M0_INTERNAL int m0_dix_cm_setup(struct m0_cm *cm)
Definition: cm.c:332
return M0_RC(rc)
static struct m0_cm * cm
Definition: cm.c:63
M0_INTERNAL void m0_cm_unlock(struct m0_cm *cm)
Definition: cm.c:550
struct m0_tl cm_proxies
Definition: cm.h:246
#define M0_ENTRY(...)
Definition: trace.h:170
Definition: buf.h:37
M0_INTERNAL void m0_cm_ag_cp_add(struct m0_cm_aggr_group *ag, struct m0_cm_cp *cp)
Definition: ag.c:510
uint32_t dc_ctg_op_flags
Definition: cp.h:71
void m0_locality_data_free(int key)
Definition: locality.c:463
static struct m0_cm_ag_id ag_id
Definition: net.c:121
M0_INTERNAL void m0_dix_cm_iter_type_register(struct m0_dix_cm_type *dcmt)
Definition: iter.c:1419
return M0_ERR(-EOPNOTSUPP)
static int key
Definition: locality.c:283
M0_INTERNAL struct m0_confc * m0_reqh2confc(struct m0_reqh *reqh)
Definition: reqh.c:753
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
M0_EXTERN struct m0_dix_cm_type dix_rebalance_dcmt
Definition: cm.h:176
M0_INTERNAL int m0_dix_cm_ag_next(struct m0_cm *cm, const struct m0_cm_ag_id *id_curr, struct m0_cm_ag_id *id_next)
Definition: cm.c:473
#define M0_ASSERT(cond)
static struct m0_confc * confc
Definition: file.c:94
m0_time_t m0_time_now(void)
Definition: time.c:134
M0_INTERNAL void m0_dix_cm_iter_stop(struct m0_dix_cm_iter *iter)
Definition: iter.c:1525
struct m0_buf dc_val
Definition: cp.h:92
M0_INTERNAL void m0_dix_cm_type_deregister(void)
Definition: cm.c:326
M0_INTERNAL struct m0_cm_aggr_group * m0_cm_aggr_group_locate(struct m0_cm *cm, const struct m0_cm_ag_id *id, bool has_incoming)
Definition: ag.c:262
struct m0_cm dcm_base
Definition: cm.h:119
uint64_t u_hi
Definition: types.h:36
uint64_t f_container
Definition: fid.h:39
struct m0_cm_ag_id cm_last_out_hi
Definition: cm.h:222
M0_EXTERN struct m0_dix_cm_type dix_repair_dcmt
Definition: cm.h:175
struct m0_chan cm_wait
Definition: cm.h:235
Definition: reqh.h:94
static struct m0_cm_proxy * dix_cm_sdev2proxy(struct m0_dix_cm *dcm, uint32_t sdev_id)
Definition: cm.c:491
M0_INTERNAL void m0_buf_free(struct m0_buf *buf)
Definition: buf.c:55
struct m0_pool_device_to_service * pc_dev2svc
Definition: pool.h:207
M0_INTERNAL int m0_dix_cm_iter_get(struct m0_dix_cm_iter *iter, struct m0_buf *key, struct m0_buf *val, uint32_t *sdev_id)
Definition: iter.c:1465
Definition: cm.h:117
M0_INTERNAL int m0_dix_cm_start(struct m0_cm *cm)
Definition: cm.c:367
#define PRId64
Definition: types.h:57
M0_INTERNAL void m0_chan_unlock(struct m0_chan *ch)
Definition: chan.c:73
struct m0_reqh_service_ctx * pds_ctx
Definition: pool.h:74
static bool dix_cm_proxies_completed_cb(struct m0_clink *cl)
Definition: cm.c:346
void m0_clink_add_lock(struct m0_chan *chan, struct m0_clink *link)
Definition: chan.c:255
bool dcm_iter_inprogress
Definition: cm.h:149
Definition: fom.h:481
#define GRP_END_MARK_ID
Definition: ag.h:62
struct m0_reqh reqh
Definition: rm_foms.c:48
struct m0_cm_proxy * c_cm_proxy
Definition: cp.h:208
M0_INTERNAL void m0_cm_aggr_group_fini(struct m0_cm_aggr_group *ag)
Definition: ag.c:180
Definition: fid.h:38
M0_INTERNAL bool m0_dix_is_peer(struct m0_cm *cm, struct m0_reqh_service_ctx *ctx)
Definition: cm.c:623
uint64_t f_key
Definition: fid.h:40
M0_EXTERN struct m0_cm_type dix_repair_cmt
Definition: cm.h:173
struct m0_dix_cm_type * dcm_type
Definition: cm.h:122
struct m0_reqh_service cm_service
Definition: cm.h:191
M0_INTERNAL int m0_dix_cm_type_register(void)
Definition: cm.c:313
uint64_t cm_proxy_active_nr
Definition: cm.h:254
bool dcm_cp_in_progress
Definition: cm.h:152
m0_time_t m0_time_sub(const m0_time_t t1, const m0_time_t t2)
Definition: time.c:65
static struct m0_net_test_service svc
Definition: service.c:34
Definition: cm.h:166
M0_INTERNAL struct m0_cm_proxy * m0_cm_proxy_locate(struct m0_cm *cm, const char *addr)
Definition: proxy.c:161
M0_INTERNAL void m0_clink_fini(struct m0_clink *link)
Definition: chan.c:208
struct m0_pools_common * rh_pools
Definition: reqh.h:118
bool dc_is_local
Definition: cp.h:59
struct m0_uint128 ai_hi
Definition: ag.h:50
struct m0_uint128 ai_lo
Definition: ag.h:51
void m0_locality_data_iterate(int key, void(*func)(int idx, void *data, void *datum), void *datum)
Definition: locality.c:480
M0_INTERNAL struct m0_reqh * m0_dix_cm2reqh(const struct m0_dix_cm *dcm)
Definition: cm.c:486
struct m0_cm_cp_pump cm_cp_pump
Definition: cm.h:257
int m0_locality_data_alloc(size_t nob, int(*ctor)(void *, void *), void(*dtor)(void *, void *), void *datum)
Definition: locality.c:442
M0_INTERNAL int m0_dix_get_space_for(struct m0_cm *cm, const struct m0_cm_ag_id *id, size_t *count)
Definition: cm.c:465
M0_INTERNAL int m0_cm_aggr_group_alloc(struct m0_cm *cm, const struct m0_cm_ag_id *id, bool has_incoming, struct m0_cm_aggr_group **out)
Definition: ag.c:330
Definition: nucleus.c:42
uint64_t dcs_write_size
Definition: cm.h:113
int dcm_processed_nr
Definition: cm.h:160
uint64_t u_lo
Definition: types.h:37
M0_INTERNAL bool m0_cm_is_locked(const struct m0_cm *cm)
Definition: cm.c:560
struct m0_reqh * rs_reqh
Definition: reqh_service.h:259
void m0_free(void *data)
Definition: memory.c:146
uint64_t dcs_read_size
Definition: cm.h:112
M0_INTERNAL void m0_dix_cm_stop(struct m0_cm *cm)
Definition: cm.c:425
M0_INTERNAL void m0_dix_fid_convert_dix2cctg(const struct m0_fid *dix_fid, struct m0_fid *cctg_fid, uint32_t device_id)
Definition: fid_convert.c:54
int32_t rc
Definition: trigger_fop.h:47
bool cm_abort
Definition: cm.h:282
struct m0_chan di_completed
Definition: iter.h:156
struct m0_fom_callback fo_cb
Definition: fom.h:488
Definition: ag.h:49
struct m0_dix_cm_iter dcm_it
Definition: cm.h:128
Definition: trace.h:478
Definition: idx_mock.c:47
M0_INTERNAL int m0_cm_type_register(struct m0_cm_type *cmtype)
Definition: cm.c:995