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 static void log_rec_fini(struct m0_dtm0_log_rec *rec,
364  struct m0_be_tx *tx)
365 {
366  M0_ASSERT_INFO(M0_IS0(&rec->dlr_dtx), "DTX should have been finalised "
367  "already in m0_dtx0_done().");
368  m0_buf_free(&rec->dlr_payload);
370  m0_free(rec);
371 }
372 
373 /*
374  * TODO: change convention of this function to:
375  * void plog_rec_fini(struct m0_dtm0_log_rec *rec, ..*tx)
376  * and allocate rec outside the function
377  */
378 static void plog_rec_fini(struct m0_dtm0_log_rec **dl_lrec,
379  struct m0_be_dtm0_log *log,
380  struct m0_be_tx *tx)
381 {
382  struct m0_be_seg *seg = log->dl_seg;
383  struct m0_dtm0_log_rec *rec = *dl_lrec;
384 
387  M0_BE_FREE_PTR_SYNC(rec, seg, tx);
388  *dl_lrec = NULL;
389 }
390 
391 static int dtm0_log__insert(struct m0_be_dtm0_log *log,
392  struct m0_be_tx *tx,
393  struct m0_dtm0_tx_desc *txd,
394  struct m0_buf *payload)
395 {
396  int rc;
397  struct m0_dtm0_log_rec *rec;
398  struct m0_be_seg *seg = log->dl_seg;
399 
400  if (log->dl_is_persistent) {
401  rc = plog_rec_init(&rec, tx, seg, txd, payload);
402  if (rc != 0)
403  return rc;
404  lrec_be_tlink_create(rec, tx);
405  lrec_be_list_add_tail(log->u.dl_persist, tx, rec);
406  } else {
407  rc = log_rec_init(&rec, tx, txd, payload);
408  if (rc != 0)
409  return rc;
410  lrec_tlink_init_at_tail(rec, log->u.dl_inmem);
411  }
412 
413  return rc;
414 }
415 
416 static int dtm0_log__set(struct m0_be_dtm0_log *log,
417  struct m0_be_tx *tx,
418  const struct m0_dtm0_tx_desc *txd,
419  const struct m0_buf *payload,
420  struct m0_dtm0_log_rec *rec)
421 {
422  bool is_persistent = log->dl_is_persistent;
423  struct m0_buf *lpayload = &rec->dlr_payload;
424  struct m0_be_seg *seg = log->dl_seg;
425 
427 
428  /* Attach payload to log if it is not attached */
429  if (!m0_buf_is_set(lpayload) && m0_buf_is_set(payload)) {
430  if (is_persistent) {
431  lpayload->b_nob = payload->b_nob;
432  M0_BE_ALLOC_BUF_SYNC(lpayload, seg, tx);
433  M0_ASSERT(lpayload != NULL);
434  m0_buf_memcpy(lpayload, payload);
435  M0_BE_TX_CAPTURE_BUF(seg, tx, lpayload);
436  M0_BE_TX_CAPTURE_PTR(seg, tx, lpayload);
437  } else {
438  m0_buf_copy(lpayload, payload);
439  }
440  }
441 
442  m0_dtm0_tx_desc_apply(&rec->dlr_txd, txd);
444  if (is_persistent) {
446  rec->dlr_txd.dtd_ps.dtp_nr);
447  }
448 
449  return 0;
450 }
451 
452 M0_INTERNAL int m0_be_dtm0_log_update(struct m0_be_dtm0_log *log,
453  struct m0_be_tx *tx,
454  struct m0_dtm0_tx_desc *txd,
455  struct m0_buf *payload)
456 {
457  struct m0_dtm0_log_rec *rec;
458 
459  M0_PRE(payload != NULL);
463 
464  return (rec = m0_be_dtm0_log_find(log, &txd->dtd_id)) ?
465  dtm0_log__set(log, tx, txd, payload, rec) :
466  dtm0_log__insert(log, tx, txd, payload);
467 }
468 
469 M0_INTERNAL int m0_be_dtm0_log_prune(struct m0_be_dtm0_log *log,
470  struct m0_be_tx *tx,
471  const struct m0_dtm0_tid *id)
472 {
473  /* This assignment is meaningful as it covers the empty log case */
474  int rc = M0_DTS_LT;
475  struct m0_dtm0_log_rec *rec;
476  struct m0_dtm0_log_rec *currec;
477 
481 
482  /*
483  * Iterate over the log records from the begining and check whether all
484  * the records preceeding this are persistent. If not, we cannot prune
485  * the record with the given id.
486  */
487 
488  m0_tl_for (lrec, log->u.dl_inmem, rec) {
491  return M0_ERR(-EPROTO);
492 
493  rc = m0_dtm0_tid_cmp(log->dl_cs, &rec->dlr_txd.dtd_id, id);
494  if (rc != M0_DTS_LT)
495  break;
496  } m0_tl_endfor;
497 
498  if (rc != M0_DTS_EQ)
499  return -ENOENT;
500 
501  /* rec is a pointer to the record matching the input id. Delete all the
502  * previous records and then this record. */
503  while ((currec = lrec_tlist_pop(log->u.dl_inmem)) != rec) {
505  log_rec_fini(currec, tx);
506  }
507 
508  log_rec_fini(rec, tx);
509  return rc;
510 }
511 
512 M0_INTERNAL void m0_be_dtm0_log_clear(struct m0_be_dtm0_log *log)
513 {
514  struct m0_dtm0_log_rec *rec;
515 
516  /* This function is expected to be called only on the client side where
517  * the log will always be a volatile log.
518  * TBD: can we change the name of dl_is_persistent to something more
519  * intutive.
520  */
522 
523  m0_mutex_lock(&log->dl_lock);
524 
525  m0_tl_teardown(lrec, log->u.dl_inmem, rec) {
529  log_rec_fini(rec, NULL);
530  }
531  M0_POST(lrec_tlist_is_empty(log->u.dl_inmem));
532 
533  m0_mutex_unlock(&log->dl_lock);
534 }
535 
536 M0_INTERNAL int m0_be_dtm0_volatile_log_insert(struct m0_be_dtm0_log *log,
537  struct m0_dtm0_log_rec *rec)
538 {
539  int rc;
540 
541  M0_ENTRY();
542  /* TODO: dissolve dlr_txd and remove this code */
543  rc = m0_dtm0_tx_desc_copy(&rec->dlr_dtx.dd_txd, &rec->dlr_txd);
544  if (rc != 0)
545  return M0_ERR(rc);
546 
547  lrec_tlink_init_at_tail(rec, log->u.dl_inmem);
548  return M0_RC(rc);
549 }
550 
551 M0_INTERNAL void m0_be_dtm0_volatile_log_update(struct m0_be_dtm0_log *log,
552  struct m0_dtm0_log_rec *rec)
553 {
554  /* TODO: dissolve dlr_txd and remove this code */
556 }
557 
558 M0_INTERNAL void m0_be_dtm0_volatile_log_del(struct m0_be_dtm0_log *log,
559  struct m0_dtm0_log_rec *rec,
560  bool fini)
561 {
563 
564  lrec_tlist_del(rec);
565  if (fini)
566  log_rec_fini(rec, NULL);
567 }
568 
580 M0_INTERNAL bool m0_be_dtm0_plog_can_prune(struct m0_be_dtm0_log *log,
581  const struct m0_dtm0_tid *id,
582  struct m0_be_tx_credit *accum)
583 {
584  /* This assignment is meaningful as it covers the empty log case */
585  int rc = M0_DTS_LT;
586  struct m0_dtm0_log_rec *rec;
587  struct m0_be_list *persist = log->u.dl_persist;
588  struct m0_be_tx_credit cred = M0_BE_TX_CREDIT(0, 0);
589 
593 
594  m0_be_list_for(lrec, persist, rec) {
597  return false;
598 
599  if (accum != NULL)
601  log->dl_seg, rec, &cred);
602 
603  rc = m0_dtm0_tid_cmp(log->dl_cs, &rec->dlr_txd.dtd_id, id);
604  if (rc != M0_DTS_LT)
605  break;
607 
608  if (rc != M0_DTS_EQ)
609  return false;
610  if (accum != NULL)
611  m0_be_tx_credit_add(accum, &cred);
612 
613  return true;
614 }
615 
616 M0_INTERNAL int m0_be_dtm0_plog_prune(struct m0_be_dtm0_log *log,
617  struct m0_be_tx *tx,
618  const struct m0_dtm0_tid *id)
619 {
620  struct m0_dtm0_log_rec *rec;
621  struct m0_dtm0_tid cur_id = {};
622 
626 
627  m0_be_list_for(lrec, log->u.dl_persist, rec) {
628  cur_id = rec->dlr_txd.dtd_id;
629 
630  lrec_be_list_del(log->u.dl_persist, tx, rec);
631  lrec_be_tlink_destroy(rec, tx);
632  plog_rec_fini(&rec, log, tx);
633  if (m0_dtm0_tid_cmp(log->dl_cs, &cur_id, id) == M0_DTS_EQ)
634  break;
636 
637  /*
638  * TODO: change the function signature to void if we are always going to
639  * returning 0.
640  */
641  return 0;
642 }
643 
644 static const struct m0_dtm0_tid dtm0_log_iter_tid0 =
645  (struct m0_dtm0_tid) { .dti_ts = { .dts_phys = ~0 } };
646 
647 static bool be_dtm0_log_iter_is_first(const struct m0_be_dtm0_log_iter *iter)
648 {
649  return memcmp(&iter->dli_current_tid, &dtm0_log_iter_tid0,
650  sizeof iter->dli_current_tid) == 0;
651 }
652 
653 static bool be_dtm0_log_iter_invariant(const struct m0_be_dtm0_log_iter *iter)
654 {
655  return _0C(m0_be_dtm0_log__invariant(iter->dli_log)) &&
658 }
659 
660 M0_INTERNAL void m0_be_dtm0_log_iter_init(struct m0_be_dtm0_log_iter *iter,
661  struct m0_be_dtm0_log *log)
662 {
663  iter->dli_log = log;
666 }
667 
668 M0_INTERNAL void m0_be_dtm0_log_iter_fini(struct m0_be_dtm0_log_iter *iter)
669 {
671 }
672 
673 M0_INTERNAL int m0_be_dtm0_log_iter_next(struct m0_be_dtm0_log_iter *iter,
674  struct m0_dtm0_log_rec *out)
675 {
676  struct m0_dtm0_log_rec *rec;
677  int rc;
678 
681  M0_ENTRY();
682 
683  if (be_dtm0_log_iter_is_first(iter))
684  rec = iter->dli_log->dl_is_persistent
685  ? lrec_be_list_head(iter->dli_log->u.dl_persist)
686  : lrec_tlist_head(iter->dli_log->u.dl_inmem);
687  else {
688  rec = m0_be_dtm0_log_find(iter->dli_log,
689  &iter->dli_current_tid);
690  rec = iter->dli_log->dl_is_persistent
691  ? lrec_be_list_next(iter->dli_log->u.dl_persist, rec)
692  : lrec_tlist_next(iter->dli_log->u.dl_inmem, rec);
693  }
694 
695  if (rec != NULL) {
696  iter->dli_current_tid = rec->dlr_txd.dtd_id;
697  rc = m0_dtm0_log_rec_copy(out, rec);
698  if (rc != 0)
699  return M0_ERR(rc);
700  }
701 
702  return M0_RC(rec == NULL ? 0 : +1);
703 }
704 
705 M0_INTERNAL int m0_dtm0_log_rec_copy(struct m0_dtm0_log_rec *dst,
706  const struct m0_dtm0_log_rec *src)
707 {
708  M0_SET0(dst);
709  return m0_dtm0_tx_desc_copy(&src->dlr_txd, &dst->dlr_txd) ?:
710  m0_buf_copy(&dst->dlr_payload, &src->dlr_payload);
711 }
712 
713 M0_INTERNAL void m0_dtm0_log_iter_rec_fini(struct m0_dtm0_log_rec *rec)
714 {
716  m0_buf_free(&rec->dlr_payload);
717 }
718 
719 #undef M0_TRACE_SUBSYSTEM
720 
723 /*
724  * Local variables:
725  * c-indentation-style: "K&R"
726  * c-basic-offset: 8
727  * tab-width: 8
728  * fill-column: 80
729  * scroll-step: 1
730  * End:
731  */
732 /*
733  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
734  */
#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:378
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:580
#define NULL
Definition: misc.h:38
static struct m0_bufvec dst
Definition: xform.c:61
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:208
static void log_rec_fini(struct m0_dtm0_log_rec *rec, struct m0_be_tx *tx)
Definition: dtm0_log.c:363
union @126 u
#define M0_BE_ALLOC_CREDIT_ARR(arr, nr, seg, accum)
Definition: alloc.h:363
static bool be_dtm0_log_iter_is_first(const struct m0_be_dtm0_log_iter *iter)
Definition: dtm0_log.c:647
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:201
#define M0_BE_ALLOC_BUF_SYNC(buf, seg, tx)
Definition: alloc.h:352
struct m0_dtm0_ts dti_ts
Definition: tx_desc.h:94
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:497
M0_INTERNAL bool m0_dtm0_tx_desc__invariant(const struct m0_dtm0_tx_desc *td)
Definition: tx_desc.c:49
#define M0_SET0(obj)
Definition: misc.h:64
struct m0_be_dtm0_log * dli_log
Definition: dtm0_log.h:533
#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:499
static bool be_dtm0_log_iter_invariant(const struct m0_be_dtm0_log_iter *iter)
Definition: dtm0_log.c:653
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:551
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:616
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:512
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:126
#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:391
m0_time_t dts_phys
Definition: clk_src.h:93
M0_INTERNAL int m0_be_dtm0_log_iter_next(struct m0_be_dtm0_log_iter *iter, struct m0_dtm0_log_rec *out)
Definition: dtm0_log.c:673
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:206
M0_INTERNAL void m0_be_dtm0_volatile_log_del(struct m0_be_dtm0_log *log, struct m0_dtm0_log_rec *rec, bool fini)
Definition: dtm0_log.c:558
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:536
#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:501
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
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:67
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
M0_INTERNAL void m0_dtm0_log_iter_rec_fini(struct m0_dtm0_log_rec *rec)
Definition: dtm0_log.c:713
#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:469
#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:75
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 m0_be_dtm0_log_iter_init(struct m0_be_dtm0_log_iter *iter, struct m0_be_dtm0_log *log)
Definition: dtm0_log.c:660
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:452
#define M0_IS0(obj)
Definition: misc.h:70
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_DTPS_PERSISTENT
Definition: tx_desc.h:171
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:118
struct m0_dtm0_clk_src * dl_cs
Definition: dtm0_log.h:203
#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:154
struct m0_dtm0_tx_participants dtd_ps
Definition: tx_desc.h:122
int fini(struct workload *w)
static struct m0_be_seg * seg
Definition: btree.c:40
M0_INTERNAL void m0_be_dtm0_log_iter_fini(struct m0_be_dtm0_log_iter *iter)
Definition: dtm0_log.c:668
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:416
#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
static const struct m0_dtm0_tid dtm0_log_iter_tid0
Definition: dtm0_log.c:644
#define m0_tl_find(name, var, head,...)
Definition: tlist.h:757
struct m0_mutex dl_lock
Definition: dtm0_log.h:200
#define m0_tl_for(name, head, obj)
Definition: tlist.h:695
struct m0_dtm0_tid dli_current_tid
Definition: dtm0_log.h:534
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:110
struct m0_pdclust_src_addr src
Definition: fd.c:108
int32_t rc
Definition: trigger_fop.h:47
#define M0_BE_FREE_CREDIT_ARR(arr, nr, seg, accum)
Definition: alloc.h:367
M0_INTERNAL int m0_dtm0_log_rec_copy(struct m0_dtm0_log_rec *dst, const struct m0_dtm0_log_rec *src)
Definition: dtm0_log.c:705
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
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