Motr  M0
fop.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2021 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_DTM0
24 #include "lib/trace.h" /* M0_LOG */
25 #include "cas/cas.h"
26 #include "cas/cas_xc.h"
27 #include "dtm0/fop.h"
28 #include "dtm0/fop_xc.h"
29 #include "dtm0/addb2.h"
30 #include "dtm0/drlink.h" /* m0_dtm0_req_post */
31 #include "dtm0/service.h" /* m0_dtm0_service */
32 #include "be/dtm0_log.h" /* m0_be_dtm0_log_* */
33 #include "be/queue.h" /* M0_BE_QUEUE_PUT */
34 #include "fop/fom_generic.h" /* M0_FOPH_* */
35 #include "lib/assert.h"
36 #include "lib/errno.h"
37 #include "lib/memory.h"
38 #include "lib/misc.h" /* M0_IN() */
39 #include "reqh/reqh.h" /* reqh::rh_beseg */
40 #include "rpc/rpc_opcodes.h" /* M0_DTM0_REP_OPCODE */
41 
45 
47 struct dtm0_fom {
48  struct m0_fom dtf_fom;
51 };
52 
53 static int dtm0_emsg_fom_tick(struct m0_fom *fom);
54 static int dtm0_pmsg_fom_tick(struct m0_fom *fom);
55 static int dtm0_rmsg_fom_tick(struct m0_fom *fom);
56 static int dtm0_tmsg_fom_tick(struct m0_fom *fom);
57 static int dtm0_fom_create(struct m0_fop *fop, struct m0_fom **out,
58  struct m0_reqh *reqh);
59 static void dtm0_fom_fini(struct m0_fom *fom);
60 static size_t dtm0_fom_locality(const struct m0_fom *fom);
61 static int dtm0_cas_fop_prepare(struct dtm0_req_fop *req,
62  struct m0_fop_type *cas_fopt,
63  struct m0_fop **cas_fop_out);
64 static int dtm0_cas_fom_spawn(
65  struct dtm0_fom *dfom,
66  struct m0_fop *cas_fop,
67  void (*on_cas_fom_complete)(struct m0_fom_thralldom *,
68  struct m0_fom *));
69 
70 static const struct m0_fom_ops dtm0_pmsg_fom_ops = {
72  .fo_tick = dtm0_pmsg_fom_tick,
73  .fo_home_locality = dtm0_fom_locality
74 };
75 
76 static const struct m0_fom_ops dtm0_rmsg_fom_ops = {
78  .fo_tick = dtm0_rmsg_fom_tick,
79  .fo_home_locality = dtm0_fom_locality
80 };
81 
82 static const struct m0_fom_ops dtm0_emsg_fom_ops = {
84  .fo_tick = dtm0_emsg_fom_tick,
85  .fo_home_locality = dtm0_fom_locality
86 };
87 
88 static const struct m0_fom_ops dtm0_tmsg_fom_ops = {
90  .fo_tick = dtm0_tmsg_fom_tick,
91  .fo_home_locality = dtm0_fom_locality
92 };
93 
95 
96 static const struct m0_fom_type_ops dtm0_req_fom_type_ops = {
98 };
99 
100 M0_INTERNAL void m0_dtm0_fop_fini(void)
101 {
105  m0_xc_dtm0_fop_fini();
106 }
107 
108 enum {
113 };
114 
116  [M0_FOPH_DTM0_ENTRY] = {
117  .sd_name = "dtm0-entry",
118  .sd_allowed = M0_BITS(M0_FOPH_DTM0_LOGGING,
122  },
124  .sd_name = "logging",
125  .sd_allowed = M0_BITS(M0_FOPH_SUCCESS,
127  },
128  [M0_FOPH_DTM0_TO_CAS] = {
129  .sd_name = "dtm0-to-cas",
130  .sd_allowed = M0_BITS(M0_FOPH_DTM0_CAS_DONE,
132  },
134  .sd_name = "cas-done",
135  .sd_allowed = M0_BITS(M0_FOPH_SUCCESS,
137  },
138 };
139 
142  {"dtm0-entry-fail", M0_FOPH_DTM0_ENTRY, M0_FOPH_FAILURE},
143  {"dtm0-entry-success", M0_FOPH_DTM0_ENTRY, M0_FOPH_SUCCESS},
144 
145  {"dtm0-logging", M0_FOPH_DTM0_ENTRY, M0_FOPH_DTM0_LOGGING},
146  {"dtm0-logging-fail", M0_FOPH_DTM0_LOGGING, M0_FOPH_FAILURE},
147  {"dtm0-logging-success", M0_FOPH_DTM0_LOGGING, M0_FOPH_SUCCESS},
148 
149  {"dtm0-to-cas", M0_FOPH_DTM0_ENTRY, M0_FOPH_DTM0_TO_CAS},
150 
151  {"dtm0-to-cas-fail", M0_FOPH_DTM0_TO_CAS, M0_FOPH_FAILURE},
152  {"dtm0-cas-done", M0_FOPH_DTM0_TO_CAS, M0_FOPH_DTM0_CAS_DONE},
153 
154  {"dtm0-cas-success", M0_FOPH_DTM0_CAS_DONE, M0_FOPH_SUCCESS},
155  {"dtm0-cas-fail", M0_FOPH_DTM0_CAS_DONE, M0_FOPH_FAILURE},
156 };
157 
158 static struct m0_sm_conf dtm0_conf = {
159  .scf_name = "dtm0-fom",
160  .scf_nr_states = ARRAY_SIZE(dtm0_phases),
161  .scf_state = dtm0_phases,
162  .scf_trans_nr = ARRAY_SIZE(dtm0_phases_trans),
163  .scf_trans = dtm0_phases_trans,
164 };
165 
166 M0_INTERNAL int m0_dtm0_fop_init(void)
167 {
168  static int init_once = 0;
169 
170  if (init_once++ > 0)
171  return 0;
172 
177 
178 
179  m0_xc_dtm0_fop_init();
181  .name = "DTM0 request",
183  .xt = dtm0_req_fop_xc,
184  .rpc_flags = M0_RPC_MUTABO_REQ,
185  .fom_ops = &dtm0_req_fom_type_ops,
186  .sm = &dtm0_conf,
187  .svc_type = &dtm0_service_type);
189  .name = "DTM0 redo",
191  .xt = dtm0_req_fop_xc,
192  .rpc_flags = M0_RPC_ITEM_TYPE_REQUEST,
193  .fom_ops = &dtm0_req_fom_type_ops,
194  .sm = &dtm0_conf,
195  .svc_type = &dtm0_service_type);
197  .name = "DTM0 reply",
199  .xt = dtm0_rep_fop_xc,
200  .rpc_flags = M0_RPC_ITEM_TYPE_REPLY,
201  .fom_ops = &dtm0_req_fom_type_ops);
202 
205 }
206 
207 
208 /*
209  Allocates a fom.
210  */
211 static int dtm0_fom_create(struct m0_fop *fop,
212  struct m0_fom **out,
213  struct m0_reqh *reqh)
214 {
215  struct dtm0_fom *fom;
216  struct m0_fop *repfop;
217  struct dtm0_rep_fop *reply;
218  struct dtm0_req_fop *req;
219  struct m0_dtm0_pmsg_ast *pma;
220  int rc;
221 
222  M0_ENTRY("reqh=%p", reqh);
223 
224  M0_ALLOC_PTR(fom);
225  M0_ALLOC_PTR(pma);
227 
228  if (fom == NULL || repfop == NULL || pma == NULL) {
229  m0_free(pma);
230  m0_free(repfop);
231  m0_free(fom);
232  return M0_ERR(-ENOMEM);
233  }
234 
235  *out = &fom->dtf_fom;
236 
237  /* TODO: calculate credits for the operation. */
238 
239  /* see ::m0_dtm0_dtx_post_persistent for the details */
240  fop->f_opaque = pma;
241  reply = m0_fop_data(repfop);
242  req = m0_fop_data(fop);
243  reply->dr_txr = (struct m0_dtm0_tx_desc) {};
244  reply->dr_rc = 0;
245 
246  /* TODO avoid copy-paste */
247  if (req->dtr_msg == DTM_EXECUTE) {
248  M0_ASSERT_INFO(m0_dtm0_in_ut(), "Emsg FOM is only for UTs.");
249  rc = m0_dtm0_tx_desc_copy(&req->dtr_txr, &reply->dr_txr);
250  M0_ASSERT(rc == 0);
251  m0_fom_init(&fom->dtf_fom, &fop->f_type->ft_fom_type,
252  &dtm0_emsg_fom_ops, fop, repfop, reqh);
253  } else if (req->dtr_msg == DTM_PERSISTENT) {
254  m0_fom_init(&fom->dtf_fom, &fop->f_type->ft_fom_type,
255  &dtm0_pmsg_fom_ops, fop, repfop, reqh);
256  } else if (req->dtr_msg == DTM_REDO) {
257  m0_fom_init(&fom->dtf_fom, &fop->f_type->ft_fom_type,
258  &dtm0_rmsg_fom_ops, fop, repfop, reqh);
259  } else if (req->dtr_msg == DTM_TEST) {
260  m0_fom_init(&fom->dtf_fom, &fop->f_type->ft_fom_type,
261  &dtm0_tmsg_fom_ops, fop, repfop, reqh);
262  } else
263  M0_IMPOSSIBLE();
264 
265  return M0_RC_INFO(0, "fom=%p", &fom->dtf_fom);
266 }
267 
268 static void dtm0_fom_fini(struct m0_fom *fom)
269 {
270  M0_PRE(fom != NULL);
271 
272  m0_fom_fini(fom);
273  m0_free(fom);
274 }
275 
276 static size_t dtm0_fom_locality(const struct m0_fom *fom)
277 {
278  static size_t locality = 0;
279 
280  M0_PRE(fom != NULL);
281  return locality++;
282 }
283 
284 M0_INTERNAL int m0_dtm0_logrec_update(struct m0_be_dtm0_log *log,
285  struct m0_be_tx *tx,
286  struct m0_dtm0_tx_desc *txd,
287  struct m0_buf *payload)
288 {
289  int rc;
290 
291  M0_ENTRY();
292 
293  m0_mutex_lock(&log->dl_lock);
294  rc = m0_be_dtm0_log_update(log, tx, txd, payload);
295  m0_mutex_unlock(&log->dl_lock);
296 
297  return M0_RC(rc);
298 }
299 
300 M0_INTERNAL int m0_dtm0_on_committed(struct m0_fom *fom,
301  const struct m0_dtm0_tid *id)
302 {
303  struct m0_dtm0_service *dtms;
304  struct m0_be_dtm0_log *log;
305  const struct m0_dtm0_log_rec *rec;
306  const struct m0_fid *target;
307  const struct m0_fid *source;
308  struct dtm0_req_fop req = { .dtr_msg = DTM_PERSISTENT };
309  struct m0_dtm0_tx_desc *txd = &req.dtr_txr;
310  int rc;
311  int i;
312 
313  dtms = m0_dtm0_service_find(fom->fo_service->rs_reqh);
314 
315  /*
316  * It is impossible to commit a transaction without DTM0 service up and
317  * running.
318  */
319  M0_PRE(dtms != NULL);
320  log = dtms->dos_log;
321  M0_PRE(log != NULL);
322  /* It is impossible to commit something on a volatile log. */
323  M0_PRE(log->dl_is_persistent);
324 
325  M0_ENTRY();
326 
327  m0_mutex_lock(&log->dl_lock);
328  /* Get the latest state of the log record. */
329  rec = m0_be_dtm0_log_find(log, id);
330  /*
331  * It is impossible to commit a record that is not a part of the
332  * DTM log.
333  */
334  M0_ASSERT_INFO(rec != NULL, "Log record must be inserted into the log "
335  "in cas_fom_tick().");
336  rc = m0_dtm0_tx_desc_copy(&rec->dlr_txd, txd);
337  m0_mutex_unlock(&log->dl_lock);
338 
339  if (rc != 0)
340  goto out;
341 
342  /*
343  * We have to send N PERSISTENT messages once a local transaction
344  * gets committed (where N == txd->dtd_ps.dtp_nr):
345  * N-1 to the other participants (except ourselves),
346  * 1 to the originator (txd->dtd_id.dti_fid).
347  */
349  for (i = 0; i < txd->dtd_ps.dtp_nr; ++i) {
350  target = &txd->dtd_ps.dtp_pa[i].p_fid;
351 
352  /*
353  * Since we should not send Pmsg to ourselves, re-use this
354  * iteration to send Pmsg to the originator.
355  */
356  if (m0_fid_eq(target, source))
357  target = &txd->dtd_id.dti_fid;
358 
359  rc = m0_dtm0_req_post(dtms, NULL, &req, target, fom, false);
360  if (rc != 0) {
361  M0_LOG(M0_WARN, "Failed to send PERSISTENT msg "
362  FID_F " -> " FID_F " (%d).",
363  FID_P(source), FID_P(target), rc);
364  /*
365  * If we have failed to send a Pmsg (for any reason),
366  * it is still not a showstopper for the caller
367  * because the transaction has already been committed.
368  */
369  rc = 0;
370  }
371  }
372 
374 
375 out:
376  return M0_RC(rc);
377 }
378 
379 /*
380  * A FOM tick to handle a DTM0 PERSISTENT message (Pmsg).
381  * A group of Pmsgs is sent whenever a local transaction gets committed
382  * (see ::m0_dtm0_on_committed). This routine is the recipient of such
383  * messages.
384  */
385 static int dtm0_pmsg_fom_tick(struct m0_fom *fom)
386 {
387  int result = M0_FSO_AGAIN;
388  struct m0_dtm0_service *svc;
389  struct m0_buf buf = {};
390  struct dtm0_rep_fop *rep;
391  struct dtm0_req_fop *req = m0_fop_data(fom->fo_fop);
392  int phase = m0_fom_phase(fom);
393  struct m0_be_tx_credit cred = {};
394 
395  M0_PRE(req->dtr_msg == DTM_PERSISTENT);
396  M0_ENTRY("fom %p phase %d", fom, phase);
397 
398  switch (phase) {
399  case M0_FOPH_INIT ... M0_FOPH_NR - 1:
400  result = m0_fom_tick_generic(fom);
401  if (m0_dtm0_is_a_persistent_dtm(fom->fo_service) &&
403  M0_ASSERT(phase == M0_FOPH_TXN_INIT);
405  &req->dtr_txr, &buf,
406  m0_fom_reqh(fom)->rh_beseg,
407  NULL, &cred);
408  m0_be_tx_credit_add(&fom->fo_tx.tx_betx_cred, &cred);
409  }
410  break;
411 
412  case M0_FOPH_DTM0_ENTRY:
414  break;
415 
417  rep = m0_fop_data(fom->fo_rep_fop);
419  M0_ASSERT(svc != NULL);
420 
421  M0_LOG(M0_DEBUG, "Logging a P msg in phase %" PRIu32
422  " %d, " FID_F ", %p", req->dtr_msg,
423  !!m0_dtm0_is_a_volatile_dtm(fom->fo_service),
424  FID_P(&fom->fo_service->rs_service_fid),
425  fom->fo_service->rs_reqh);
426 
427  if (m0_dtm0_is_a_volatile_dtm(fom->fo_service)) {
428  /*
429  * On the client side, DTX is the owner of the
430  * corresponding log record, so that it cannot be
431  * modifed right here. We have to post an AST
432  * to ensure DTX is modifed under the group lock held.
433  */
434  m0_be_dtm0_log_pmsg_post(svc->dos_log, fom->fo_fop);
435  rep->dr_rc = 0;
436  } else {
437  rep->dr_rc = m0_dtm0_logrec_update(svc->dos_log,
438  &fom->fo_tx.tx_betx,
439  &req->dtr_txr, &buf);
440  }
441 
442  /* We do not handle any failures of Pmsg processing. */
444 
445  break;
446  default:
447  M0_IMPOSSIBLE("Invalid phase");
448  }
449 
450  return M0_RC(result);
451 }
452 
453 /*
454  * A FOM tick to handle a DTM0 EXECUTE message (Emsg).
455  * TODO:
456  * EXECUTE/EXECUTED message is "under development", and it is not a part
457  * of the main DTM0 algorithm yet.
458  * Previously, it was used to send ping-pongs in the UT. Once DTM0 RPC link
459  * gets its version of m0_rpc_post_sync, this FOM tick will be used in the
460  * UT that sends ping-pongs between volatile and persistent DTM0 services.
461  */
462 static int dtm0_emsg_fom_tick(struct m0_fom *fom)
463 {
464  int result = M0_FSO_AGAIN;
465  struct dtm0_rep_fop *rep = m0_fop_data(fom->fo_rep_fop);
466  struct dtm0_req_fop *req = m0_fop_data(fom->fo_fop);
467  int phase = m0_fom_phase(fom);
469  const struct m0_fid *tgt = &req->dtr_txr.dtd_id.dti_fid;
470  const struct dtm0_req_fop executed = {
471  .dtr_msg = DTM_EXECUTED,
472  .dtr_txr = req->dtr_txr,
473  };
474 
475  M0_PRE(req->dtr_msg == DTM_EXECUTE);
476  M0_ASSERT_INFO(m0_dtm0_in_ut(), "Emsg cannot be used outside of UT.");
477 
478  M0_ENTRY("fom %p phase %d", fom, phase);
479 
480  switch (phase) {
481  case M0_FOPH_INIT ... M0_FOPH_NR - 1:
482  result = m0_fom_tick_generic(fom);
483  break;
484  case M0_FOPH_DTM0_ENTRY:
485  if (m0_dtm0_is_a_persistent_dtm(fom->fo_service))
486  rep->dr_rc = m0_dtm0_req_post(svc, NULL, &executed,
487  tgt, fom, false);
489  break;
490  default:
491  M0_IMPOSSIBLE("Invalid phase");
492  }
493 
494  return M0_RC(result);
495 }
496 
498  struct m0_fom *serf)
499 {
500  struct dtm0_fom *leader = M0_AMB(leader, thrall, dtf_thrall);
501  struct m0_cas_rep *rep;
502  int rc;
503 
504  rc = m0_fom_rc(serf);
505  if (rc == 0) {
506  M0_ASSERT(serf->fo_rep_fop != NULL);
507  rep = (struct m0_cas_rep *)m0_fop_data(serf->fo_rep_fop);
508  M0_ASSERT(rep != NULL);
509  rc = rep->cgr_rc;
510  if (rc == 0) {
511  M0_ASSERT(rep->cgr_rep.cr_nr == 1);
512  rc = rep->cgr_rep.cr_rec[0].cr_rc;
513  }
514  }
515  leader->dtf_thrall_rc = rc;
516 }
517 
519  struct dtm0_fom *dfom,
520  struct m0_fop *cas_fop,
521  void (*on_cas_fom_complete)(struct m0_fom_thralldom *,
522  struct m0_fom *))
523 {
524 #ifndef __KERNEL__
525  return m0_cas_fom_spawn(&dfom->dtf_fom, &dfom->dtf_thrall,
526  cas_fop, on_cas_fom_complete);
527 #else
528  /* CAS service is not compiled for kernel. */
529  return 0;
530 #endif
531 }
532 
534  struct m0_fop_type *cas_fopt,
535  struct m0_fop **cas_fop_out)
536 {
537  int rc;
538  struct m0_cas_op *cas_op;
539  struct m0_fop *cas_fop;
540 
541  *cas_fop_out = NULL;
542 
544  M0_ALLOC_PTR(cas_fop);
545 
546  if (cas_op == NULL || cas_fop == NULL) {
547  rc = -ENOMEM;
548  } else {
550  &M0_XCODE_OBJ(m0_cas_op_xc, cas_op),
551  req->dtr_payload.b_addr,
552  req->dtr_payload.b_nob);
553  if (rc == 0)
554  m0_fop_init(cas_fop, cas_fopt, cas_op, &m0_fop_release);
555  else
556  M0_LOG(M0_ERROR, "Could not decode the REDO payload");
557  }
558 
559  if (rc == 0) {
560  *cas_fop_out = cas_fop;
561  } else {
562  m0_free(cas_op);
563  m0_free(cas_fop);
564  }
565 
566  return rc;
567 }
568 
569 static int dtm0_rmsg_fom_tick(struct m0_fom *fom)
570 {
571  int rc;
572  int result = M0_FSO_AGAIN;
573  int phase = m0_fom_phase(fom);
574  struct dtm0_fom *dfom = M0_AMB(dfom, fom, dtf_fom);
575  struct dtm0_req_fop *req = m0_fop_data(fom->fo_fop);
576  struct m0_fop *cas_fop = NULL;
577 
578  M0_ENTRY("fom %p phase %d", fom, phase);
579 
580  switch (phase) {
581  case M0_FOPH_INIT ... M0_FOPH_NR - 1:
582  result = m0_fom_tick_generic(fom);
583  break;
584  case M0_FOPH_DTM0_ENTRY:
586  break;
587  case M0_FOPH_DTM0_TO_CAS:
588  /* REDO_END()s from all recovering processes received, send
589  * RECOVERED() message to the counterpart.
590 
591  cs_ha_process_event(m0_cs_ctx_get(m0_fom_reqh(fom)),
592  M0_CONF_HA_PROCESS_DTM_RECOVERED);
593  */
594  rc = dtm0_cas_fop_prepare(req, &cas_put_fopt, &cas_fop);
595  if (rc == 0) {
596  rc = dtm0_cas_fom_spawn(dfom, cas_fop,
598  if (rc != 0) {
599  M0_LOG(M0_ERROR, "Could not spawn CAS fom");
600  m0_fop_fini(cas_fop);
601  m0_free(cas_fop);
602  } else {
603  result = M0_FSO_WAIT;
604  }
605  } else {
606  M0_LOG(M0_ERROR, "Could not prepare CAS fop");
607  }
608 
609  if (rc != 0)
611  else
613  break;
615  if (dfom->dtf_thrall_rc != 0) {
616  M0_LOG(M0_ERROR, "Spawned CAS fom failed, rc = %d",
617  dfom->dtf_thrall_rc);
620  } else {
622  }
623  break;
624  default:
625  M0_IMPOSSIBLE("Invalid phase");
626  }
627  return M0_RC(result);
628 }
629 
631 static int dtm0_tmsg_fom_tick(struct m0_fom *fom)
632 {
634  struct dtm0_req_fop *req = m0_fop_data(fom->fo_fop);
635  int phase = m0_fom_phase(fom);
636  int result;
637 
638  M0_ENTRY("fom %p phase %d", fom, phase);
639 
640  if (m0_fom_phase(fom) < M0_FOPH_NR) {
641  result = m0_fom_tick_generic(fom);
642  } else {
643  m0_be_queue_lock(svc->dos_ut_queue);
645  M0_BE_QUEUE_PUT(svc->dos_ut_queue, &op,
646  &req->dtr_txr.dtd_id.dti_fid));
647  m0_be_queue_unlock(svc->dos_ut_queue);
649  result = M0_RC(M0_FSO_AGAIN);
650  }
651  return M0_RC(result);
652 }
653 
654 /*
655  * Local variables:
656  * c-indentation-style: "K&R"
657  * c-basic-offset: 8
658  * tab-width: 8
659  * fill-column: 80
660  * scroll-step: 1
661  * End:
662  */
M0_INTERNAL bool m0_dtm0_is_a_volatile_dtm(struct m0_reqh_service *service)
Definition: service.c:393
#define M0_PRE(cond)
M0_INTERNAL void m0_sm_conf_init(struct m0_sm_conf *conf)
Definition: sm.c:340
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
#define M0_BE_QUEUE_PUT(bq, op, ptr)
Definition: queue.h:236
static const struct m0_fom_ops dtm0_pmsg_fom_ops
Definition: fop.c:70
#define NULL
Definition: misc.h:38
M0_INTERNAL struct m0_dtm0_service * m0_dtm0_service_find(const struct m0_reqh *reqh)
Definition: service.c:406
Definition: fop.h:50
static size_t locality(const struct m0_fom *fom)
Definition: rm_foms.c:269
static void init_once(void *foo)
Definition: inode.c:90
static struct m0_sm_conf dtm0_conf
Definition: fop.c:158
#define M0_FOP_TYPE_INIT(ft,...)
Definition: fop.h:307
Definition: sm.h:350
static struct io_request req
Definition: file.c:100
M0_INTERNAL void m0_fop_init(struct m0_fop *fop, struct m0_fop_type *fopt, void *data, void(*fop_release)(struct m0_ref *))
Definition: fop.c:79
struct m0_reqh_service_type dtm0_service_type
Definition: service.c:60
#define M0_LOG(level,...)
Definition: trace.h:167
static const struct m0_fom_ops dtm0_tmsg_fom_ops
Definition: fop.c:88
int(* fto_create)(struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: fom.h:650
struct m0_dtm0_tx_desc dlr_txd
Definition: dtm0_log.h:162
#define M0_BE_OP_SYNC(op_obj, action)
Definition: op.h:190
struct m0_sm_trans_descr dtm0_phases_trans[]
Definition: fop.c:140
void * m0_fop_data(const struct m0_fop *fop)
Definition: fop.c:220
void m0_fop_type_fini(struct m0_fop_type *fopt)
Definition: fop.c:232
M0_INTERNAL void m0_sm_conf_trans_extend(const struct m0_sm_conf *base, struct m0_sm_conf *sub)
Definition: sm.c:726
M0_INTERNAL void m0_sm_conf_extend(const struct m0_sm_state_descr *base, struct m0_sm_state_descr *sub, uint32_t nr)
Definition: sm.c:763
#define M0_BITS(...)
Definition: misc.h:236
static int dtm0_rmsg_fom_tick(struct m0_fom *fom)
Definition: fop.c:569
static const struct m0_fom_ops dtm0_emsg_fom_ops
Definition: fop.c:82
M0_INTERNAL int m0_cas_fom_spawn(struct m0_fom *lead, struct m0_fom_thralldom *thrall, struct m0_fop *cas_fop, void(*on_fom_complete)(struct m0_fom_thralldom *, struct m0_fom *))
Definition: service.c:2570
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
static struct m0_xcode_type ** xt[]
Definition: protocol.c:64
const struct m0_sm_conf m0_generic_conf
Definition: fom_generic.c:838
struct m0_fop_getxattr_rep * rep
Definition: dir.c:455
m0_fom_phase
Definition: fom.h:372
Definition: sock.c:887
M0_INTERNAL int m0_dtm0_on_committed(struct m0_fom *fom, const struct m0_dtm0_tid *id)
Definition: fop.c:300
struct m0_fom_type ft_fom_type
Definition: fop.h:232
return M0_RC(rc)
struct m0_be_dtm0_log * dos_log
Definition: service.h:50
op
Definition: libdemo.c:64
struct m0_dtm0_tid dtd_id
Definition: tx_desc.h:121
#define M0_ENTRY(...)
Definition: trace.h:170
M0_INTERNAL bool m0_dtm0_is_a_persistent_dtm(struct m0_reqh_service *service)
Definition: service.c:399
Definition: buf.h:37
M0_INTERNAL int m0_dtm0_fop_init(void)
Definition: fop.c:166
int opcode
Definition: crate.c:301
void m0_fom_init(struct m0_fom *fom, const struct m0_fom_type *fom_type, const struct m0_fom_ops *ops, struct m0_fop *fop, struct m0_fop *reply, struct m0_reqh *reqh)
Definition: fom.c:1372
int i
Definition: dir.c:1033
#define M0_RC_INFO(rc, fmt,...)
Definition: trace.h:209
struct m0_fop_type * f_type
Definition: fop.h:81
static void dtm0_cas_done_cb(struct m0_fom_thralldom *thrall, struct m0_fom *serf)
Definition: fop.c:497
return M0_ERR(-EOPNOTSUPP)
Definition: fop.c:47
M0_INTERNAL void m0_be_queue_unlock(struct m0_be_queue *bq)
Definition: stubs.c:325
const char * name
Definition: trace.c:110
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
struct m0_fom_thralldom thrall
Definition: ms_fom_ut.c:110
struct m0_fom dtf_fom
Definition: fop.c:48
int m0_fom_tick_generic(struct m0_fom *fom)
Definition: fom_generic.c:848
void m0_fom_fini(struct m0_fom *fom)
Definition: fom.c:1324
#define M0_ASSERT(cond)
const char * scf_name
Definition: sm.h:352
M0_INTERNAL void m0_be_dtm0_log_pmsg_post(struct m0_be_dtm0_log *log, struct m0_fop *fop)
Definition: dtm0_log.c:637
void m0_fom_phase_move(struct m0_fom *fom, int32_t rc, int phase)
Definition: fom.c:1699
struct m0_fid rs_service_fid
Definition: reqh_service.h:220
uint32_t scf_nr_states
Definition: sm.h:354
M0_INTERNAL void m0_be_tx_credit_add(struct m0_be_tx_credit *c0, const struct m0_be_tx_credit *c1)
Definition: tx_credit.c:44
static const struct m0_fom_type_ops dtm0_req_fom_type_ops
Definition: fop.c:96
void * f_opaque
Definition: fop.h:84
Definition: reqh.h:94
Definition: dump.c:103
M0_INTERNAL void m0_dtm0_fop_fini(void)
Definition: fop.c:100
M0_INTERNAL void m0_fop_fini(struct m0_fop *fop)
Definition: fop.c:136
struct m0_fid p_fid
Definition: tx_desc.h:110
struct m0_fop_type dtm0_redo_fop_fopt
Definition: fop.c:44
#define FID_P(f)
Definition: fid.h:77
int dtf_thrall_rc
Definition: fop.c:50
Definition: cas.h:372
static void dtm0_fom_fini(struct m0_fom *fom)
Definition: fop.c:268
static int dtm0_fom_create(struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: fop.c:211
static const struct m0_fom_ops dtm0_rmsg_fom_ops
Definition: fop.c:76
struct m0_fop * m0_fop_reply_alloc(struct m0_fop *req, struct m0_fop_type *rept)
Definition: fop.c:129
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
M0_INTERNAL int m0_dtm0_tx_desc_copy(const struct m0_dtm0_tx_desc *src, struct m0_dtm0_tx_desc *dst)
Definition: tx_desc.c:76
Definition: fom.h:481
#define PRIu32
Definition: types.h:66
struct m0_dtm0_tx_pa * dtp_pa
Definition: tx_desc.h:117
struct m0_pdclust_tgt_addr tgt
Definition: fd.c:110
Definition: fop.h:46
struct m0_reqh reqh
Definition: rm_foms.c:48
const char * sd_name
Definition: sm.h:383
struct m0_sm_state_descr dtm0_phases[]
Definition: fop.c:115
struct m0_sm_state_descr * scf_state
Definition: sm.h:356
static int dtm0_pmsg_fom_tick(struct m0_fom *fom)
Definition: fop.c:385
Definition: fid.h:38
M0_INTERNAL int m0_be_dtm0_log_update(struct m0_be_dtm0_log *log, struct m0_be_tx *tx, struct m0_dtm0_tx_desc *txd, struct m0_buf *payload)
Definition: dtm0_log.c:460
M0_INTERNAL void m0_fop_release(struct m0_ref *ref)
Definition: fop.c:148
static int dtm0_cas_fop_prepare(struct dtm0_req_fop *req, struct m0_fop_type *cas_fopt, struct m0_fop **cas_fop_out)
Definition: fop.c:533
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL void m0_be_dtm0_log_credit(enum m0_be_dtm0_log_credit_op op, struct m0_dtm0_tx_desc *txd, struct m0_buf *payload, struct m0_be_seg *seg, struct m0_dtm0_log_rec *rec, struct m0_be_tx_credit *accum)
Definition: dtm0_log.c:202
struct m0_fid dti_fid
Definition: tx_desc.h:95
int m0_fop_type_addb2_instrument(struct m0_fop_type *type)
Definition: fop.c:461
M0_INTERNAL int m0_xcode_obj_dec_from_buf(struct m0_xcode_obj *obj, void *buf, m0_bcount_t len)
Definition: xcode.c:850
static struct m0_net_test_service svc
Definition: service.c:34
M0_INTERNAL int m0_fom_rc(const struct m0_fom *fom)
Definition: fom.c:1727
M0_INTERNAL struct m0_dtm0_service * m0_dtm0_fom2service(struct m0_fom *fom)
Definition: service.c:88
struct m0_sm_trans_descr m0_generic_phases_trans[]
Definition: fom_generic.c:765
static struct m0_fop * fop
Definition: item.c:57
M0_INTERNAL void m0_be_queue_lock(struct m0_be_queue *bq)
Definition: stubs.c:321
static int dtm0_emsg_fom_tick(struct m0_fom *fom)
Definition: fop.c:462
struct m0_dtm0_tx_participants dtd_ps
Definition: tx_desc.h:122
static int dtm0_tmsg_fom_tick(struct m0_fom *fom)
Definition: fop.c:631
static size_t dtm0_fom_locality(const struct m0_fom *fom)
Definition: fop.c:276
void(* fo_fini)(struct m0_fom *fom)
Definition: fom.h:657
struct m0_fop * fo_rep_fop
Definition: fom.h:492
#define M0_ASSERT_INFO(cond, fmt,...)
#define M0_XCODE_OBJ(type, ptr)
Definition: xcode.h:962
M0_INTERNAL struct m0_fop_type cas_put_fopt
Definition: cas.c:48
static struct m0_cas_op * cas_op(const struct m0_fom *fom)
Definition: service.c:1761
bool dl_is_persistent
Definition: dtm0_log.h:194
M0_INTERNAL struct m0_dtm0_log_rec * m0_be_dtm0_log_find(struct m0_be_dtm0_log *log, const struct m0_dtm0_tid *id)
Definition: dtm0_log.c:270
#define out(...)
Definition: gen.c:41
void m0_fom_phase_set(struct m0_fom *fom, int phase)
Definition: fom.c:1688
M0_INTERNAL int m0_dtm0_logrec_update(struct m0_be_dtm0_log *log, struct m0_be_tx *tx, struct m0_dtm0_tx_desc *txd, struct m0_buf *payload)
Definition: fop.c:284
static struct m0_dtm_oper_descr reply
Definition: transmit.c:94
struct m0_mutex dl_lock
Definition: dtm0_log.h:198
Definition: net.c:93
void m0_free(void *data)
Definition: memory.c:146
M0_INTERNAL void m0_dtm0_tx_desc_fini(struct m0_dtm0_tx_desc *td)
Definition: tx_desc.c:111
struct m0_reqh_service dos_generic
Definition: service.h:45
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
struct m0_fop_type dtm0_req_fop_fopt
Definition: fop.c:42
static int dtm0_cas_fom_spawn(struct dtm0_fom *dfom, struct m0_fop *cas_fop, void(*on_cas_fom_complete)(struct m0_fom_thralldom *, struct m0_fom *))
Definition: fop.c:518
Definition: fop.h:79
struct m0_fom_thralldom dtf_thrall
Definition: fop.c:49
#define FID_F
Definition: fid.h:75
M0_INTERNAL struct m0_reqh * m0_fom_reqh(const struct m0_fom *fom)
Definition: fom.c:283
Definition: trace.h:478
const uint64_t payload[]
Definition: base.c:65
Definition: tx.h:280
M0_INTERNAL bool m0_dtm0_in_ut(void)
Definition: service.c:415
#define M0_IMPOSSIBLE(fmt,...)
struct m0_fop_type dtm0_rep_fop_fopt
Definition: fop.c:43