Motr  M0
dtm0_log.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 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_DTM0
23 #include "be/dtm0_log.h"
24 #include "be/alloc.h"
25 #include "dtm0/clk_src.h"
26 #include "lib/buf.h"
27 #include "be/list.h"
28 #include "be/op.h"
29 #include "be/tx.h"
30 #include "be/tx_credit.h"
31 #include "be/seg.h"
32 #include "lib/assert.h" /* M0_PRE */
33 #include "lib/errno.h" /* ENOENT */
34 #include "lib/memory.h" /* M0_ALLOC */
35 #include "lib/trace.h"
36 #include "dtm0/fop.h" /* dtm0_req_fop */
37 #include "motr/magic.h"
38 
39 
40 M0_TL_DESCR_DEFINE(lrec, "DTM0 Log", static, struct m0_dtm0_log_rec,
41  u.dlr_tlink, dlr_magic, M0_BE_DTM0_LOG_REC_MAGIX,
43 M0_TL_DEFINE(lrec, static, struct m0_dtm0_log_rec);
44 
45 
46 M0_BE_LIST_DESCR_DEFINE(lrec, "DTM0 PLog", static, struct m0_dtm0_log_rec,
47  u.dlr_link, dlr_magic, M0_BE_DTM0_LOG_REC_MAGIX,
49 M0_BE_LIST_DEFINE(lrec, static, struct m0_dtm0_log_rec);
50 
51 
52 static bool m0_be_dtm0_log__invariant(const struct m0_be_dtm0_log *log)
53 {
54  return _0C(log != NULL) &&
55  _0C(log->dl_cs != NULL);
56  /* TODO: Add an invariant check against the volatile part */
57  /* _0C(lrec_tlist_invariant(log->u.dl_inmem)); */
58 }
59 
60 static bool m0_dtm0_log_rec__invariant(const struct m0_dtm0_log_rec *rec)
61 {
62  return _0C(rec != NULL) &&
64  /* _0C(m0_tlink_invariant(&lrec_tl, rec)); */
65 }
66 
70 M0_INTERNAL int m0_be_dtm0_log_alloc(struct m0_be_dtm0_log **out)
71 {
72  struct m0_be_dtm0_log *log;
73 
74  M0_PRE(out != NULL);
75 
76  M0_ALLOC_PTR(log);
77  if (log == NULL)
78  return M0_ERR(-ENOMEM);
79 
80  M0_ALLOC_PTR(log->u.dl_inmem);
81  if (log->u.dl_inmem == NULL) {
82  m0_free(log);
83  return M0_ERR(-ENOMEM);
84  }
85  lrec_tlist_init(log->u.dl_inmem);
86  *out = log;
87  return 0;
88 }
89 
90 /*
91  * Intialize a dtm0 log. log should point to a pre-allocated
92  * dtm0_log structure.
93  */
94 M0_INTERNAL int m0_be_dtm0_log_init(struct m0_be_dtm0_log *log,
95  struct m0_be_seg *seg,
96  struct m0_dtm0_clk_src *cs,
97  bool is_plog)
98 {
99  M0_PRE(log != NULL);
100  M0_PRE(cs != NULL);
101  M0_PRE(equi(is_plog, seg != NULL));
102 
103  m0_mutex_init(&log->dl_lock);
104  log->dl_is_persistent = is_plog;
105  log->dl_cs = cs;
106  log->dl_seg = seg;
107 
108  return 0;
109 }
110 
111 M0_INTERNAL void m0_be_dtm0_log_fini(struct m0_be_dtm0_log *log)
112 {
114  m0_mutex_fini(&log->dl_lock);
115  lrec_tlist_fini(log->u.dl_inmem);
116  log->dl_cs = NULL;
117 }
118 
119 M0_INTERNAL void m0_be_dtm0_log_free(struct m0_be_dtm0_log **in_log)
120 {
121  struct m0_be_dtm0_log *log = *in_log;
122 
123  M0_PRE(!log->dl_is_persistent);
124 
125  m0_free(log->u.dl_inmem);
126  m0_free(log);
127  *in_log = NULL;
128 }
129 
137  struct m0_be_seg *seg,
138  struct m0_be_tx_credit *accum)
139 {
140  struct m0_dtm0_log_rec *rec;
141 
142  /* allocate a new record */
143  M0_BE_ALLOC_CREDIT_PTR(rec, seg, accum);
144  /* allocate .dlr_txd.dtd_ps.dtp_pa[] */
146  txd->dtd_ps.dtp_nr, seg, accum);
147  /* create .u.dlr_link */
148  lrec_be_list_credit(M0_BLO_TLINK_CREATE, 1, accum);
149  /* update m0_be_dtm0_log::dl_persist */
150  m0_be_list_credit(M0_BLO_ADD, 1, accum);
151 }
152 
153 /*
154  * Calculate credits for a full update.
155  * A full update carries enough information to replay the corresponding
156  * transaction -- it contains tx_desc and the payload (serialised request).
157  */
159  struct m0_buf *payload,
160  struct m0_be_seg *seg,
161  struct m0_be_tx_credit *accum)
162 {
163  log_rec_partial_insert_credit(txd, seg, accum);
165 }
166 
167 static void log_rec_del_credit(struct m0_be_seg *seg,
168  struct m0_dtm0_log_rec *rec,
169  struct m0_be_tx_credit *accum)
170 {
171  m0_be_list_credit(M0_BLO_DEL, 1, accum);
172  lrec_be_list_credit(M0_BLO_TLINK_DESTROY, 1, accum);
174  rec->dlr_txd.dtd_ps.dtp_nr, seg, accum);
176  M0_BE_FREE_CREDIT_PTR(rec, seg, accum);
177 }
178 
179 M0_INTERNAL void log_destroy_credit(struct m0_be_seg *seg,
180  struct m0_be_tx_credit *accum)
181 {
182  lrec_be_list_credit(M0_BLO_DESTROY, 1, accum);
183  /* TODO: add entries for the other components of the structure */
184 }
185 
186 static void log_create_credit(struct m0_be_seg *seg,
187  struct m0_be_tx_credit *accum)
188 {
189  /* log ptr */
190  M0_BE_ALLOC_CREDIT_PTR((struct m0_be_dtm0_log *) NULL, seg, accum);
191  /* log obj */
192  m0_be_tx_credit_add(accum,
194  /* log->dl_seg ptr */
195  M0_BE_ALLOC_CREDIT_PTR((struct m0_be_seg *) NULL, seg, accum);
196  /* log->dl_persist ptr */
197  M0_BE_ALLOC_CREDIT_PTR((struct m0_be_list *) NULL, seg, accum);
198  /* log->dl_persist obj */
199  lrec_be_list_credit(M0_BLO_CREATE, 1, accum);
200 }
201 
203  struct m0_dtm0_tx_desc *txd,
204  struct m0_buf *payload,
205  struct m0_be_seg *seg,
206  struct m0_dtm0_log_rec *rec,
207  struct m0_be_tx_credit *accum)
208 {
209  switch (op) {
210  case M0_DTML_CREATE:
211  log_create_credit(seg, accum);
212  break;
213  /*
214  * A note about PERSISTENT and EXECUTED credits.
215  * There are two cases -- insert a new record (1) and
216  * update an existing record (2).
217  * Insert (by definition) is a "subset" of update. In other
218  * words, the insert scenario should take more credits than
219  * the amount of credits required for the update scenario.
220  * So that, we consider only the worst case here (insert).
221  */
222  case M0_DTML_PERSISTENT:
223  log_rec_partial_insert_credit(txd, seg, accum);
224  break;
225  case M0_DTML_EXECUTED:
226  log_rec_full_insert_credit(txd, payload, seg, accum);
227  break;
228  case M0_DTML_PRUNE:
229  log_rec_del_credit(seg, rec, accum);
230  break;
231  case M0_DTML_REDO:
232  default:
233  M0_IMPOSSIBLE("");
234  }
235 }
236 
237 M0_INTERNAL int m0_be_dtm0_log_create(struct m0_be_tx *tx,
238  struct m0_be_seg *seg,
239  struct m0_be_dtm0_log **out)
240 {
241  struct m0_be_dtm0_log *log;
242 
243  M0_PRE(tx != NULL);
244  M0_PRE(seg != NULL);
245 
246  M0_BE_ALLOC_PTR_SYNC(log, seg, tx);
247  M0_ASSERT(log != NULL);
248 
250  M0_ASSERT(log->u.dl_persist != NULL);
251 
252  log->dl_seg = seg;
253 
254  lrec_be_list_create(log->u.dl_persist, tx);
255  M0_BE_TX_CAPTURE_PTR(seg, tx, log);
256  *out = log;
257  return 0;
258 }
259 
260 M0_INTERNAL void m0_be_dtm0_log_destroy(struct m0_be_tx *tx,
261  struct m0_be_dtm0_log **log)
262 {
263  /*
264  * TODO: write down the implementation to destroy persistent
265  * implementation.
266  */
267 }
268 
269 M0_INTERNAL
271  const struct m0_dtm0_tid *id)
272 {
276 
277  if (log->dl_is_persistent) {
278  struct m0_dtm0_log_rec *lrec;
279 
280  m0_be_list_for(lrec, log->u.dl_persist, lrec) {
281  if (m0_dtm0_tid_cmp(log->dl_cs, &lrec->dlr_txd.dtd_id,
282  id) == M0_DTS_EQ)
283  break;
285  return lrec;
286  } else {
287  return m0_tl_find(lrec, rec, log->u.dl_inmem,
288  m0_dtm0_tid_cmp(log->dl_cs,
289  &rec->dlr_txd.dtd_id,
290  id) == M0_DTS_EQ);
291  }
292 }
293 
294 static int log_rec_init(struct m0_dtm0_log_rec **rec,
295  struct m0_be_tx *tx,
296  struct m0_dtm0_tx_desc *txd,
297  struct m0_buf *payload)
298 {
299  int rc;
300  struct m0_dtm0_log_rec *lrec;
301 
302  M0_ALLOC_PTR(lrec);
303  if (lrec == NULL)
304  return M0_ERR(-ENOMEM);
305 
306  rc = m0_dtm0_tx_desc_copy(txd, &lrec->dlr_txd);
307  if (rc != 0) {
308  m0_free(lrec);
309  return rc;
310  }
311 
312  rc = m0_buf_copy(&lrec->dlr_payload, payload);
313  if (rc != 0) {
315  m0_free(lrec);
316  return rc;
317  }
318 
319  *rec = lrec;
320  return 0;
321 }
322 
323 static int plog_rec_init(struct m0_dtm0_log_rec **out,
324  struct m0_be_tx *tx,
325  struct m0_be_seg *seg,
326  struct m0_dtm0_tx_desc *txd,
327  struct m0_buf *payload)
328 {
329  struct m0_dtm0_log_rec *rec;
330 
331  M0_BE_ALLOC_PTR_SYNC(rec, seg, tx);
332  M0_ASSERT(rec != NULL);
333 
334  rec->dlr_txd.dtd_id = txd->dtd_id;
335  rec->dlr_txd.dtd_ps.dtp_nr = txd->dtd_ps.dtp_nr;
337  txd->dtd_ps.dtp_nr, seg, tx);
339 
340  memcpy(rec->dlr_txd.dtd_ps.dtp_pa, txd->dtd_ps.dtp_pa,
341  sizeof(rec->dlr_txd.dtd_ps.dtp_pa[0]) * rec->dlr_txd.dtd_ps.dtp_nr);
342 
343  if (payload->b_nob > 0) {
344  rec->dlr_payload.b_nob = payload->b_nob;
346  M0_ASSERT(&rec->dlr_payload.b_addr != NULL); /* TODO: handle error */
349  } else {
350  rec->dlr_payload.b_addr = NULL;
351  rec->dlr_payload.b_nob = 0;
352  }
353 
355  rec->dlr_txd.dtd_ps.dtp_pa,
356  rec->dlr_txd.dtd_ps.dtp_nr);
357  M0_BE_TX_CAPTURE_PTR(seg, tx, rec);
358 
359  *out = rec;
360  return 0;
361 }
362 
363 /*
364  * TODO: change convention of this function to:
365  * void log_rec_fini(struct m0_dtm0_log_rec *rec, ..*tx)
366  * and free rec outside the function
367  */
368 static void log_rec_fini(struct m0_dtm0_log_rec **rec,
369  struct m0_be_tx *tx)
370 {
371  struct m0_dtm0_log_rec *lrec = *rec;
372 
373  M0_ASSERT_INFO(M0_IS0(&lrec->dlr_dtx), "DTX should have been finalised "
374  "already in m0_dtx0_done().");
375  m0_buf_free(&lrec->dlr_payload);
377  m0_free(lrec);
378  *rec = NULL;
379 }
380 
381 /*
382  * TODO: change convention of this function to:
383  * void plog_rec_fini(struct m0_dtm0_log_rec *rec, ..*tx)
384  * and allocate rec outside the function
385  */
386 static void plog_rec_fini(struct m0_dtm0_log_rec **dl_lrec,
387  struct m0_be_dtm0_log *log,
388  struct m0_be_tx *tx)
389 {
390  struct m0_be_seg *seg = log->dl_seg;
391  struct m0_dtm0_log_rec *rec = *dl_lrec;
392 
395  M0_BE_FREE_PTR_SYNC(rec, seg, tx);
396  *dl_lrec = NULL;
397 }
398 
399 static int dtm0_log__insert(struct m0_be_dtm0_log *log,
400  struct m0_be_tx *tx,
401  struct m0_dtm0_tx_desc *txd,
402  struct m0_buf *payload)
403 {
404  int rc;
405  struct m0_dtm0_log_rec *rec;
406  struct m0_be_seg *seg = log->dl_seg;
407 
408  if (log->dl_is_persistent) {
409  rc = plog_rec_init(&rec, tx, seg, txd, payload);
410  if (rc != 0)
411  return rc;
412  lrec_be_tlink_create(rec, tx);
413  lrec_be_list_add_tail(log->u.dl_persist, tx, rec);
414  } else {
415  rc = log_rec_init(&rec, tx, txd, payload);
416  if (rc != 0)
417  return rc;
418  lrec_tlink_init_at_tail(rec, log->u.dl_inmem);
419  }
420 
421  return rc;
422 }
423 
424 static int dtm0_log__set(struct m0_be_dtm0_log *log,
425  struct m0_be_tx *tx,
426  const struct m0_dtm0_tx_desc *txd,
427  const struct m0_buf *payload,
428  struct m0_dtm0_log_rec *rec)
429 {
430  bool is_persistent = log->dl_is_persistent;
431  struct m0_buf *lpayload = &rec->dlr_payload;
432  struct m0_be_seg *seg = log->dl_seg;
433 
435 
436  /* Attach payload to log if it is not attached */
437  if (!m0_buf_is_set(lpayload) && m0_buf_is_set(payload)) {
438  if (is_persistent) {
439  lpayload->b_nob = payload->b_nob;
440  M0_BE_ALLOC_BUF_SYNC(lpayload, seg, tx);
441  M0_ASSERT(lpayload != NULL);
442  m0_buf_memcpy(lpayload, payload);
443  M0_BE_TX_CAPTURE_BUF(seg, tx, lpayload);
444  M0_BE_TX_CAPTURE_PTR(seg, tx, lpayload);
445  } else {
446  m0_buf_copy(lpayload, payload);
447  }
448  }
449 
450  m0_dtm0_tx_desc_apply(&rec->dlr_txd, txd);
452  if (is_persistent) {
454  rec->dlr_txd.dtd_ps.dtp_nr);
455  }
456 
457  return 0;
458 }
459 
460 M0_INTERNAL int m0_be_dtm0_log_update(struct m0_be_dtm0_log *log,
461  struct m0_be_tx *tx,
462  struct m0_dtm0_tx_desc *txd,
463  struct m0_buf *payload)
464 {
465  struct m0_dtm0_log_rec *rec;
466 
467  M0_PRE(payload != NULL);
471 
472  return (rec = m0_be_dtm0_log_find(log, &txd->dtd_id)) ?
473  dtm0_log__set(log, tx, txd, payload, rec) :
474  dtm0_log__insert(log, tx, txd, payload);
475 }
476 
477 M0_INTERNAL int m0_be_dtm0_log_prune(struct m0_be_dtm0_log *log,
478  struct m0_be_tx *tx,
479  const struct m0_dtm0_tid *id)
480 {
481  /* This assignment is meaningful as it covers the empty log case */
482  int rc = M0_DTS_LT;
483  struct m0_dtm0_log_rec *rec;
484  struct m0_dtm0_log_rec *currec;
485 
489 
490  /*
491  * Iterate over the log records from the begining and check whether all
492  * the records preceeding this are persistent. If not, we cannot prune
493  * the record with the given id.
494  */
495 
496  m0_tl_for (lrec, log->u.dl_inmem, rec) {
499  return M0_ERR(-EPROTO);
500 
501  rc = m0_dtm0_tid_cmp(log->dl_cs, &rec->dlr_txd.dtd_id, id);
502  if (rc != M0_DTS_LT)
503  break;
504  } m0_tl_endfor;
505 
506  if (rc != M0_DTS_EQ)
507  return -ENOENT;
508 
509  /* rec is a pointer to the record matching the input id. Delete all the
510  * previous records and then this record. */
511  while ((currec = lrec_tlist_pop(log->u.dl_inmem)) != rec) {
513  log_rec_fini(&currec, tx);
514  }
515 
516  log_rec_fini(&rec, tx);
517  return rc;
518 }
519 
520 M0_INTERNAL void m0_be_dtm0_log_clear(struct m0_be_dtm0_log *log)
521 {
522  struct m0_dtm0_log_rec *rec;
523 
524  /* This function is expected to be called only on the client side where
525  * the log will always be a volatile log.
526  * TBD: can we change the name of dl_is_persistent to something more
527  * intutive.
528  */
530 
531  m0_tl_teardown(lrec, log->u.dl_inmem, rec) {
535  log_rec_fini(&rec, NULL);
536  }
537  M0_POST(lrec_tlist_is_empty(log->u.dl_inmem));
538 }
539 
540 M0_INTERNAL int m0_be_dtm0_volatile_log_insert(struct m0_be_dtm0_log *log,
541  struct m0_dtm0_log_rec *rec)
542 {
543  int rc;
544 
545  M0_ENTRY();
546  /* TODO: dissolve dlr_txd and remove this code */
547  rc = m0_dtm0_tx_desc_copy(&rec->dlr_dtx.dd_txd, &rec->dlr_txd);
548  if (rc != 0)
549  return M0_ERR(rc);
550 
551  lrec_tlink_init_at_tail(rec, log->u.dl_inmem);
552  return M0_RC(rc);
553 }
554 
555 M0_INTERNAL void m0_be_dtm0_volatile_log_update(struct m0_be_dtm0_log *log,
556  struct m0_dtm0_log_rec *rec)
557 {
558  /* TODO: dissolve dlr_txd and remove this code */
560 }
561 
573 M0_INTERNAL bool m0_be_dtm0_plog_can_prune(struct m0_be_dtm0_log *log,
574  const struct m0_dtm0_tid *id,
575  struct m0_be_tx_credit *accum)
576 {
577  /* This assignment is meaningful as it covers the empty log case */
578  int rc = M0_DTS_LT;
579  struct m0_dtm0_log_rec *rec;
580  struct m0_be_list *persist = log->u.dl_persist;
581  struct m0_be_tx_credit cred = M0_BE_TX_CREDIT(0, 0);
582 
586 
587  m0_be_list_for(lrec, persist, rec) {
590  return false;
591 
592  if (accum != NULL)
594  log->dl_seg, rec, &cred);
595 
596  rc = m0_dtm0_tid_cmp(log->dl_cs, &rec->dlr_txd.dtd_id, id);
597  if (rc != M0_DTS_LT)
598  break;
600 
601  if (rc != M0_DTS_EQ)
602  return false;
603  if (accum != NULL)
604  m0_be_tx_credit_add(accum, &cred);
605 
606  return true;
607 }
608 
609 M0_INTERNAL int m0_be_dtm0_plog_prune(struct m0_be_dtm0_log *log,
610  struct m0_be_tx *tx,
611  const struct m0_dtm0_tid *id)
612 {
613  struct m0_dtm0_log_rec *rec;
614  struct m0_dtm0_tid cur_id = {};
615 
619 
620  m0_be_list_for(lrec, log->u.dl_persist, rec) {
621  cur_id = rec->dlr_txd.dtd_id;
622 
623  lrec_be_list_del(log->u.dl_persist, tx, rec);
624  lrec_be_tlink_destroy(rec, tx);
625  plog_rec_fini(&rec, log, tx);
626  if (m0_dtm0_tid_cmp(log->dl_cs, &cur_id, id) == M0_DTS_EQ)
627  break;
629 
630  /*
631  * TODO: change the function signature to void if we are always going to
632  * returning 0.
633  */
634  return 0;
635 }
636 
637 M0_INTERNAL void m0_be_dtm0_log_pmsg_post(struct m0_be_dtm0_log *log,
638  struct m0_fop *fop)
639 {
640  struct m0_dtm0_log_rec *rec;
641  struct dtm0_req_fop *req = m0_fop_data(fop);
642  const struct m0_dtm0_tx_desc *txd = &req->dtr_txr;
643  bool is_persistent;
644 
645  M0_PRE(log != NULL);
646  M0_PRE(!log->dl_is_persistent);
649 
650  M0_ENTRY();
651 
652  m0_mutex_lock(&log->dl_lock);
653  rec = m0_be_dtm0_log_find(log, &txd->dtd_id);
654  /* TODO: We do not handle the case where a P msg is received before
655  * the corresponding DTX enters INPROGRESS state.
656  */
657  M0_ASSERT_INFO(rec != NULL, "Log record must be inserted into the log "
658  "in m0_dtx0_close().");
659  is_persistent = m0_dtm0_tx_desc_state_eq(&rec->dlr_txd,
661  m0_mutex_unlock(&log->dl_lock);
662  /* NOTE: we do not need to hold the global mutex any longer
663  * because of the following assumptions:
664  * 1. Log record cannot be removed unless it is stable.
665  * We explicitly check that.
666  * 2. The log record linkage is not shared with dtx_post_persistent,
667  * i.e. it should not try to remove or insert records.
668  * This point is not enforced.
669  */
670  if (!is_persistent)
672 
673  M0_LEAVE();
674 }
675 
676 #undef M0_TRACE_SUBSYSTEM
677 
680 /*
681  * Local variables:
682  * c-indentation-style: "K&R"
683  * c-basic-offset: 8
684  * tab-width: 8
685  * fill-column: 80
686  * scroll-step: 1
687  * End:
688  */
689 /*
690  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
691  */
#define M0_BE_ALLOC_CREDIT_PTR(ptr, seg, accum)
Definition: alloc.h:355
#define M0_PRE(cond)
#define M0_BE_ALLOC_PTR_SYNC(ptr, seg, tx)
Definition: alloc.h:339
M0_INTERNAL bool m0_buf_is_set(const struct m0_buf *buf)
Definition: buf.c:127
static void plog_rec_fini(struct m0_dtm0_log_rec **dl_lrec, struct m0_be_dtm0_log *log, struct m0_be_tx *tx)
Definition: dtm0_log.c:386
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
M0_INTERNAL bool m0_be_dtm0_plog_can_prune(struct m0_be_dtm0_log *log, const struct m0_dtm0_tid *id, struct m0_be_tx_credit *accum)
Definition: dtm0_log.c:573
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_be_dtm0_log_free(struct m0_be_dtm0_log **in_log)
Definition: dtm0_log.c:119
struct m0_dtm0_dtx dlr_dtx
Definition: dtm0_log.h:161
M0_BE_LIST_DESCR_DEFINE(lrec, "DTM0 PLog", static, struct m0_dtm0_log_rec, u.dlr_link, dlr_magic, M0_BE_DTM0_LOG_REC_MAGIX, M0_BE_DTM0_LOG_MAGIX)
void * b_addr
Definition: buf.h:39
struct m0_tl * dl_inmem
Definition: dtm0_log.h:206
M0_INTERNAL void m0_dtm0_dtx_pmsg_post(struct m0_dtm0_dtx *dtx, struct m0_fop *fop)
Definition: dtx.c:371
static struct io_request req
Definition: file.c:100
union @126 u
M0_LEAVE()
#define M0_BE_ALLOC_CREDIT_ARR(arr, nr, seg, accum)
Definition: alloc.h:363
struct m0_dtm0_tx_desc dlr_txd
Definition: dtm0_log.h:162
static void log_create_credit(struct m0_be_seg *seg, struct m0_be_tx_credit *accum)
Definition: dtm0_log.c:186
struct m0_be_seg * dl_seg
Definition: dtm0_log.h:199
#define M0_BE_ALLOC_BUF_SYNC(buf, seg, tx)
Definition: alloc.h:352
void * m0_fop_data(const struct m0_fop *fop)
Definition: fop.c:220
M0_INTERNAL void m0_be_dtm0_log_fini(struct m0_be_dtm0_log *log)
Definition: dtm0_log.c:111
#define M0_BE_TX_CAPTURE_PTR(seg, tx, ptr)
Definition: tx.h:505
M0_INTERNAL bool m0_dtm0_tx_desc__invariant(const struct m0_dtm0_tx_desc *td)
Definition: tx_desc.c:49
#define M0_BE_TX_CREDIT_TYPE(type)
Definition: tx_credit.h:97
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
#define M0_BE_TX_CAPTURE_ARR(seg, tx, arr, nr)
Definition: tx.h:507
M0_INTERNAL void m0_be_dtm0_volatile_log_update(struct m0_be_dtm0_log *log, struct m0_dtm0_log_rec *rec)
Definition: dtm0_log.c:555
M0_INTERNAL int m0_be_dtm0_plog_prune(struct m0_be_dtm0_log *log, struct m0_be_tx *tx, const struct m0_dtm0_tid *id)
Definition: dtm0_log.c:609
struct m0_buf dlr_payload
Definition: dtm0_log.h:178
M0_INTERNAL void m0_be_dtm0_log_clear(struct m0_be_dtm0_log *log)
Definition: dtm0_log.c:520
M0_INTERNAL void m0_buf_memcpy(struct m0_buf *dst, const struct m0_buf *src)
Definition: buf.c:96
#define m0_tl_endfor
Definition: tlist.h:700
return M0_RC(rc)
op
Definition: libdemo.c:64
#define equi(a, b)
Definition: misc.h:297
M0_INTERNAL void m0_dtm0_tx_desc_apply(struct m0_dtm0_tx_desc *tgt, const struct m0_dtm0_tx_desc *upd)
Definition: tx_desc.c:127
#define M0_BE_TX_CREDIT(nr, size)
Definition: tx_credit.h:94
struct m0_dtm0_tid dtd_id
Definition: tx_desc.h:121
#define M0_ENTRY(...)
Definition: trace.h:170
Definition: buf.h:37
static int dtm0_log__insert(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:399
struct m0_fop_type * f_type
Definition: fop.h:81
static int plog_rec_init(struct m0_dtm0_log_rec **out, struct m0_be_tx *tx, struct m0_be_seg *seg, struct m0_dtm0_tx_desc *txd, struct m0_buf *payload)
Definition: dtm0_log.c:323
return M0_ERR(-EOPNOTSUPP)
struct m0_be_list * dl_persist
Definition: dtm0_log.h:204
M0_INTERNAL int m0_be_dtm0_volatile_log_insert(struct m0_be_dtm0_log *log, struct m0_dtm0_log_rec *rec)
Definition: dtm0_log.c:540
#define m0_tl_teardown(name, head, obj)
Definition: tlist.h:708
M0_INTERNAL int m0_be_dtm0_log_init(struct m0_be_dtm0_log *log, struct m0_be_seg *seg, struct m0_dtm0_clk_src *cs, bool is_plog)
Definition: dtm0_log.c:94
#define M0_BE_TX_CAPTURE_BUF(seg, tx, buf)
Definition: tx.h:509
m0_bcount_t b_nob
Definition: buf.h:38
M0_INTERNAL int m0_be_dtm0_log_create(struct m0_be_tx *tx, struct m0_be_seg *seg, struct m0_be_dtm0_log **out)
Definition: dtm0_log.c:237
#define M0_ASSERT(cond)
M0_INTERNAL bool m0_mutex_is_locked(const struct m0_mutex *mutex)
Definition: mutex.c:95
M0_INTERNAL int m0_be_dtm0_log_alloc(struct m0_be_dtm0_log **out)
Definition: dtm0_log.c:70
M0_INTERNAL void m0_be_dtm0_log_pmsg_post(struct m0_be_dtm0_log *log, struct m0_fop *fop)
Definition: dtm0_log.c:637
union m0_be_dtm0_log::@31 u
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
M0_INTERNAL bool m0_dtm0_tid__invariant(const struct m0_dtm0_tid *tid)
Definition: tx_desc.c:68
static void log_rec_del_credit(struct m0_be_seg *seg, struct m0_dtm0_log_rec *rec, struct m0_be_tx_credit *accum)
Definition: dtm0_log.c:167
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
M0_INTERNAL void m0_be_dtm0_log_destroy(struct m0_be_tx *tx, struct m0_be_dtm0_log **log)
Definition: dtm0_log.c:260
#define M0_POST(cond)
m0_be_dtm0_log_credit_op
Definition: dtm0_log.h:141
M0_TL_DESCR_DEFINE(lrec, "DTM0 Log", static, struct m0_dtm0_log_rec, u.dlr_tlink, dlr_magic, M0_BE_DTM0_LOG_REC_MAGIX, M0_BE_DTM0_LOG_MAGIX)
M0_INTERNAL void m0_buf_free(struct m0_buf *buf)
Definition: buf.c:55
M0_INTERNAL int m0_be_dtm0_log_prune(struct m0_be_dtm0_log *log, struct m0_be_tx *tx, const struct m0_dtm0_tid *id)
Definition: dtm0_log.c:477
#define M0_BE_FREE_PTR_SYNC(ptr, seg, tx)
Definition: alloc.h:345
Definition: seg.h:66
M0_INTERNAL int m0_buf_copy(struct m0_buf *dest, const struct m0_buf *src)
Definition: buf.c:104
M0_BE_LIST_DEFINE(lrec, static, struct m0_dtm0_log_rec)
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
static void log_rec_partial_insert_credit(struct m0_dtm0_tx_desc *txd, struct m0_be_seg *seg, struct m0_be_tx_credit *accum)
Definition: dtm0_log.c:136
struct m0_dtm0_tx_pa * dtp_pa
Definition: tx_desc.h:117
M0_INTERNAL void log_destroy_credit(struct m0_be_seg *seg, struct m0_be_tx_credit *accum)
Definition: dtm0_log.c:179
static bool m0_dtm0_log_rec__invariant(const struct m0_dtm0_log_rec *rec)
Definition: dtm0_log.c:60
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
#define M0_IS0(obj)
Definition: misc.h:70
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_DTPS_PERSISTENT
Definition: tx_desc.h:164
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
#define _0C(exp)
Definition: assert.h:311
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
#define M0_BE_ALLOC_ARR_SYNC(arr, nr, seg, tx)
Definition: alloc.h:335
M0_INTERNAL int m0_dtm0_tid_cmp(struct m0_dtm0_clk_src *cs, const struct m0_dtm0_tid *left, const struct m0_dtm0_tid *right)
Definition: tx_desc.c:119
static struct m0_fop * fop
Definition: item.c:57
struct m0_dtm0_clk_src * dl_cs
Definition: dtm0_log.h:201
#define m0_be_list_endfor
Definition: list.h:369
M0_INTERNAL bool m0_dtm0_tx_desc_state_eq(const struct m0_dtm0_tx_desc *txd, enum m0_dtm0_tx_pa_state state)
Definition: tx_desc.c:155
struct m0_dtm0_tx_participants dtd_ps
Definition: tx_desc.h:122
static struct m0_be_seg * seg
Definition: btree.c:40
static int dtm0_log__set(struct m0_be_dtm0_log *log, struct m0_be_tx *tx, const struct m0_dtm0_tx_desc *txd, const struct m0_buf *payload, struct m0_dtm0_log_rec *rec)
Definition: dtm0_log.c:424
#define M0_ASSERT_INFO(cond, fmt,...)
static void log_rec_full_insert_credit(struct m0_dtm0_tx_desc *txd, struct m0_buf *payload, struct m0_be_seg *seg, struct m0_be_tx_credit *accum)
Definition: dtm0_log.c:158
static bool m0_be_dtm0_log__invariant(const struct m0_be_dtm0_log *log)
Definition: dtm0_log.c:52
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
#define m0_tl_find(name, var, head,...)
Definition: tlist.h:757
struct m0_mutex dl_lock
Definition: dtm0_log.h:198
#define m0_tl_for(name, head, obj)
Definition: tlist.h:695
void m0_free(void *data)
Definition: memory.c:146
static int log_rec_init(struct m0_dtm0_log_rec **rec, struct m0_be_tx *tx, struct m0_dtm0_tx_desc *txd, struct m0_buf *payload)
Definition: dtm0_log.c:294
M0_INTERNAL void m0_dtm0_tx_desc_fini(struct m0_dtm0_tx_desc *td)
Definition: tx_desc.c:111
int32_t rc
Definition: trigger_fop.h:47
struct m0_fop_type dtm0_req_fop_fopt
Definition: fop.c:42
#define M0_BE_FREE_CREDIT_ARR(arr, nr, seg, accum)
Definition: alloc.h:367
M0_INTERNAL void m0_be_list_credit(enum m0_be_list_op optype, m0_bcount_t nr, struct m0_be_tx_credit *accum)
Definition: list.c:56
#define m0_be_list_for(name, head, obj)
Definition: list.h:358
#define M0_BE_FREE_CREDIT_PTR(ptr, seg, accum)
Definition: alloc.h:359
static void log_rec_fini(struct m0_dtm0_log_rec **rec, struct m0_be_tx *tx)
Definition: dtm0_log.c:368
Definition: fop.h:79
M0_TL_DEFINE(lrec, static, struct m0_dtm0_log_rec)
struct m0_dtm0_tx_desc dd_txd
Definition: dtx.h:62
const uint64_t payload[]
Definition: base.c:65
Definition: tx.h:280
#define M0_IMPOSSIBLE(fmt,...)
#define M0_BE_ALLOC_CREDIT_BUF(buf, seg, accum)
Definition: alloc.h:371