Motr  M0
client.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2020-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 #include "lib/vec.h"
24 #include "lib/types.h"
25 #include "lib/memory.h" /* m0_alloc, m0_free */
26 #include "lib/errno.h" /* ENOMEM */
27 #include "sm/sm.h"
28 #include "layout/layout.h" /* m0_layout_instance_to_enum */
29 #include "ioservice/fid_convert.h" /* M0_FID_GOB_CONTAINER_MASK */
30 
31 #include "motr/addb.h"
32 #include "motr/client.h"
33 #include "motr/client_internal.h"
34 #include "motr/layout.h"
35 #include "motr/sync.h"
36 
37 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CLIENT
38 #include "lib/trace.h"
39 #include "lib/finject.h"
40 
44 const struct m0_bob_type oc_bobtype;
45 const struct m0_bob_type oo_bobtype;
46 const struct m0_bob_type op_bobtype;
47 
48 M0_BOB_DEFINE(M0_INTERNAL, &oc_bobtype, m0_op_common);
49 M0_BOB_DEFINE(M0_INTERNAL, &oo_bobtype, m0_op_obj);
50 M0_BOB_DEFINE(M0_INTERNAL, &op_bobtype, m0_op);
51 
52 const struct m0_bob_type oc_bobtype = {
53  .bt_name = "op_common_bobtype",
54  .bt_magix_offset = offsetof(struct m0_op_common, oc_magic),
55  .bt_magix = M0_OC_MAGIC,
56  .bt_check = NULL,
57 };
58 
59 const struct m0_bob_type oo_bobtype = {
60  .bt_name = "m0_op_obj_bobtype",
61  .bt_magix_offset = offsetof(struct m0_op_obj, oo_magic),
62  .bt_magix = M0_OO_MAGIC,
63  .bt_check = NULL,
64 };
65 
66 const struct m0_bob_type op_bobtype = {
67  .bt_name = "m0_op_bobtype",
68  .bt_magix_offset = offsetof(struct m0_op, op_magic),
69  .bt_magix = M0_OP_MAGIC,
70  .bt_check = NULL,
71 };
72 
73 const struct m0_bob_type ar_bobtype;
74 M0_BOB_DEFINE(M0_INTERNAL, &ar_bobtype, m0_ast_rc);
75 const struct m0_bob_type ar_bobtype = {
76  .bt_name = "ar_bobtype",
77  .bt_magix_offset = offsetof(struct m0_ast_rc, ar_magic),
78  .bt_magix = M0_M0_AST_RC_MAGIC,
79  .bt_check = NULL,
80 };
81 
85 const struct m0_uint128 M0_UBER_REALM = {0UL, 1ULL};
86 M0_EXPORTED(M0_UBER_REALM);
87 
92 const struct m0_uint128 M0_ID_APP = { 0ULL, 0x100000ULL };
93 M0_EXPORTED(M0_ID_APP);
94 
95 enum { MAX_OPCODE = 256 };
96 static uint64_t opcount[MAX_OPCODE];
97 
104  [M0_OS_INITIALISED] = {
106  .sd_name = "initialised",
107  .sd_allowed = M0_BITS(M0_OS_LAUNCHED,
108  M0_OS_FAILED),
109  },
110  [M0_OS_LAUNCHED] = {
111  .sd_name = "launched",
112  .sd_allowed = M0_BITS(M0_OS_EXECUTED,
113  M0_OS_FAILED),
114  },
115  [M0_OS_EXECUTED] = {
116  .sd_name = "executed",
117  .sd_allowed = M0_BITS(M0_OS_STABLE,
118  M0_OS_FAILED),
119  },
120  [M0_OS_STABLE] = {
121  .sd_flags = M0_SDF_FINAL | M0_SDF_TERMINAL,
122  .sd_name = "stable",
123  },
124  [M0_OS_FAILED] = {
126  .sd_name = "failed",
127  },
128 };
129 
134  {"launching", M0_OS_INITIALISED, M0_OS_LAUNCHED},
135  {"failed-to-launch", M0_OS_INITIALISED, M0_OS_FAILED},
136  {"operation-executed", M0_OS_LAUNCHED, M0_OS_EXECUTED},
137  {"operation-failed", M0_OS_LAUNCHED, M0_OS_FAILED},
138  {"transaction-stable", M0_OS_EXECUTED, M0_OS_STABLE},
139  {"transaction-failed", M0_OS_EXECUTED, M0_OS_FAILED},
140 };
141 
146  .scf_name = "op-conf",
147  .scf_nr_states = ARRAY_SIZE(m0_op_phases),
148  .scf_state = m0_op_phases,
149  .scf_trans = m0_op_trans,
150  .scf_trans_nr = ARRAY_SIZE(m0_op_trans),
151 };
152 
157  [M0_ES_INIT] = {
159  .sd_name = "init",
160  .sd_allowed = M0_BITS(M0_ES_CREATING,
161  M0_ES_OPENING),
162  },
163  [M0_ES_CREATING] = {
164  .sd_name = "creating",
165  .sd_allowed = M0_BITS(M0_ES_OPEN, M0_ES_FAILED),
166  },
167  [M0_ES_DELETING] = {
168  .sd_name = "deleting",
169  .sd_allowed = M0_BITS(M0_ES_INIT, M0_ES_FAILED),
170  },
171  [M0_ES_OPENING] = {
172  .sd_name = "opening",
173  .sd_allowed = M0_BITS(M0_ES_OPEN, M0_ES_FAILED),
174  },
175  [M0_ES_OPEN] = {
176  .sd_name = "open",
177  .sd_allowed = M0_BITS(M0_ES_DELETING,
179  M0_ES_FAILED),
180  },
181  [M0_ES_CLOSING] = {
182  .sd_name = "closing",
183  .sd_allowed = M0_BITS(M0_ES_INIT, M0_ES_FAILED),
184  },
185  [M0_ES_FAILED] = {
187  .sd_name = "failed",
188  },
189 };
190 
195  {"creating", M0_ES_INIT, M0_ES_CREATING},
196  {"deleting", M0_ES_OPEN, M0_ES_DELETING},
197  {"opening", M0_ES_INIT, M0_ES_OPENING},
198  {"finished-creating", M0_ES_CREATING, M0_ES_OPEN},
199  {"finished-deleting", M0_ES_DELETING, M0_ES_INIT},
200  {"open", M0_ES_OPENING, M0_ES_OPEN},
201  {"failed-to-create", M0_ES_CREATING, M0_ES_FAILED},
202  {"failed-to-delete", M0_ES_DELETING, M0_ES_FAILED},
203  {"failed-to-open", M0_ES_OPENING, M0_ES_FAILED},
204  {"closing", M0_ES_OPEN, M0_ES_CLOSING},
205  {"failed-to-open", M0_ES_OPEN, M0_ES_FAILED},
206  {"finished-closing", M0_ES_CLOSING, M0_ES_INIT},
207  {"failed-to-close", M0_ES_CLOSING, M0_ES_FAILED},
208 };
209 
214  .scf_name = "entity-conf",
215  .scf_nr_states = ARRAY_SIZE(entity_phases),
216  .scf_state = entity_phases,
217  .scf_trans = entity_trans,
218  .scf_trans_nr = ARRAY_SIZE(entity_trans),
219 };
220 
225 M0_INTERNAL struct m0_client *
226 m0__entity_instance(const struct m0_entity *entity)
227 {
228  M0_PRE(entity != NULL);
229  M0_PRE(entity->en_realm != NULL);
230  M0_PRE(entity->en_realm->re_instance != NULL);
231 
232  return entity->en_realm->re_instance;
233 }
234 
235 M0_INTERNAL struct m0_client *
236 m0__op_instance(const struct m0_op *op)
237 {
238  struct m0_entity *entity;
239  M0_PRE(op != NULL);
240 
241  entity = op->op_code == M0_EO_SYNC ?
242  m0__op_sync_entity(op) : op->op_entity;
243  M0_PRE(entity != NULL);
244 
245  return m0__entity_instance(entity);
246 }
247 
248 M0_INTERNAL struct m0_op *
250 {
251  return &ioo->ioo_oo.oo_oc.oc_op;
252 }
253 
254 M0_INTERNAL bool
256 {
257  return instance->m0c_config->mc_is_oostore;
258 }
259 
260 M0_INTERNAL struct m0_client *
262 {
263  M0_PRE(obj != NULL);
264 
265  return m0__entity_instance(&obj->ob_entity);
266 }
267 
268 M0_INTERNAL struct m0_client *
269 m0__idx_instance(const struct m0_idx *idx)
270 {
271  M0_PRE(idx != NULL);
272 
273  return m0__entity_instance(&idx->in_entity);
274 }
275 
289 M0_INTERNAL struct m0_locality *
291 {
292  return m0_locality_here();
293 }
294 
296 {
297  return M0_IN(type, (M0_ET_OBJ, M0_ET_IDX));
298 }
299 
300 M0_INTERNAL bool entity_invariant_full(struct m0_entity *ent)
301 {
302  bool rc = false;
303  struct m0_sm_group *grp;
304 
305  grp = &ent->en_sm_group;
306  if (!m0_sm_group_is_locked(grp)) {
310  }
311  return M0_RC(rc);
312 }
313 
320 M0_INTERNAL bool entity_invariant_locked(const struct m0_entity *ent)
321 {
322  return M0_RC(ent != NULL &&
323  m0_sm_group_is_locked(&ent->en_sm_group) &&
324  m0_sm_invariant(&ent->en_sm) &&
325  m0_entity_type_is_valid(ent->en_type));
326 }
327 
334 M0_INTERNAL bool m0_op_invariant(const struct m0_op *op)
335 {
336  return M0_RC(op != NULL &&
337  op->op_size >= sizeof(struct m0_op_common) &&
338  m0_op_bob_check(op));
339 }
340 
344 M0_INTERNAL bool m0_op_entity_invariant(const struct m0_op *op)
345 {
346  return (op->op_entity == NULL) == (op->op_code == M0_EO_SYNC) &&
347  ergo(op->op_entity != NULL,
348  entity_invariant_full(op->op_entity));
349 }
350 
354 M0_INTERNAL bool entity_id_is_valid(const struct m0_uint128 *id)
355 {
356  if (m0_uint128_cmp(&M0_ID_APP, id) >= 0) {
357  M0_LOG(M0_ERROR, "Invalid entity fid detected: "
358  "<%"PRIx64 ":%"PRIx64 ">."
359  "Entity id should larger than M0_ID_APP.",
360  id->u_hi, id->u_lo);
361  return false;
362  }
363 
364  return true;
365 }
366 
371 M0_INTERNAL void m0_entity_init(struct m0_entity *entity,
372  struct m0_realm *parent,
373  const struct m0_uint128 *id,
374  const enum m0_entity_type type)
375 {
376  struct m0_sm_group *grp;
377 
378  M0_ENTRY();
379 
380  M0_PRE(entity != NULL);
381  M0_PRE(parent != NULL);
382  M0_PRE(parent->re_instance != NULL);
383  M0_PRE(id != NULL);
387 
388  /* initalise the entity */
389  entity->en_type = type;
390  entity->en_id = *id;
391  entity->en_realm = parent;
392 
393  /* initalise the state machine */
394  grp = &entity->en_sm_group;
396  m0_sm_init(&entity->en_sm, &entity_conf, M0_ES_INIT, grp);
398  spti_tlist_init(&entity->en_pending_tx);
400  M0_LEAVE();
401 }
402 
403 void m0_obj_init(struct m0_obj *obj,
404  struct m0_realm *parent,
405  const struct m0_uint128 *id,
406  uint64_t layout_id)
407 {
408  size_t obj_size;
409 
410  M0_ENTRY();
411 
412  M0_PRE(obj != NULL);
413  M0_PRE(parent != NULL);
414  M0_PRE(id != NULL);
416  M0_PRE(M0_IS0(&obj->ob_entity));
418 
419  /* Initalise the entity */
420  m0_entity_init(&obj->ob_entity, parent, id, M0_ET_OBJ);
421 
422  /* set the blocksize to a reasonable default */
423  obj->ob_attr.oa_bshift = M0_DEFAULT_BUF_SHIFT;
424  obj_size = obj->ob_attr.oa_buf_size;
425  obj->ob_attr.oa_layout_id = obj_size == 0 && layout_id == 0 ?
426  M0_DEFAULT_LAYOUT_ID : layout_id;
427  M0_LOG(M0_DEBUG, "YJC: layout id = %"PRIu64, obj->ob_attr.oa_layout_id);
428 
429 #ifdef OSYNC
430  m0_mutex_init(&obj->ob_pending_tx_lock);
431  spti_tlist_init(&obj->ob_pending_tx);
432 #endif
433 
434  M0_LEAVE();
435 }
436 M0_EXPORTED(m0_obj_init);
437 
438 void m0_entity_fini(struct m0_entity *entity)
439 {
440  struct m0_reqh_service_txid *iter;
441 
442  M0_ENTRY();
443 
444  M0_PRE(entity != NULL);
445  M0_PRE(M0_IN(entity->en_sm.sm_state,
447  M0_ES_FAILED)));
449 
450  m0_tl_teardown(spti, &entity->en_pending_tx, iter)
451  m0_free0(&iter);
452  spti_tlist_fini(&entity->en_pending_tx);
454  m0_sm_group_lock(&entity->en_sm_group);
455  if (entity->en_sm.sm_state == M0_ES_OPEN) {
456  m0_sm_move(&entity->en_sm, 0, M0_ES_CLOSING);
457  m0_sm_move(&entity->en_sm, 0, M0_ES_INIT);
458  }
459  m0_sm_fini(&entity->en_sm);
461  m0_sm_group_fini(&entity->en_sm_group);
462  M0_SET0(entity);
463  M0_LEAVE();
464 }
465 M0_EXPORTED(m0_entity_fini);
466 
467 void m0_obj_fini(struct m0_obj *obj)
468 {
469 
471 
472  M0_ENTRY();
473  M0_PRE(obj != NULL);
474 
475  /* Cleanup layout. */
476  if (obj->ob_layout != NULL) {
477  m0_client__layout_put(obj->ob_layout);
478  m0_client_layout_free(obj->ob_layout);
479  obj->ob_layout = NULL;
480  }
481  m0_entity_fini(&obj->ob_entity);
482  M0_SET0(obj);
483 
484  M0_LEAVE();
485 }
486 M0_EXPORTED(m0_obj_fini);
487 
488 
500 M0_INTERNAL int m0_op_executed(struct m0_op *op)
501 {
502  M0_ENTRY();
503 
505 
506  /* Call the op:executed callback if one is present */
507  if (op->op_cbs != NULL && op->op_cbs->oop_executed != NULL)
508  op->op_cbs->oop_executed(op);
509 
510  return M0_RC(-1);
511 }
512 
520 M0_INTERNAL int m0_op_stable(struct m0_op *op)
521 {
522  struct m0_client *m0c;
523 
524  M0_ENTRY();
525 
527 
529  M0_PRE(m0c != NULL);
530 
531  /* Call the op:stable callback if one is present */
532  if (op->op_cbs != NULL && op->op_cbs->oop_stable != NULL)
533  op->op_cbs->oop_stable(op);
534  if (!M0_FI_ENABLED("skip_ongoing_io_ref"))
536 
537  return M0_RC(-1);
538 }
539 
548 M0_INTERNAL int m0_op_failed(struct m0_op *op)
549 {
550  struct m0_client *m0c;
551 
552  M0_ENTRY();
554 
556  M0_PRE(m0c != NULL);
557 
558  /* Call the op:failed callback if one is present */
559  if (op->op_cbs != NULL && op->op_cbs->oop_failed != NULL)
560  op->op_cbs->oop_failed(op);
561 
562  if (!M0_FI_ENABLED("skip_ongoing_io_ref"))
564 
565  return M0_RC(-1);
566 }
567 
568 M0_INTERNAL int m0_op_get(struct m0_op **op, size_t size)
569 {
570  int rc = 0;
571 
572  M0_ENTRY();
573  M0_PRE(op != NULL);
574 
575  /* Allocate the op if necessary. */
576  if (*op == NULL) {
577  rc = m0_op_alloc(op, size);
578  if (rc != 0)
579  return M0_ERR(rc);
580  } else {
581  size_t cached_size = (*op)->op_size;
582 
583  if ((*op)->op_size < size)
584  return M0_ERR(-EMSGSIZE);
585 
586  /* 0 the pre-allocated operation. */
587  memset(*op, 0, cached_size);
588  (*op)->op_size = size;
589  }
590  m0_mutex_init(&(*op)->op_pending_tx_lock);
591  spti_tlist_init(&(*op)->op_pending_tx);
592  return M0_RC(0);
593 }
594 
599 M0_INTERNAL void m0_op_cancel_one(struct m0_op *op)
600 {
601  struct m0_op_common *oc;
602 
603  M0_ENTRY();
604 
606  M0_PRE(M0_IN(op->op_sm.sm_state, (M0_OS_LAUNCHED,
608  M0_OS_STABLE,
609  M0_OS_FAILED)));
610 
611  oc = bob_of(op, struct m0_op_common, oc_op, &oc_bobtype);
612  M0_PRE(oc->oc_cb_cancel != NULL);
613 
614  m0_sm_group_lock(&op->op_sm_group);
615 
616  if (!M0_IN(op->op_sm.sm_state, (M0_OS_STABLE,
617  M0_OS_FAILED))) {
618  if (oc->oc_cb_cancel != NULL) {
619  /*
620  * Not implemented for opcodes M0_OC_ALLOC,
621  * M0_ET_REALM, M0_EO_INVALID,
622  * M0_EO_SYNC, M0_EO_GETATTR,
623  * M0_EO_SETATTR, M0_EO_LAYOUT_GET,
624  * M0_EO_LAYOUT_SET
625  */
626  oc->oc_cb_cancel(oc);
627  } else {
628  op->op_rc = M0_ERR(-EINVAL);
629  m0_sm_move(&op->op_sm, op->op_rc, M0_OS_FAILED);
630  }
631  }
632 
633  /* Call the op-type's cancel function */
634  m0_sm_group_unlock(&op->op_sm_group);
635 
636  M0_LEAVE();
637 }
638 
639 void m0_op_cancel(struct m0_op **op, uint32_t nr)
640 {
641  int i;
642  struct m0_entity *entity;
643 
644  M0_ENTRY();
645  M0_PRE(op != NULL);
646 
647  for (i = 0; i < nr; i++) {
648  entity = op[i]->op_entity;
649  if (M0_IN(entity->en_type, (M0_ET_OBJ,
650  M0_ET_IDX)))
652  }
653 
654  M0_LEAVE();
655 }
656 M0_EXPORTED(m0_op_cancel);
657 
658 static void addb2_add_op_attrs(const struct m0_op *op)
659 {
660  struct m0_entity *entity;
661  uint64_t oid;
662 
663  M0_PRE(op != NULL);
664 
665  oid = m0_sm_id_get(&op->op_sm);
666  entity = op->op_code == M0_EO_SYNC ?
667  m0__op_sync_entity(op) : op->op_entity;
668 
669  if (entity != NULL)
671  entity->en_type);
673  op->op_code);
674 }
675 
686 M0_INTERNAL void m0_op_launch_one(struct m0_op *op)
687 {
688  struct m0_op_common *oc;
689  struct m0_client *m0c;
690  int rc;
691 
692  M0_ENTRY();
693 
695  M0_PRE(op->op_sm.sm_state == M0_OS_INITIALISED);
696  /* SYNC op doesn't have `entity`. */
698 
699  oc = bob_of(op, struct m0_op_common, oc_op, &oc_bobtype);
700  M0_PRE(oc->oc_cb_launch != NULL);
701 
703  M0_PRE(m0c != NULL);
704 
705  rc = m0__io_ref_get(m0c);
706  if (rc != 0) {
707  m0_sm_group_lock(&op->op_sm_group);
708  m0_sm_move(&op->op_sm, rc, M0_OS_FAILED);
709  op->op_rc = rc;
710  m0_sm_group_unlock(&op->op_sm_group);
711  return;
712  }
713 
715 
716  m0_sm_group_lock(&op->op_sm_group);
717 
718  /* Call the op-type's launch function */
719  oc->oc_cb_launch(oc);
720  m0_sm_group_unlock(&op->op_sm_group);
721 
722  M0_LEAVE();
723 }
724 
725 void m0_op_launch(struct m0_op **op, uint32_t nr)
726 {
727  int i;
728 
729  M0_ENTRY();
730  M0_PRE(op != NULL);
731 
732  for (i = 0; i < nr; i++)
734 
735  M0_LEAVE();
736 }
737 M0_EXPORTED(m0_op_launch);
738 
739 int32_t m0_op_wait(struct m0_op *op, uint64_t bits,
740  m0_time_t to)
741 {
742  int32_t rc;
743 
744  M0_ENTRY();
745 
747  M0_PRE(bits != 0);
748  /* Check bits only contains bits for these states */
749  M0_PRE((bits & ~M0_BITS(M0_OS_LAUNCHED,
751  M0_OS_STABLE,
752  M0_OS_FAILED)) == 0);
753 
754  /* Perform a timed wait */
755  m0_sm_group_lock(&op->op_sm_group);
756  rc = m0_sm_timedwait(&op->op_sm, bits, to);
757  m0_sm_group_unlock(&op->op_sm_group);
758 
759  /*
760  * No point checking sm in one of bits states - it may have moved
761  * while we released the locks
762  */
763  return M0_RC(rc);
764 }
765 M0_EXPORTED(m0_op_wait);
766 
779 M0_INTERNAL int m0_op_alloc(struct m0_op **op, size_t op_size)
780 {
781  M0_ENTRY();
782 
783  M0_PRE(op != NULL);
784  M0_PRE(*op == NULL);
785  M0_PRE(op_size >= sizeof(struct m0_op_common));
786 
787  /* Allocate the operation */
788  *op = m0_alloc(op_size);
789  if (*op == NULL)
790  return M0_ERR(-ENOMEM);
791  (*op)->op_size = op_size;
792 
793  return M0_RC(0);
794 }
795 
806 M0_INTERNAL int m0_op_init(struct m0_op *op,
807  const struct m0_sm_conf *conf,
808  struct m0_entity *entity)
809 {
810  struct m0_sm_group *grp;
811 
812  M0_ENTRY();
813 
814  if (M0_FI_ENABLED("fail_op_init"))
815  return M0_ERR(-EINVAL);
816 
817  M0_PRE(op != NULL);
818  M0_PRE(conf != NULL);
820  M0_ASSERT(ergo(entity != NULL, entity_invariant_full(entity)));
821 
822  /* Initialise the operation. */
823  m0_op_bob_init(op);
824  op->op_entity = entity;
825 
826  /* XXX initialise a cookie? or wait for launch to do that... */
827  /*(*op)->op_gen = ?;*/
828 
829  /* Initialise the state machine. */
830  grp = &op->op_sm_group;
832  m0_sm_init(&op->op_sm, conf, M0_OS_INITIALISED, grp);
833  m0_sm_addb2_counter_init(&op->op_sm);
834 
835  M0_ASSERT(IS_IN_ARRAY(op->op_code, opcount));
836  op->op_count = opcount[op->op_code]++; /* XXX lock! */
837 
838  /* m0_sm_invariant must be checked under sm_group lock. */
840  M0_POST(m0_sm_invariant(&op->op_sm));
842  m0_mutex_init(&op->op_priv_lock);
843 
844  return M0_RC(0);
845 }
846 
847 void m0_op_fini(struct m0_op *op)
848 {
849  struct m0_op_common *oc;
850  struct m0_sm_group *grp;
851  struct m0_reqh_service_txid *iter;
852 
853  M0_ENTRY();
854 
855  M0_PRE(op != NULL);
856  M0_PRE(M0_IN(op->op_sm.sm_state, (M0_OS_INITIALISED,
857  M0_OS_STABLE,
858  M0_OS_FAILED)));
859  M0_PRE(op->op_size >= sizeof *oc);
860 
861  oc = bob_of(op, struct m0_op_common, oc_op, &oc_bobtype);
862  if (oc->oc_cb_fini != NULL)
863  oc->oc_cb_fini(oc);
864  m0_mutex_fini(&op->op_priv_lock);
865 
866  m0_tl_teardown(spti, &op->op_pending_tx, iter)
867  m0_free0(&iter);
868  spti_tlist_fini(&op->op_pending_tx);
869  m0_mutex_fini(&op->op_pending_tx_lock);
870 
871  grp = &op->op_sm_group;
873  m0_sm_fini(&op->op_sm);
874  op->op_sm.sm_state = M0_OS_UNINITIALISED;
877 
878  /* Finalise op's bob */
879  m0_op_bob_fini(op);
880 
881  M0_LEAVE();
882 }
883 M0_EXPORTED(m0_op_fini);
884 
885 void m0_op_free(struct m0_op *op)
886 {
887  struct m0_op_common *oc;
888  struct m0_op_obj *oo;
889 
890  M0_ENTRY();
891 
892  M0_PRE(op != NULL);
893  M0_PRE(op->op_sm.sm_state == M0_OS_UNINITIALISED);
894  M0_PRE((op->op_size >= sizeof *oc));
895 
896  /* bob_fini has been called in op_fini, using M0_AMB() here. */
897  oc = M0_AMB(oc, op, oc_op);
898  oo = M0_AMB(oo, oc, oo_oc);
899  if (oc->oc_cb_free != NULL)
900  oc->oc_cb_free(oc);
901  else
902  m0_free(oo);
903 
904  M0_LEAVE();
905 }
906 M0_EXPORTED(m0_op_free);
907 
908 void m0_op_setup(struct m0_op *op,
909  const struct m0_op_ops *cbs,
910  m0_time_t linger)
911 {
912  M0_ENTRY();
913 
914  M0_PRE(op != NULL);
915  M0_PRE(op->op_sm.sm_state == M0_OS_INITIALISED);
916 
917  op->op_cbs = cbs;
918  op->op_linger = linger;
919 
920  M0_LEAVE();
921 }
922 M0_EXPORTED(m0_op_setup);
923 
924 void m0_op_kick(struct m0_op *op)
925 {
926  M0_ENTRY();
927 
928  M0_PRE(op != NULL);
929  M0_PRE(op->op_sm.sm_state >= M0_OS_INITIALISED);
930 
939  M0_LEAVE();
940 }
941 M0_EXPORTED(m0_op_kick);
942 
943 int32_t m0_rc(const struct m0_op *op)
944 {
945  M0_ENTRY();
946  M0_PRE(op != NULL);
947  return M0_RC(op->op_rc);
948 }
949 M0_EXPORTED(m0_rc);
950 
951 #undef M0_TRACE_SUBSYSTEM
952 
953 /*
954  * Local variables:
955  * c-indentation-style: "K&R"
956  * c-basic-offset: 8
957  * tab-width: 8
958  * fill-column: 80
959  * scroll-step: 1
960  * End:
961  */
962 /*
963  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
964  */
M0_INTERNAL int m0_uint128_cmp(const struct m0_uint128 *u0, const struct m0_uint128 *u1)
Definition: misc.c:45
uint64_t id
Definition: cob.h:2380
static size_t nr
Definition: dump.c:1505
const struct m0_bob_type ar_bobtype
Definition: client.c:73
const struct m0_bob_type oo_bobtype
Definition: client.c:45
#define M0_PRE(cond)
M0_INTERNAL struct m0_client * m0__idx_instance(const struct m0_idx *idx)
Definition: client.c:269
Definition: client.h:835
void m0_entity_fini(struct m0_entity *entity)
Definition: client.c:438
M0_INTERNAL int m0_op_get(struct m0_op **op, size_t size)
Definition: client.c:568
struct m0_mutex en_pending_tx_lock
Definition: client.h:737
Definition: client.h:788
struct m0_sm_trans_descr entity_trans[]
Definition: client.c:194
#define NULL
Definition: misc.h:38
M0_INTERNAL bool entity_invariant_full(struct m0_entity *ent)
Definition: client.c:300
#define ergo(a, b)
Definition: misc.h:293
M0_INTERNAL bool entity_id_is_valid(const struct m0_uint128 *id)
Definition: client.c:354
Definition: sm.h:350
const struct m0_bob_type op_bobtype
Definition: client.c:46
void m0_op_fini(struct m0_op *op)
Definition: client.c:847
M0_INTERNAL bool m0__is_oostore(struct m0_client *instance)
Definition: client.c:255
static struct m0_sm_group * grp
Definition: bytecount.c:38
static uint64_t opcount[MAX_OPCODE]
Definition: client.c:96
uint64_t m0_time_t
Definition: time.h:37
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
struct m0_sm_trans_descr m0_op_trans[]
Definition: client.c:133
int32_t m0_rc(const struct m0_op *op)
Definition: client.c:943
static struct m0_clovis * m0c
Definition: main.c:25
struct m0_op oc_op
M0_INTERNAL int m0_op_init(struct m0_op *op, const struct m0_sm_conf *conf, struct m0_entity *entity)
Definition: client.c:806
Definition: conf.py:1
M0_INTERNAL void m0_op_launch_one(struct m0_op *op)
Definition: client.c:686
#define M0_BITS(...)
Definition: misc.h:236
M0_INTERNAL bool m0_op_entity_invariant(const struct m0_op *op)
Definition: client.c:344
#define M0_SET0(obj)
Definition: misc.h:64
M0_ADDB2_ADD(M0_AVI_FS_CREATE, new_fid.f_container, new_fid.f_key, mode, rc)
const struct m0_uint128 M0_UBER_REALM
Definition: client.c:85
M0_INTERNAL bool m0_sm_addb2_counter_init(struct m0_sm *sm)
Definition: sm.c:891
M0_INTERNAL void m0_sm_group_fini(struct m0_sm_group *grp)
Definition: sm.c:65
static struct foo * obj
Definition: tlist.c:302
#define PRIx64
Definition: types.h:61
const char * bt_name
Definition: bob.h:73
const struct m0_uint128 M0_ID_APP
Definition: client.c:92
M0_INTERNAL int m0_sm_timedwait(struct m0_sm *mach, uint64_t states, m0_time_t deadline)
Definition: sm.c:387
int32_t m0_op_wait(struct m0_op *op, uint64_t bits, m0_time_t to)
Definition: client.c:739
struct m0_tl en_pending_tx
Definition: client.h:736
return M0_RC(rc)
op
Definition: libdemo.c:64
#define M0_ENTRY(...)
Definition: trace.h:170
M0_INTERNAL void m0__io_ref_put(struct m0_client *m0c)
Definition: client_init.c:897
M0_INTERNAL void m0_sm_group_unlock(struct m0_sm_group *grp)
Definition: sm.c:96
struct m0_entity in_entity
Definition: client.h:836
int i
Definition: dir.c:1033
M0_INTERNAL void m0_client__layout_put(struct m0_client_layout *layout)
Definition: layout.c:288
struct m0_sm_state_descr entity_phases[]
Definition: client.c:156
#define PRIu64
Definition: types.h:58
static void addb2_add_op_attrs(const struct m0_op *op)
Definition: client.c:658
Definition: client.h:641
const struct m0_bob_type oc_bobtype
Definition: client.c:44
void(* oc_cb_free)(struct m0_op_common *oc)
return M0_ERR(-EOPNOTSUPP)
struct m0_op_obj ioo_oo
M0_INTERNAL struct m0_client * m0__op_instance(const struct m0_op *op)
Definition: client.c:236
M0_INTERNAL int m0_op_stable(struct m0_op *op)
Definition: client.c:520
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
#define m0_tl_teardown(name, head, obj)
Definition: tlist.h:708
#define m0_free0(pptr)
Definition: memory.h:77
void m0_client_layout_free(struct m0_client_layout *layout)
Definition: layout.c:504
#define M0_ASSERT(cond)
const char * scf_name
Definition: sm.h:352
M0_INTERNAL void m0_sm_group_init(struct m0_sm_group *grp)
Definition: sm.c:53
M0_INTERNAL bool m0_entity_type_is_valid(enum m0_entity_type type)
Definition: client.c:295
void m0_obj_fini(struct m0_obj *obj)
Definition: client.c:467
#define bob_of(ptr, type, field, bt)
Definition: bob.h:140
struct m0_sm_conf entity_conf
Definition: client.c:213
void m0_op_launch(struct m0_op **op, uint32_t nr)
Definition: client.c:725
M0_INTERNAL struct m0_entity * m0__op_sync_entity(const struct m0_op *op)
Definition: sync.c:1172
int layout_id
Definition: dir.c:331
void * m0_alloc(size_t size)
Definition: memory.c:126
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
#define M0_POST(cond)
void(* oc_cb_fini)(struct m0_op_common *oc)
struct m0_uint128 en_id
Definition: client.h:708
struct m0_op_common oo_oc
void m0_op_cancel(struct m0_op **op, uint32_t nr)
Definition: client.c:639
M0_INTERNAL int m0_op_executed(struct m0_op *op)
Definition: client.c:500
M0_INTERNAL struct m0_op * m0__ioo_to_op(struct m0_op_io *ioo)
Definition: client.c:249
M0_INTERNAL struct m0_locality * m0_locality_here(void)
Definition: locality.c:146
M0_INTERNAL int m0__io_ref_get(struct m0_client *m0c)
Definition: client_init.c:868
uint32_t sd_flags
Definition: sm.h:378
static struct m0_client cinst
Definition: sync.c:84
M0_INTERNAL bool entity_invariant_locked(const struct m0_entity *ent)
Definition: client.c:320
struct m0_realm * en_realm
Definition: client.h:710
struct m0_sm_group en_sm_group
Definition: client.h:734
M0_INTERNAL bool m0_op_invariant(const struct m0_op *op)
Definition: client.c:334
const int m0_lid_to_unit_map_nr
Definition: layout_pver.c:116
#define M0_FI_ENABLED(tag)
Definition: finject.h:231
M0_INTERNAL void m0_sm_init(struct m0_sm *mach, const struct m0_sm_conf *conf, uint32_t state, struct m0_sm_group *grp)
Definition: sm.c:313
#define M0_IS0(obj)
Definition: misc.h:70
M0_INTERNAL int m0_op_failed(struct m0_op *op)
Definition: client.c:548
m0_entity_type
Definition: client.h:585
M0_INTERNAL struct m0_locality * m0__locality_pick(struct m0_client *cinst)
Definition: client.c:290
void(* oc_cb_cancel)(struct m0_op_common *oc)
#define M0_CLIENT_THREAD_ENTER
m0_bcount_t size
Definition: di.c:39
M0_INTERNAL void m0_sm_move(struct m0_sm *mach, int32_t rc, int state)
Definition: sm.c:485
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
#define IS_IN_ARRAY(idx, array)
Definition: misc.h:311
void m0_obj_init(struct m0_obj *obj, struct m0_realm *parent, const struct m0_uint128 *id, uint64_t layout_id)
Definition: client.c:403
static struct m0 instance
Definition: main.c:78
M0_INTERNAL void m0_sm_group_lock(struct m0_sm_group *grp)
Definition: sm.c:83
M0_INTERNAL struct m0_client * m0__obj_instance(const struct m0_obj *obj)
Definition: client.c:261
M0_INTERNAL int m0_op_alloc(struct m0_op **op, size_t op_size)
Definition: client.c:779
struct m0_client * re_instance
Definition: client.h:873
void m0_op_kick(struct m0_op *op)
Definition: client.c:924
M0_INTERNAL void m0_op_cancel_one(struct m0_op *op)
Definition: client.c:599
M0_BOB_DEFINE(M0_INTERNAL, &oc_bobtype, m0_op_common)
void m0_op_free(struct m0_op *op)
Definition: client.c:885
struct m0_sm en_sm
Definition: client.h:732
int type
Definition: dir.c:1031
M0_INTERNAL bool m0_sm_conf_is_initialized(const struct m0_sm_conf *conf)
Definition: sm.c:382
struct m0_dirent * ent
Definition: dir.c:1029
struct m0_sm_state_descr m0_op_phases[]
Definition: client.c:103
void(* oc_cb_launch)(struct m0_op_common *oc)
M0_INTERNAL uint64_t m0_sm_id_get(const struct m0_sm *sm)
Definition: sm.c:1021
void m0_free(void *data)
Definition: memory.c:146
uint32_t sm_state
Definition: sm.h:307
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL void m0_entity_init(struct m0_entity *entity, struct m0_realm *parent, const struct m0_uint128 *id, const enum m0_entity_type type)
Definition: client.c:371
#define ARRAY_SIZE(a)
Definition: misc.h:45
#define offsetof(typ, memb)
Definition: misc.h:29
enum m0_entity_type en_type
Definition: client.h:706
M0_INTERNAL bool m0_sm_group_is_locked(const struct m0_sm_group *grp)
Definition: sm.c:107
struct m0_sm_conf m0_op_conf
Definition: client.c:145
M0_INTERNAL struct m0_client * m0__entity_instance(const struct m0_entity *entity)
Definition: client.c:226
void m0_op_setup(struct m0_op *op, const struct m0_op_ops *cbs, m0_time_t linger)
Definition: client.c:908
M0_INTERNAL void m0_sm_fini(struct m0_sm *mach)
Definition: sm.c:331
M0_INTERNAL bool m0_sm_invariant(const struct m0_sm *mach)
Definition: sm.c:267