Motr  M0
history.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-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 
30 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_DTM
31 
32 #include "lib/trace.h"
33 #include "lib/bob.h"
34 #include "lib/assert.h"
35 #include "lib/misc.h" /* M0_IN, M0_SET0 */
36 #include "lib/memory.h"
37 #include "lib/errno.h" /* ENOMEM */
38 #include "lib/cookie.h"
39 
40 #include "dtm/dtm_internal.h"
41 #include "dtm/machine.h"
42 #include "dtm/remote.h"
43 #include "dtm/nucleus.h"
44 #include "dtm/history.h"
45 #include "dtm/update.h"
46 #include "dtm/dtm.h"
47 
48 static const struct m0_dtm_update_ops ch_close_ops;
49 static const struct m0_dtm_update_ops ch_noop_ops;
50 
51 M0_INTERNAL void m0_dtm_history_init(struct m0_dtm_history *history,
52  struct m0_dtm *dtm)
53 {
54  m0_dtm_hi_init(&history->h_hi, &dtm->d_nu);
55  cat_tlink_init(history);
56  exc_tlink_init(history);
57  m0_cookie_new(&history->h_gen);
58  M0_SET0(&history->h_remcookie);
59  history->h_max_ver = history->h_hi.hi_ver;
61 }
62 
63 M0_INTERNAL void m0_dtm_history_fini(struct m0_dtm_history *history)
64 {
66  exc_tlink_fini(history);
67  cat_tlink_fini(history);
68  m0_dtm_hi_fini(&history->h_hi);
69 }
70 
71 M0_INTERNAL bool m0_dtm_history_invariant(const struct m0_dtm_history *history)
72 {
73  const struct m0_dtm_history_type *htype =
74  history->h_ops != NULL ? history->h_ops->hio_type : NULL;
75  const struct m0_dtm_hi *hi = &history->h_hi;
76 #define H_STATE(field) (history->field->upd_up.up_state)
77  return
79  _0C(ergo(history->h_undo != NULL,
80  history->h_persistent == NULL &&
81  history->h_reint == NULL &&
82  history->h_reset == NULL)) &&
83  _0C(ergo(history->h_known != NULL,
84  H_STATE(h_known) >= M0_DOS_INPROGRESS)) &&
85  _0C(ergo(history->h_undo != NULL,
86  M0_IN(H_STATE(h_undo), (M0_DOS_VOLATILE,
87  M0_DOS_PERSISTENT)))) &&
88  _0C(ergo(history->h_persistent != NULL,
89  M0_IN(H_STATE(h_persistent), (M0_DOS_INPROGRESS,
90  M0_DOS_VOLATILE)))) &&
91  _0C(ergo(history->h_reint != NULL,
92  H_STATE(h_reint) == M0_DOS_INPROGRESS)) &&
93  _0C(ergo(history->h_reset != NULL,
94  M0_IN(H_STATE(h_reset), (M0_DOS_INPROGRESS,
96  M0_DOS_PERSISTENT)))) &&
97  _0C(ergo(history->h_reint != NULL && history->h_known != NULL,
98  update_is_earlier(history->h_known, history->h_reint))) &&
99  _0C(ergo(htype != NULL,
100  HISTORY_DTM(history)->d_htype[htype->hit_id] == htype)) &&
101  _0C(ergo(hi->hi_flags & M0_DHF_OWNED,
102  m0_tl_forall(hi, up, &hi->hi_ups,
103  up->up_ver <= history->h_max_ver)));
104 #undef H_STATE
105 }
106 
107 M0_INTERNAL void m0_dtm_history_persistent(struct m0_dtm_history *history,
108  m0_dtm_ver_t upto)
109 {
110  struct m0_dtm_up *up;
111 
112  history_lock(history);
113  M0_PRE(upto > 0);
115 
116  up = hi_find(&history->h_hi, upto);
117  if (up != NULL) {
118  history->h_persistent = up_update(up);
119  m0_dtm_history_balance(history);
120  }
122  history_unlock(history);
123 }
124 
125 M0_INTERNAL void m0_dtm_history_reset(struct m0_dtm_history *history,
126  m0_dtm_ver_t since)
127 {
128  struct m0_dtm_up *up;
129 
130  history_lock(history);
132 
133 
134  up = hi_find(&history->h_hi, since);
135  if (up != NULL) {
136  history->h_reset = up_update(up);
137  history->h_epoch++;
138  m0_dtm_history_balance(history);
139  }
141  history_unlock(history);
142 }
143 
144 M0_INTERNAL void m0_dtm_history_undo(struct m0_dtm_history *history,
145  m0_dtm_ver_t upto)
146 {
147  struct m0_dtm_up *up;
148 
149  history_lock(history);
151 
152  up = hi_find(&history->h_hi, upto);
153  if (up != NULL) {
154  history->h_undo = up_update(up);
155  history->h_epoch++;
156  m0_dtm_history_balance(history);
157  }
159  history_unlock(history);
160 }
161 
162 M0_INTERNAL void m0_dtm_history_close(struct m0_dtm_history *history)
163 {
164  history_lock(history);
165  history_close(history);
166  history_unlock(history);
167 }
168 
169 M0_INTERNAL void history_close(struct m0_dtm_history *history)
170 {
172  M0_PRE(!(history->h_hi.hi_flags & M0_DHF_CLOSED));
173  history->h_hi.hi_flags |= M0_DHF_CLOSED;
174 }
175 
176 M0_INTERNAL void m0_dtm_history_update_get(const struct m0_dtm_history *history,
177  enum m0_dtm_up_rule rule,
178  struct m0_dtm_update_data *data)
179 {
180  M0_PRE(M0_IN(rule, (M0_DUR_NOT, M0_DUR_INC, M0_DUR_SET)));
181 
182  data->da_rule = rule;
183  data->da_label = 0;
184  if (history->h_hi.hi_flags & M0_DHF_OWNED) {
185  data->da_orig_ver = history->h_max_ver;
186  data->da_ver = rule == M0_DUR_NOT ?
187  data->da_orig_ver : data->da_orig_ver + 1;
188  } else {
189  data->da_orig_ver = 0;
190  data->da_ver = 0;
191  }
192 }
193 
194 M0_INTERNAL m0_dtm_ver_t update_ver(const struct m0_dtm_update *update)
195 {
196  return up_ver(UPDATE_UP(update));
197 }
198 
199 M0_INTERNAL struct m0_dtm_history *hi_history(struct m0_dtm_hi *hi)
200 {
201  return hi != NULL ?
202  container_of(hi, struct m0_dtm_history, h_hi) : NULL;
203 }
204 
205 M0_INTERNAL struct m0_dtm_up *history_latest(struct m0_dtm_history *history)
206 {
207  return hi_latest(&history->h_hi);
208 }
209 
210 M0_INTERNAL struct m0_dtm_up *history_earliest(struct m0_dtm_history *history)
211 {
212  return hi_earliest(&history->h_hi);
213 }
214 
215 M0_INTERNAL void
217  const struct m0_dtm_history_type *ht)
218 {
219  M0_PRE(IS_IN_ARRAY(ht->hit_id, dtm->d_htype));
220  M0_PRE(dtm->d_htype[ht->hit_id] == NULL);
221  dtm->d_htype[ht->hit_id] = ht;
222 }
223 
224 M0_INTERNAL void
226  const struct m0_dtm_history_type *ht)
227 {
228  M0_PRE(IS_IN_ARRAY(ht->hit_id, dtm->d_htype));
229  M0_PRE(dtm->d_htype[ht->hit_id] == ht);
230  dtm->d_htype[ht->hit_id] = NULL;
231 }
232 
233 M0_INTERNAL const struct m0_dtm_history_type *
234 m0_dtm_history_type_find(struct m0_dtm *dtm, uint8_t id)
235 {
236  return IS_IN_ARRAY(id, dtm->d_htype) ? dtm->d_htype[id] : NULL;
237 }
238 
239 M0_INTERNAL void m0_dtm_history_pack(const struct m0_dtm_history *history,
240  struct m0_dtm_history_id *id)
241 {
242  id->hid_id = *history->h_ops->hio_id(history);
243  id->hid_htype = history->h_ops->hio_type->hit_rem_id;
244  id->hid_receiver = history->h_remcookie;
245  m0_cookie_init(&id->hid_sender, &history->h_gen);
246 }
247 
248 M0_INTERNAL int m0_dtm_history_unpack(struct m0_dtm *dtm,
249  const struct m0_dtm_history_id *id,
250  struct m0_dtm_history **out)
251 {
252  const struct m0_dtm_history_type *htype;
253  int result;
254 
255  htype = m0_dtm_history_type_find(dtm, id->hid_htype);
256  if (htype == NULL)
257  return M0_ERR_INFO(-EPROTO, "%i", id->hid_htype);
258 
259  /* !m0_cookie_is_null() && */
260  *out = m0_cookie_of(&id->hid_receiver, struct m0_dtm_history, h_gen);
261  result = *out != NULL ? 0 :
262  htype->hit_ops->hito_find(dtm, htype, &id->hid_id, out);
263  if (result == 0)
264  (*out)->h_remcookie = id->hid_sender;
265  return result;
266 }
267 
268 static void control_update_add(struct m0_dtm_history *history,
269  struct m0_dtm_oper *oper,
270  struct m0_dtm_update *cupdate,
271  enum m0_dtm_up_rule rule,
272  const struct m0_dtm_update_ops *ops)
273 {
274  struct m0_dtm_update_data udata;
275 
276  oper_lock(oper);
277 
279  M0_PRE(M0_IN(rule, (M0_DUR_NOT, M0_DUR_INC)));
280 
281  m0_dtm_history_update_get(history, rule, &udata);
282  m0_dtm_update_init(cupdate, history, oper, &udata);
283  cupdate->upd_ops = ops;
285  oper_unlock(oper);
286 }
287 
288 M0_INTERNAL void history_lock(const struct m0_dtm_history *history)
289 {
290  dtm_lock(HISTORY_DTM(history));
291 }
292 
293 M0_INTERNAL void history_unlock(const struct m0_dtm_history *history)
294 {
295  dtm_unlock(HISTORY_DTM(history));
296 }
297 
298 M0_INTERNAL void m0_dtm_history_add_nop(struct m0_dtm_history *history,
299  struct m0_dtm_oper *oper,
300  struct m0_dtm_update *cupdate)
301 {
302  control_update_add(history, oper, cupdate, M0_DUR_INC, &ch_noop_ops);
303 }
304 
305 static void clop_nop(struct m0_dtm_op *op)
306 {}
307 
308 static void clop_impossible(struct m0_dtm_op *op)
309 {
310  M0_IMPOSSIBLE("Unexpected op.");
311 }
312 
313 static const struct m0_dtm_op_ops clop_ops = {
314  .doo_ready = clop_nop,
315  .doo_late = clop_impossible,
316  .doo_miser = clop_impossible
317 };
318 
319 M0_INTERNAL void m0_dtm_history_add_close(struct m0_dtm_history *history,
320  struct m0_dtm_oper *oper,
321  struct m0_dtm_update *cupdate)
322 {
323  control_update_add(history, oper, cupdate, M0_DUR_INC, &ch_close_ops);
324  oper->oprt_op.op_ops = &clop_ops;
325  m0_dtm_oper_close(oper);
326 }
327 
328 M0_INTERNAL void m0_dtm_controlh_init(struct m0_dtm_controlh *ch,
329  struct m0_dtm *dtm)
330 {
331  struct m0_tl uu;
332 
333  m0_dtm_history_init(&ch->ch_history, dtm);
335  m0_dtm_update_link(&uu, &ch->ch_clup_rem, 1);
336  m0_dtm_oper_init(&ch->ch_clop, dtm, &uu);
338 }
339 
340 M0_INTERNAL void m0_dtm_controlh_fini(struct m0_dtm_controlh *ch)
341 {
342  m0_dtm_oper_fini(&ch->ch_clop);
343  m0_dtm_history_fini(&ch->ch_history);
344 }
345 
346 M0_INTERNAL void m0_dtm_controlh_close(struct m0_dtm_controlh *ch)
347 {
348  m0_dtm_history_add_close(&ch->ch_history, &ch->ch_clop, &ch->ch_clup);
349  m0_dtm_oper_prepared(&ch->ch_clop, ch->ch_history.h_rem);
350 }
351 
352 M0_INTERNAL void m0_dtm_controlh_add(struct m0_dtm_controlh *ch,
353  struct m0_dtm_oper *oper)
354 {
355  struct m0_dtm_update *update = oper_tlist_pop(&oper->oprt_uu);
356 
357  M0_PRE(update != NULL);
358  m0_dtm_history_add_nop(&ch->ch_history, oper, update);
359 }
360 
361 enum {
362  H_NOOP = 1,
364 };
365 
366 static int ch_noop(struct m0_dtm_update *updt)
367 {
368  return 0;
369 }
370 
371 static const struct m0_dtm_update_type ch_noop_utype = {
372  .updtt_id = H_NOOP,
373  .updtt_name = "noop"
374 };
375 
376 static const struct m0_dtm_update_ops ch_noop_ops = {
377  .updo_redo = &ch_noop,
378  .updo_undo = &ch_noop,
379  .updo_type = &ch_noop_utype
380 };
381 
382 static const struct m0_dtm_update_type ch_close_utype = {
383  .updtt_id = H_CLOSE,
384  .updtt_name = "close"
385 };
386 
387 static const struct m0_dtm_update_ops ch_close_ops = {
388  .updo_redo = &ch_noop,
389  .updo_undo = &ch_noop,
390  .updo_type = &ch_close_utype
391 };
392 
393 M0_INTERNAL int m0_dtm_controlh_update(struct m0_dtm_history *history,
394  uint8_t id,
395  struct m0_dtm_update *update)
396 {
397  if (id == H_NOOP)
398  update->upd_ops = &ch_noop_ops;
399  else if (id == H_CLOSE)
400  update->upd_ops = &ch_close_ops;
401  else
402  return M0_ERR_INFO(-EPROTO, "%i", id);
403  return 0;
404 }
405 
406 M0_INTERNAL void m0_dtm_controlh_fuse_close(struct m0_dtm_update *update)
407 {
408  M0_PRE(update->upd_ops == &ch_noop_ops);
409  update->upd_ops = &ch_close_ops;
411 }
412 
413 M0_INTERNAL bool
415 {
416  M0_PRE(M0_IN(update->upd_ops, (&ch_noop_ops, &ch_close_ops)));
417  return update->upd_ops == &ch_close_ops;
418 }
419 
420 M0_TL_DESCR_DEFINE(exc, "excited histories", M0_INTERNAL,
421  struct m0_dtm_history, h_exclink,
422  h_hi.hi_ups.t_magic, M0_DTM_HI_MAGIX, M0_DTM_EXC_MAGIX);
423 M0_TL_DEFINE(exc, M0_INTERNAL, struct m0_dtm_history);
424 
425 M0_INTERNAL void history_print_header(const struct m0_dtm_history *history,
426  char *buf)
427 {
428  static struct m0_uint128 null_id = M0_UINT128(0xfe0f, 0xfe0d);
429  struct m0_uint128 hid = *history->h_ops->hio_id(history);
430  struct m0_uint128 *rid = history->h_rem != NULL ?
431  &history->h_rem->re_id : &null_id;
432 
433  sprintf(buf, "%s@%p["U128X_F"]->["U128X_F"]",
434  history->h_ops->hio_type->hit_name, history,
435  U128_P(&hid), U128_P(rid));
436 }
437 
438 M0_INTERNAL void history_print(const struct m0_dtm_history *history)
439 {
440  char buf[100];
441 
442  history_print_header(history, buf);
443  M0_LOG(M0_FATAL, "history %s", &buf[0]);
444  history_for(history, update) {
445  update_print_internal(update,
446  update->upd_up.up_hi != &history->h_hi);
447  } history_endfor;
448 }
449 
450 #undef M0_TRACE_SUBSYSTEM
451 
454 /*
455  * Local variables:
456  * c-indentation-style: "K&R"
457  * c-basic-offset: 8
458  * tab-width: 8
459  * fill-column: 80
460  * scroll-step: 1
461  * End:
462  */
463 /*
464  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
465  */
M0_INTERNAL void history_print_header(const struct m0_dtm_history *history, char *buf)
Definition: history.c:425
uint64_t id
Definition: cob.h:2380
const struct m0_dtm_history_type_ops * hit_ops
Definition: history.h:91
struct m0_dtm_update * h_known
Definition: history.h:63
#define M0_PRE(cond)
M0_INTERNAL void update_print_internal(const struct m0_dtm_update *update, bool history)
Definition: update.c:297
M0_INTERNAL m0_dtm_ver_t up_ver(const struct m0_dtm_up *up)
Definition: nucleus.c:405
const struct m0_uint128 *(* hio_id)(const struct m0_dtm_history *history)
Definition: history.h:80
m0_dtm_up_rule
Definition: nucleus.h:84
M0_INTERNAL void m0_dtm_controlh_fini(struct m0_dtm_controlh *ch)
Definition: history.c:340
#define NULL
Definition: misc.h:38
M0_INTERNAL const struct m0_dtm_history_type * m0_dtm_history_type_find(struct m0_dtm *dtm, uint8_t id)
Definition: history.c:234
#define ergo(a, b)
Definition: misc.h:293
static const struct m0_dtm_update_ops ch_noop_ops
Definition: history.c:49
M0_INTERNAL bool m0_dtm_hi_invariant(const struct m0_dtm_hi *hi)
Definition: nucleus.c:436
uint64_t hi_flags
Definition: nucleus.h:65
struct m0_dtm_remote * h_rem
Definition: history.h:59
M0_INTERNAL void m0_dtm_controlh_init(struct m0_dtm_controlh *ch, struct m0_dtm *dtm)
Definition: history.c:328
#define M0_LOG(level,...)
Definition: trace.h:167
struct m0_cookie h_remcookie
Definition: history.h:68
#define UPDATE_UP(update)
Definition: dtm_internal.h:97
M0_INTERNAL void m0_dtm_oper_init(struct m0_dtm_oper *oper, struct m0_dtm *dtm, struct m0_tl *uu)
Definition: operation.c:44
uint8_t hit_id
Definition: history.h:88
struct m0_bufvec data
Definition: di.c:40
M0_INTERNAL void m0_dtm_controlh_close(struct m0_dtm_controlh *ch)
Definition: history.c:346
struct m0_dtm_op oprt_op
Definition: operation.h:48
M0_INTERNAL void m0_dtm_oper_prepared(const struct m0_dtm_oper *oper, const struct m0_dtm_remote *rem)
Definition: operation.c:122
static void control_update_add(struct m0_dtm_history *history, struct m0_dtm_oper *oper, struct m0_dtm_update *cupdate, enum m0_dtm_up_rule rule, const struct m0_dtm_update_ops *ops)
Definition: history.c:268
struct m0_dtm_update * h_reint
Definition: history.h:62
struct m0_dtm_hi h_hi
Definition: history.h:56
M0_INTERNAL struct m0_dtm_up * hi_find(struct m0_dtm_hi *hi, m0_dtm_ver_t ver)
Definition: nucleus.c:396
M0_INTERNAL struct m0_dtm_up * history_earliest(struct m0_dtm_history *history)
Definition: history.c:210
#define container_of(ptr, type, member)
Definition: misc.h:33
#define M0_SET0(obj)
Definition: misc.h:64
static const struct m0_dtm_update_type ch_close_utype
Definition: history.c:382
M0_INTERNAL struct m0_dtm_update * up_update(struct m0_dtm_up *up)
Definition: update.c:228
M0_INTERNAL void dtm_lock(struct m0_dtm *dtm)
Definition: dtm.c:159
M0_INTERNAL void m0_dtm_history_fini(struct m0_dtm_history *history)
Definition: history.c:63
const struct m0_dtm_update_ops * upd_ops
Definition: update.h:74
Definition: sock.c:887
M0_INTERNAL struct m0_dtm_history * hi_history(struct m0_dtm_hi *hi)
Definition: history.c:199
static const struct m0_dtm_update_type ch_noop_utype
Definition: history.c:371
op
Definition: libdemo.c:64
M0_INTERNAL void history_lock(const struct m0_dtm_history *history)
Definition: history.c:288
M0_INTERNAL void m0_dtm_update_link(struct m0_tl *list, struct m0_dtm_update *update, uint32_t nr)
Definition: update.c:221
M0_INTERNAL void m0_dtm_history_balance(struct m0_dtm_history *history)
Definition: machine.c:63
M0_TL_DESCR_DEFINE(exc, "excited histories", M0_INTERNAL, struct m0_dtm_history, h_exclink, h_hi.hi_ups.t_magic, M0_DTM_HI_MAGIX, M0_DTM_EXC_MAGIX)
M0_INTERNAL void m0_dtm_history_type_register(struct m0_dtm *dtm, const struct m0_dtm_history_type *ht)
Definition: history.c:216
M0_INTERNAL bool update_is_earlier(struct m0_dtm_update *update0, struct m0_dtm_update *update1)
Definition: update.c:234
M0_INTERNAL void m0_dtm_history_undo(struct m0_dtm_history *history, m0_dtm_ver_t upto)
Definition: history.c:144
#define M0_ERR_INFO(rc, fmt,...)
Definition: trace.h:215
struct m0_dtm_update * h_persistent
Definition: history.h:60
#define UPDATE_HISTORY(update)
Definition: dtm_internal.h:104
const struct m0_dtm_op_ops * op_ops
Definition: nucleus.h:108
M0_INTERNAL void m0_dtm_history_persistent(struct m0_dtm_history *history, m0_dtm_ver_t upto)
Definition: history.c:107
M0_INTERNAL int m0_dtm_history_unpack(struct m0_dtm *dtm, const struct m0_dtm_history_id *id, struct m0_dtm_history **out)
Definition: history.c:248
static void clop_nop(struct m0_dtm_op *op)
Definition: history.c:305
uint64_t h_gen
Definition: history.h:66
#define H_STATE(field)
#define history_endfor
Definition: dtm_internal.h:93
uint64_t m0_dtm_ver_t
Definition: nucleus.h:48
struct m0_dtm_update * h_reset
Definition: history.h:64
M0_INTERNAL void m0_dtm_history_close(struct m0_dtm_history *history)
Definition: history.c:162
#define U128_P(x)
Definition: types.h:45
#define HISTORY_DTM(history)
Definition: dtm_internal.h:106
Definition: tlist.h:251
struct m0_dtm_nu d_nu
Definition: dtm.h:533
M0_INTERNAL bool m0_dtm_controlh_update_is_close(const struct m0_dtm_update *update)
Definition: history.c:414
const char * hit_name
Definition: history.h:90
static const struct m0_dtm_update_ops ch_close_ops
Definition: history.c:48
#define M0_POST(cond)
M0_INTERNAL void m0_dtm_hi_fini(struct m0_dtm_hi *hi)
Definition: nucleus.c:277
M0_INTERNAL m0_dtm_ver_t update_ver(const struct m0_dtm_update *update)
Definition: history.c:194
M0_INTERNAL void m0_dtm_history_reset(struct m0_dtm_history *history, m0_dtm_ver_t since)
Definition: history.c:125
M0_INTERNAL void history_close(struct m0_dtm_history *history)
Definition: history.c:169
const struct m0_dtm_history_type * d_htype[M0_DTM_HISTORY_TYPE_NR]
Definition: dtm.h:544
M0_INTERNAL void m0_dtm_history_type_deregister(struct m0_dtm *dtm, const struct m0_dtm_history_type *ht)
Definition: history.c:225
M0_INTERNAL void m0_dtm_history_add_close(struct m0_dtm_history *history, struct m0_dtm_oper *oper, struct m0_dtm_update *cupdate)
Definition: history.c:319
void(* doo_ready)(struct m0_dtm_op *op)
Definition: nucleus.h:113
M0_INTERNAL void m0_dtm_history_pack(const struct m0_dtm_history *history, struct m0_dtm_history_id *id)
Definition: history.c:239
M0_INTERNAL void oper_unlock(const struct m0_dtm_oper *oper)
Definition: operation.c:288
static int ch_noop(struct m0_dtm_update *updt)
Definition: history.c:366
#define U128X_F
Definition: types.h:42
M0_INTERNAL void history_unlock(const struct m0_dtm_history *history)
Definition: history.c:293
struct m0_uint128 re_id
Definition: remote.h:55
M0_INTERNAL void m0_dtm_update_init(struct m0_dtm_update *update, struct m0_dtm_history *history, struct m0_dtm_oper *oper, const struct m0_dtm_update_data *data)
Definition: update.c:47
M0_INTERNAL bool m0_dtm_history_invariant(const struct m0_dtm_history *history)
Definition: history.c:71
static const struct m0_dtm_op_ops clop_ops
Definition: history.c:313
struct m0_tl oprt_uu
Definition: operation.h:49
int(* hito_find)(struct m0_dtm *dtm, const struct m0_dtm_history_type *ht, const struct m0_uint128 *id, struct m0_dtm_history **out)
Definition: history.h:95
const struct m0_dtm_history_type * hio_type
Definition: history.h:79
M0_INTERNAL void m0_dtm_controlh_fuse_close(struct m0_dtm_update *update)
Definition: history.c:406
m0_dtm_ver_t hi_ver
Definition: nucleus.h:66
M0_INTERNAL int m0_dtm_controlh_update(struct m0_dtm_history *history, uint8_t id, struct m0_dtm_update *update)
Definition: history.c:393
M0_INTERNAL void m0_dtm_history_update_get(const struct m0_dtm_history *history, enum m0_dtm_up_rule rule, struct m0_dtm_update_data *data)
Definition: history.c:176
M0_INTERNAL void m0_dtm_oper_close(struct m0_dtm_oper *oper)
Definition: operation.c:83
M0_INTERNAL void m0_dtm_update_list_fini(struct m0_tl *list)
Definition: update.c:182
M0_INTERNAL void dtm_unlock(struct m0_dtm *dtm)
Definition: dtm.c:164
#define _0C(exp)
Definition: assert.h:311
uint64_t h_epoch
Definition: history.h:67
#define IS_IN_ARRAY(idx, array)
Definition: misc.h:311
static const struct m0_dtm_history_type htype
Definition: dtx.c:131
#define history_for(h, update)
Definition: dtm_internal.h:87
M0_INTERNAL void m0_dtm_history_init(struct m0_dtm_history *history, struct m0_dtm *dtm)
Definition: history.c:51
struct m0_dtm_update * h_undo
Definition: history.h:61
#define M0_UINT128(hi, lo)
Definition: types.h:40
Definition: dtm.h:529
M0_INTERNAL void m0_dtm_oper_fini(struct m0_dtm_oper *oper)
Definition: operation.c:58
static struct m0_tl uu
Definition: dtx.c:65
M0_INTERNAL void m0_dtm_update_list_init(struct m0_tl *list)
Definition: update.c:177
M0_INTERNAL void m0_dtm_hi_init(struct m0_dtm_hi *hi, struct m0_dtm_nu *nu)
Definition: nucleus.c:268
uint8_t updtt_id
Definition: update.h:91
static void clop_impossible(struct m0_dtm_op *op)
Definition: history.c:308
#define out(...)
Definition: gen.c:41
M0_INTERNAL struct m0_dtm_up * hi_earliest(struct m0_dtm_hi *hi)
Definition: nucleus.c:390
struct m0_fom_ops ops
Definition: io_foms.c:623
M0_INTERNAL void m0_dtm_controlh_add(struct m0_dtm_controlh *ch, struct m0_dtm_oper *oper)
Definition: history.c:352
static const struct m0_uint128 * hid(const struct m0_dtm_history *history)
Definition: dtx.c:138
M0_INTERNAL void m0_dtm_history_add_nop(struct m0_dtm_history *history, struct m0_dtm_oper *oper, struct m0_dtm_update *cupdate)
Definition: history.c:298
m0_dtm_ver_t h_max_ver
Definition: history.h:69
uint8_t hit_rem_id
Definition: history.h:89
static void hi(void)
Definition: nucleus.c:93
M0_INTERNAL void oper_lock(const struct m0_dtm_oper *oper)
Definition: operation.c:283
M0_TL_DEFINE(exc, M0_INTERNAL, struct m0_dtm_history)
M0_INTERNAL void history_print(const struct m0_dtm_history *history)
Definition: history.c:438
#define m0_tl_forall(name, var, head,...)
Definition: tlist.h:735
const struct m0_dtm_history_ops * h_ops
Definition: history.h:65
#define M0_IMPOSSIBLE(fmt,...)
int(* updo_redo)(struct m0_dtm_update *updt)
Definition: update.h:84
M0_INTERNAL struct m0_dtm_up * hi_latest(struct m0_dtm_hi *hi)
Definition: nucleus.c:385
M0_INTERNAL struct m0_dtm_up * history_latest(struct m0_dtm_history *history)
Definition: history.c:205