Motr  M0
cob.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 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 #include "motr/client.h"
24 #include "motr/client_internal.h"
25 #include "motr/layout.h"
26 #include "motr/idx.h"
27 #include "motr/sync.h"
28 
29 #include "lib/errno.h"
30 #include "lib/finject.h"
31 #include "fid/fid.h" /* m0_fid */
32 #include "fop/fom_generic.h" /* m0_rpc_item_is_generic_reply_fop */
33 #include "ioservice/fid_convert.h" /* m0_fid_convert_ */
34 #include "mdservice/md_fops.h"
35 #include "rpc/rpclib.h"
36 #include "rpc/rpc_opcodes.h" /* M0_MDSERVICE_CREATE_OPCODE */
37 #include "motr/addb.h"
38 
39 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CLIENT
40 #include "lib/trace.h"
41 
42 #define OSYNC
43 
44 struct ios_cob_req {
45  struct cob_req *icr_cr;
46  struct m0_ast_rc icr_ar;
47  uint32_t icr_index;
48  uint64_t icr_magic;
49 };
50 
52  COB_REQ_ASYNC = (1 << 1),
53  COB_REQ_SYNC = (1 << 2),
54 };
55 
59 struct cob_req {
60  struct m0_ref cr_ref;
61  uint64_t cr_magic;
63  struct m0_ast_rc cr_ar;
64 
65  struct m0_op *cr_op;
67 
68  uint32_t cr_opcode;
69  struct m0_fid cr_fid;
70  struct m0_fid cr_pver;
71  struct m0_buf cr_name;
72  uint32_t cr_cob_type;
73  uint32_t cr_flags;
74  uint32_t cr_icr_nr;
75  struct m0_fop **cr_ios_fop;
76  struct m0_fop *cr_mds_fop;
77 
78  struct m0_fop *cr_rep_fop;
81  uint64_t cr_id;
82 };
83 
89 enum {IOS_COB_REQ_DEADLINE = 2000000};
90 
91 const struct m0_bob_type cr_bobtype;
92 M0_BOB_DEFINE(M0_INTERNAL, &cr_bobtype, cob_req);
93 const struct m0_bob_type cr_bobtype = {
94  .bt_name = "cr_bobtype",
95  .bt_magix_offset = offsetof(struct cob_req, cr_magic),
96  .bt_magix = M0_CR_MAGIC,
97  .bt_check = NULL,
98 };
99 
100 static const struct m0_bob_type icr_bobtype;
102 static const struct m0_bob_type icr_bobtype = {
103  .bt_name = "icr_bobtype",
104  .bt_magix_offset = offsetof(struct ios_cob_req, icr_magic),
105  .bt_magix = M0_ICR_MAGIC,
106  .bt_check = NULL,
107 };
108 
109 static void cob_ios_fop_fini(struct m0_fop *ios_fop);
110 static void cob_ast_ios_io_send(struct m0_sm_group *grp,
111  struct m0_sm_ast *ast);
112 static int cob_mds_send(struct cob_req *cr);
113 static int cob_ios_md_send(struct cob_req *cr);
114 
115 static void to_cob_req_map(const struct m0_op *op,
116  const struct cob_req *cr)
117 {
118  uint64_t oid;
119 
120  /* Sometimes op==NULL in STs in most cases due to convoluted scenario */
121  if (op == NULL)
122  return;
123 
124  oid = m0_sm_id_get(&op->op_sm);
126 }
127 
128 static void cob_req_to_rpc_map(const struct cob_req *cr,
129  const struct m0_rpc_item *item)
130 {
131  uint64_t rid = m0_sm_id_get(&item->ri_sm);
133 }
141 static bool ios_cob_req_invariant(struct ios_cob_req *icr)
142 {
143  return M0_RC(icr != NULL &&
144  ios_cob_req_bob_check(icr));
145 }
146 
154 static int cob_name_mem2wire(struct m0_fop_str *tgt,
155  const struct m0_buf *name)
156 {
157  M0_ENTRY();
158 
159  M0_PRE(tgt != NULL);
160  M0_PRE(name != NULL);
161 
162  tgt->s_buf = m0_alloc(name->b_nob);
163  if (tgt->s_buf == NULL)
164  return M0_ERR(-ENOMEM);
165 
166  memcpy(tgt->s_buf, name->b_addr, (int)name->b_nob);
167  tgt->s_len = name->b_nob;
168 
169  return M0_RC(0);
170 }
171 
178 static void cob_body_mem2wire(struct m0_fop_cob *body,
179  struct m0_cob_attr *attr,
180  int valid,
181  struct cob_req *cr)
182 {
183  M0_PRE(body != NULL);
184  M0_PRE(cr != NULL);
185 
186  body->b_tfid = cr->cr_fid;
187 #ifdef CLIENT_FOR_M0T1FS
189 #endif
190 
191  if (valid & M0_COB_PVER)
192  body->b_pver = cr->cr_pver;
193  if (valid & M0_COB_NLINK)
194  body->b_nlink = attr->ca_nlink;
195  if (valid & M0_COB_LID)
196  body->b_lid = attr->ca_lid;
197  body->b_valid |= valid;
198 }
199 
200 static void cob_body_wire2mem(struct m0_cob_attr *attr,
201  const struct m0_fop_cob *body)
202 {
203  M0_SET0(attr);
204  attr->ca_pfid = body->b_pfid;
205  attr->ca_tfid = body->b_tfid;
206  attr->ca_valid = body->b_valid;
207  if (body->b_valid & M0_COB_NLINK)
208  attr->ca_nlink = body->b_nlink;
209  if (body->b_valid & M0_COB_LID)
210  attr->ca_lid = body->b_lid;
211  if (body->b_valid & M0_COB_PVER)
212  attr->ca_pver = body->b_pver;
213  attr->ca_version = body->b_version;
214 }
215 
216 static void cob_attr_init(struct cob_req *cr,
217  struct m0_cob_attr *attr,
218  int *valid)
219 {
220  switch (cr->cr_opcode) {
221  case M0_EO_CREATE:
222  /* mds requires nlink > 0 */
223  attr->ca_nlink = 1;
224  attr->ca_lid = cr->cr_cob_attr->ca_lid;
225  *valid = M0_COB_NLINK | M0_COB_PVER | M0_COB_LID;
226  break;
227  case M0_EO_DELETE:
228  attr->ca_nlink = 0;
229  *valid = M0_COB_NLINK;
230  break;
231  case M0_EO_OPEN:
232  case M0_EO_GETATTR:
233  case M0_EO_LAYOUT_GET:
234  memset(attr, 0, sizeof *attr);
235  *valid = 0;
236  break;
237  case M0_EO_LAYOUT_SET:
238  attr->ca_lid = cr->cr_cob_attr->ca_lid;
239  *valid |= M0_COB_LID;
240  break;
241  default:
242  M0_IMPOSSIBLE("Operation not supported");
243  }
244 }
245 
246 static void cob_req_release(struct cob_req *cr) {
247  struct m0_op *op = cr->cr_op;
248  int i;
249 
250  m0_ast_rc_bob_fini(&cr->cr_ar);
251  cob_req_bob_fini(cr);
252 
253  /* XXX: Can someone else access cr-> fields? do we need to lock? */
254  /* Release the mds fop. */
255  if (cr->cr_mds_fop != NULL) {
257  cr->cr_mds_fop = NULL;
258  }
259 
260  /* Release the ios fops. */
261  for (i = 0; i < cr->cr_icr_nr; ++i) {
262  if (cr->cr_ios_fop[i] != NULL) {
264  cr->cr_ios_fop[i] = NULL;
265  }
266  }
267  if (op != NULL)
268  op->op_priv = NULL;
269  m0_free(cr->cr_ios_fop);
270  m0_free(cr->cr_ios_replied);
271  m0_free(cr->cr_cob_attr);
272  m0_free(cr);
273 }
274 
275 static void cob_req_ref_release(struct m0_ref *ref)
276 {
277  struct cob_req *cr;
278 
279  M0_PRE(ref != NULL);
280  cr = container_of(ref, struct cob_req, cr_ref);
281  cob_req_release(cr);
282 }
283 
284 M0_INTERNAL struct cob_req*
286 {
287  m0_ref_get(&cr->cr_ref);
288  return cr;
289 }
290 
291 
292 M0_INTERNAL void cob_req_ref_put(struct cob_req *cr)
293 {
294  uint64_t count = m0_ref_read(&cr->cr_ref);
295  M0_PRE(count > 0);
296  m0_ref_put(&cr->cr_ref);
297 }
298 
305 static struct cob_req *cob_req_alloc(struct m0_pool_version *pv)
306 {
307  struct cob_req *cr;
308  uint32_t pool_width = pv->pv_attr.pa_P;
309 
310  cr = m0_alloc(sizeof *cr);
311  if (cr == NULL)
312  return NULL;
313 
314  cob_req_bob_init(cr);
315  m0_ast_rc_bob_init(&cr->cr_ar);
316 
317  /* Initialises and sets FOP related members. */
318  cr->cr_pver = pv->pv_id;
319  M0_ALLOC_ARR(cr->cr_ios_fop, pool_width);
320  M0_ALLOC_ARR(cr->cr_ios_replied, pool_width);
321  if (cr->cr_ios_fop == NULL || cr->cr_ios_replied == NULL) {
322  m0_free(cr->cr_ios_fop);
323  m0_free(cr->cr_ios_replied);
324  m0_free(cr);
325  return NULL;
326  }
328  cr->cr_id = m0_dummy_id_generate();
329  cr->cr_icr_nr = pool_width;
331 
332  return cr;
333 }
334 
342 static void cob_req_free(struct cob_req *cr)
343 {
344  M0_ASSERT(cr != NULL);
345  M0_ASSERT(cr->cr_cinst != NULL);
346 
348 
349  if (cr->cr_op != NULL) {
350  struct m0_op *op = cr->cr_op;
351  m0_mutex_lock(&op->op_priv_lock);
352  cob_req_ref_put(cr);
353  m0_mutex_unlock(&op->op_priv_lock);
354  } else {
358  cob_req_ref_put(cr);
359  }
360  return;
361 }
362 
363 static int cob_req_send(struct cob_req *cr)
364 {
365  int rc;
366 
367  M0_ENTRY();
368  M0_PRE(cr != NULL);
369 
370  to_cob_req_map(cr->cr_op, cr);
371 
373  /* Send fops to redundant IOS's */
374  rc = cob_ios_md_send(cr);
375  else
376  /* Initiate the op by sending a fop to the mdservice. */
377  rc = cob_mds_send(cr);
378 
380  return M0_RC(rc);
381 }
382 
383 static int cob_make_name(struct cob_req *cr)
384 {
385 #ifdef CLIENT_FOR_M0T1FS
386  int rc;
387  char *obj_name;
388 
389  /* Set the object's parent's fid. */
390  M0_ASSERT(cr->cr_cinst != NULL);
391  if (!m0_fid_is_set(&cr->cr_cinst->m0c_root_fid) ||
393  return M0_ERR(-EINVAL);
394 
395  /* Generate a valid name. */
396  obj_name = m0_alloc(M0_OBJ_NAME_MAX_LEN);
397  if (obj_name == NULL)
398  return M0_ERR(-ENOMEM);
400  obj_name, M0_OBJ_NAME_MAX_LEN, &cr->cr_fid);
401  if (rc != 0)
402  return M0_ERR(rc);
403  cr->cr_name.b_addr = obj_name;
404  cr->cr_name.b_nob = strlen(obj_name);
405 #endif
406  return M0_RC(0);
407 }
408 
409 static void cob_entity_sm_move(struct m0_op *op)
410 {
411  struct m0_entity *entity;
412  struct m0_obj *obj;
413 
414  M0_ENTRY();
415 
416  M0_PRE(op != NULL);
417  entity = op->op_entity;
418 
419  /* CREATE or DELETE op. */
420  if (M0_IN(op->op_code, (M0_EO_CREATE, M0_EO_DELETE)) &&
421  M0_IN(entity->en_sm.sm_state, (M0_ES_CREATING,
422  M0_ES_DELETING))) {
423  m0_sm_group_lock(&entity->en_sm_group);
424  M0_LOG(M0_DEBUG, "entity sm state: %p, %d\n",
425  &entity->en_sm, entity->en_sm.sm_state);
426  if (entity->en_sm.sm_state == M0_ES_CREATING)
427  m0_sm_move(&entity->en_sm, 0, M0_ES_OPEN);
428  else
429  m0_sm_move(&entity->en_sm, 0, M0_ES_INIT);
431 
432  M0_LEAVE();
433  return;
434  }
435 
436  /* It is an OPEN op for an entity. */
437  if (op->op_code == M0_EO_OPEN) {
438  obj = M0_AMB(obj, entity, ob_entity);
439 
440  /* Move object's entity state to OPEN. */
441  m0_sm_group_lock(&entity->en_sm_group);
442  m0_sm_move(&entity->en_sm, 0, M0_ES_OPEN);
444  }
445 
446  M0_LEAVE();
447  return;
448 }
449 
450 
457 static void cob_complete_op(struct m0_op *op)
458 {
459  struct m0_sm_group *op_grp;
460 
461  M0_ENTRY();
462  M0_PRE(op != NULL);
463 
465 
466  op_grp = &op->op_sm_group;
467  m0_sm_group_lock(op_grp);
468  m0_sm_move(&op->op_sm, 0, M0_OS_EXECUTED);
469  /* TODO Callbacks */
471  /* XXX: currently we do this straightaway */
472  m0_sm_move(&op->op_sm, 0, M0_OS_STABLE);
473  m0_op_stable(op);
474  /* TODO Callbacks */
475  m0_sm_group_unlock(op_grp);
476 
477  M0_LEAVE();
478 }
479 
489 static void cob_fail_op(struct m0_op *op, int rc)
490 {
491  struct m0_sm_group *op_grp;
492  struct m0_sm_group *en_grp;
493 
494  M0_ENTRY();
495  M0_PRE(rc != 0);
496 
497  op_grp = &op->op_sm_group;
498  en_grp = &op->op_entity->en_sm_group;
499 
500  /* Avoid cancelling rpc items and setting op's state multiple times. */
501  if (op->op_sm.sm_rc != 0)
502  goto out;
503 
504  /*
505  * Move the state machines: op and entity.
506  *
507  * This function getting called signals that a reply to a request has
508  * arrived from the server, resulting in the op being completed
509  * stably. The return code for the failure of the operation is captured
510  * in op->op_rc.
511  */
512  m0_sm_group_lock(en_grp);
513  switch(op->op_entity->en_sm.sm_state) {
514  case M0_ES_INIT:
515  break;
516  case M0_ES_OPENING:
517  /* fallthrough */
518  case M0_ES_CREATING:
519  m0_sm_move(&op->op_entity->en_sm, 0, M0_ES_OPEN);
520  /* fallthrough */
521  case M0_ES_OPEN:
522  m0_sm_move(&op->op_entity->en_sm, 0, M0_ES_CLOSING);
523  /* fallthrough */
524  default:
525  m0_sm_move(&op->op_entity->en_sm, 0, M0_ES_INIT);
526  }
527  m0_sm_group_unlock(en_grp);
528 
529  op->op_rc = rc;
530  m0_sm_group_lock(op_grp);
531  M0_ASSERT(M0_IN(op->op_sm.sm_state,
533  /*
534  * It is possible that cob_fail_op() is called before
535  * an op is launched. For example, rpc sessions to io/md
536  * services are invalid for some reason and no fop are
537  * sent. In this case, the op is still in INITIALISED state
538  * when reaching here.
539  */
540  if (op->op_sm.sm_state == M0_OS_LAUNCHED) {
541  m0_sm_move(&op->op_sm, 0, M0_OS_EXECUTED);
543  m0_sm_move(&op->op_sm, 0, M0_OS_STABLE);
544  m0_op_stable(op);
545  } else {
546  m0_sm_move(&op->op_sm, op->op_rc, M0_OS_FAILED);
547  m0_op_failed(op);
548  }
549  m0_sm_group_unlock(op_grp);
550 
551 out:
552  M0_LEAVE();
553 }
554 
555 M0_INTERNAL void cob_rep_attr_copy(struct cob_req *cr)
556 {
557  struct m0_fop_getattr_rep *getattr_rep;
558  struct m0_fop_cob_getattr_reply *getattr_ios_rep;
559  struct m0_fop_cob *body;
560  struct m0_cob_attr *cob_attr;
561  struct m0_client *cinst;
562 
563  M0_PRE(cr != NULL);
564  M0_PRE(cr->cr_cinst != NULL);
565  M0_PRE(cr->cr_cob_attr != NULL);
566  M0_PRE(cr->cr_rep_fop != NULL);
567 
568  cinst = cr->cr_cinst;
569  cob_attr = cr->cr_cob_attr;
570  if (!cinst->m0c_config->mc_is_oostore) {
571  getattr_rep = m0_fop_data(cr->cr_rep_fop);
572  if (getattr_rep->g_rc == 0) {
573  body = &getattr_rep->g_body;
574  cob_body_wire2mem(cob_attr, body);
575  }
576  } else {
577  getattr_ios_rep = m0_fop_data(cr->cr_rep_fop);
578  if (getattr_ios_rep->cgr_rc == 0) {
579  body = &getattr_ios_rep->cgr_body;
580  cob_body_wire2mem(cob_attr, body);
581  }
582  }
583 }
584 
585 static void cob_rep_process(struct cob_req *cr)
586 {
587  struct m0_obj *obj;
588  struct m0_op_common *oc;
589  struct m0_op_layout *ol;
590  struct m0_cob_attr *cob_attr = cr->cr_cob_attr;
591 
592  switch (cr->cr_opcode) {
593  case M0_EO_GETATTR:
594  cob_rep_attr_copy(cr);
596  m0__obj_attr_set(obj, cob_attr->ca_pver, cob_attr->ca_lid);
597  break;
598  case M0_EO_LAYOUT_GET:
599  cob_rep_attr_copy(cr);
600  oc = bob_of(cr->cr_op, struct m0_op_common,
601  oc_op, &op_bobtype);
602  ol = bob_of(oc, struct m0_op_layout, ol_oc, &ol_bobtype);
604  ol->ol_ops->olo_copy_to_app(ol->ol_layout, cob_attr);
605  break;
606  default:
607  M0_LOG(M0_DEBUG, "no action needed.");
608  break;
609  }
610 }
611 
618 static void cob_ast_complete_cr(struct m0_sm_group *grp,
619  struct m0_sm_ast *ast)
620 {
621  struct m0_ast_rc *ar;
622  struct cob_req *cr;
623  struct m0_op *op;
624 
625  M0_ENTRY();
626  M0_PRE(grp != NULL);
628  M0_PRE(ast != NULL);
629 
630  ar = bob_of(ast, struct m0_ast_rc, ar_ast, &ar_bobtype);
631  cr = bob_of(ar, struct cob_req, cr_ar, &cr_bobtype);
632  M0_ASSERT(ar->ar_rc == 0);
633 
634  /* Process the reply according to the type of op. */
635  op = cr->cr_op;
636  cob_rep_process(cr);
637  cob_req_free(cr);
639  M0_LEAVE();
640 }
641 
642 static void cob_fail_cr(struct cob_req *cr, int rc)
643 {
644  struct m0_op *op;
645  M0_ENTRY();
646  M0_ASSERT(rc != 0);
647 
648  op = cr->cr_op;
649  cob_req_free(cr);
650  cob_fail_op(op, rc);
651 
652  M0_LEAVE();
653 }
654 
661 static void cob_ast_fail_cr(struct m0_sm_group *grp,
662  struct m0_sm_ast *ast)
663 {
664  struct cob_req *cr;
665  struct m0_ast_rc *ar;
666 
667  M0_ENTRY();
668 
669  M0_PRE(grp != NULL);
671  M0_PRE(ast != NULL);
672 
673  ar = bob_of(ast, struct m0_ast_rc, ar_ast, &ar_bobtype);
674  cr = bob_of(ar, struct cob_req, cr_ar, &cr_bobtype);
675  M0_ASSERT(ar->ar_rc != 0);
676  cob_fail_cr(cr, ar->ar_rc);
677 
678  M0_LEAVE();
679 }
680 
681 
696 static struct ios_cob_req *
698 {
699  struct m0_fop *fop;
700  struct ios_cob_req *icr;
701 
702  M0_ENTRY();
703  M0_PRE(item != NULL);
704 
706  icr = (struct ios_cob_req *)fop->f_opaque;
707 
708  M0_LEAVE();
709  return icr;
710 }
711 
712 static void icrs_complete(struct cob_req *cr)
713 {
714  uint32_t i;
715  uint32_t cob_type;
716 
717  M0_ENTRY();
718 
719  if (M0_FI_ENABLED("skip_post_cr_ast")) {
720  cob_complete_op(cr->cr_op);
721  M0_LEAVE();
722  return;
723  }
724 
725  cob_type = cr->cr_cob_type;
726  if (cob_type == M0_COB_IO ||
727  M0_IN(cr->cr_opcode,
728  (M0_EO_CREATE,
732  } else {
733  /*
734  * M0_COB_MD
735  * Just finished creating metadata in selected io services,
736  * start the 2nd phase now (to prepare COB fops for all io
737  * services).
738  */
739  for (i = 0; i < cr->cr_icr_nr; i++)
740  cr->cr_ios_replied[i] = false;
742  }
744 
745  M0_LEAVE();
746 }
747 
748 static void icrs_fail(struct cob_req *cr, int rc)
749 {
750  M0_ENTRY();
751  M0_PRE(cr != NULL);
752 
753  if (M0_FI_ENABLED("skip_post_cr_ast")) {
754  cob_fail_op(cr->cr_op, rc);
755  M0_LEAVE();
756  return;
757  }
758  cob_fail_cr(cr, rc);
759 
760  M0_LEAVE();
761 }
762 
763 static int icrs_rc(struct cob_req *cr)
764 {
765  int rc = 0;
766  int i = 0;
767  struct m0_fop *fop;
768  struct ios_cob_req *icr;
769 
770  for (i = 0; i < cr->cr_icr_nr; ++i) {
771  fop = cr->cr_ios_fop[i];
772  if (fop == NULL)
773  continue;
774  icr = (struct ios_cob_req *)fop->f_opaque;
775  M0_ASSERT(icr != NULL);
776  rc = icr->icr_ar.ar_rc;
777 
778  if (M0_IN(cr->cr_opcode,
780  /*
781  * GETATTR and LAYOUT_GET are considered successful as
782  * long as one cob reply is successful.
783  */
784  if (rc == 0)
785  break;
786  } else {
787  /*
788  * Other types of OP have to receive all successful
789  * replies.
790  */
791  if (rc != 0)
792  break;
793  }
794  }
795 
796  return M0_RC(rc);
797 }
798 
806 static void icr_ast(struct m0_sm_group *grp,
807  struct m0_sm_ast *ast)
808 {
809  int i = 0;
810  int icr_idx;
811  int rc;
812  bool all_replied = true;
813  struct ios_cob_req *icr;
814  struct m0_ast_rc *ar;
815  struct cob_req *cr;
816 
817  M0_ENTRY();
818  M0_PRE(grp != NULL);
820  M0_PRE(ast != NULL);
821 
822  ar = bob_of(ast, struct m0_ast_rc, ar_ast, &ar_bobtype);
823  icr = bob_of(ar, struct ios_cob_req, icr_ar, &icr_bobtype);
825  cr = icr->icr_cr;
826  M0_ASSERT(cr->cr_ios_replied != NULL);
827  icr_idx = icr->icr_index;
828  cr->cr_ios_replied[icr_idx] = true;
829 
830  /*
831  * MUST check the error code before getting the latest reply
832  * fop from reply rpc item. Note that ar_rc records any
833  * rpc item error (see cob_ios_rio_replied()). If
834  * there is any error in a rpc item for some reason, the item
835  * will be freed (internally in rpc sub-system), including the
836  * reply item associated with it.
837  */
838  if (ar->ar_rc == 0) {
839  M0_ASSERT(cr->cr_ios_fop[icr_idx]->f_item.ri_reply != NULL);
841  cr->cr_ios_fop[icr_idx]->f_item.ri_reply);
842  }
843 
844  /* Check if all replies are received. */
845  for (i = 0; i < cr->cr_icr_nr; ++i) {
846  if (cr->cr_ios_fop[i] == NULL)
847  continue;
848 
849  all_replied = cr->cr_ios_replied[i];
850  if (all_replied == false)
851  break;
852  }
853  if (all_replied == false) {
854  M0_LEAVE();
855  return;
856  }
857 
858  /* Check if the request succeeds or fails. */
859  rc = icrs_rc(cr);
860  if (rc == 0)
861  icrs_complete(cr);
862  else
863  icrs_fail(cr, rc);
864  M0_LEAVE();
865 }
866 
874 {
875  struct ios_cob_req *icr;
876  struct m0_fop *rep_fop;
877  struct m0_fop_cob_op_reply *cob_rep;
878  struct cob_req *cr;
879  struct m0_ast_rc *ar;
880  int rc;
881 
882  M0_ENTRY();
883  M0_PRE(item != NULL);
884 
885  icr = rpc_item_to_icr(item);
886  M0_ASSERT(icr != NULL);
887  cr = icr->icr_cr;
888  ar = &icr->icr_ar;
889  /* Failure in rpc? */
891  if (rc == 0) {
892  /*
893  * According to m0_rpc_item_error(), it returns 0 when
894  * item->ri_reply == NULL, this doesn't look right for replies
895  * of cob operations. We enforce an assert here to ensure it
896  * isn't NULL.
897  */
900  cob_rep = m0_fop_data(rep_fop);
901  /* Failure in operation specific phase? */
902  rc = cob_rep->cor_rc;
903  } else
904  M0_LOG(M0_ERROR, "rpc item error = %d", rc);
905 
906  /*
907  * Note: each icr is only associated to one single ioservice/rpc_item so
908  * only one component should be accessing it at the same time.
909  */
910  ar->ar_rc = rc;
911  ar->ar_ast.sa_cb = &icr_ast;
912  m0_sm_ast_post(cr->cr_op_sm_grp, &ar->ar_ast);
913 
914  M0_LEAVE();
915 }
916 
920 static const struct m0_rpc_item_ops cob_ios_ri_ops = {
922 };
923 
924 M0_INTERNAL struct m0_rpc_session*
926  uint64_t container_id)
927 {
928  struct m0_reqh_service_ctx *ios_ctx;
929 
930  M0_ENTRY();
931 
932  M0_PRE(pver != NULL);
933  M0_PRE(container_id < pver->pv_pc->pc_nr_devices);
934 
935  ios_ctx = pver->pv_pc->pc_dev2svc[container_id].pds_ctx;
936  M0_ASSERT(ios_ctx != NULL);
937  M0_ASSERT(ios_ctx->sc_type == M0_CST_IOS);
938 
939  if (M0_FI_ENABLED("rpc_session_cancel")) {
941  }
942 
943  M0_LEAVE();
944  return &ios_ctx->sc_rlink.rlk_sess;
945 }
946 
957 static int cob_ios_fop_populate(struct cob_req *cr,
958  struct m0_fop *fop,
959  struct m0_fid *cob_fid,
960  uint32_t cob_idx)
961 {
962  int valid = 0;
963  struct m0_cob_attr attr;
964  struct m0_fop_cob_common *common;
965  struct m0_client *cinst;
966  uint32_t cob_type;
967 
968  M0_ENTRY();
969 
970  M0_PRE(cr != NULL);
971  M0_PRE(fop != NULL);
972  M0_PRE(cob_fid != NULL);
973 
974  cob_type = cr->cr_cob_type;
975  common = m0_cobfop_common_get(fop);
976  M0_ASSERT(common != NULL);
977  cinst = cr->cr_cinst;
978  M0_ASSERT(cinst != NULL);
979 
980  /*
981  * Fill the m0_fop_cob_common. Note: commit c5ba7b47f68 introduced
982  * attributes in a ios cob fop (struct m0_fop_cob c_body), they
983  * have to be set properly before sent on wire.
984  */
985  cob_attr_init(cr, &attr, &valid);
986  cob_body_mem2wire(&common->c_body, &attr, valid, cr);
987  common->c_gobfid = cr->cr_fid;
988  common->c_cobfid = *cob_fid;
989  common->c_pver = cr->cr_pver;
990  common->c_cob_type = cob_type;
991  /* For special "meta cobs", this would be some special value,
992  * e.g. -1. @todo this will be done in MM hash function task.
993  */
994  common->c_cob_idx = cob_idx;
995  /* COB may not be created yet */
997  common->c_flags |= M0_IO_FLAG_CROW;
998 
999  return M0_RC(0);
1000 }
1001 
1002 static void cob_ios_fop_fini(struct m0_fop *ios_fop)
1003 {
1004  M0_ENTRY();
1005  M0_PRE(ios_fop != NULL);
1006 
1007  /*
1008  * m0_rpc_item_cancel may have already put the fop and finalised the rpc
1009  * item which this fop links to. This may leave the rpc_mach == NULL.
1010  */
1011  if (m0_fop_rpc_machine(ios_fop) != NULL)
1012  m0_fop_put_lock(ios_fop);
1013 
1014  M0_LEAVE();
1015 }
1016 
1017 static void cob_ios_fop_release(struct m0_ref *ref)
1018 {
1019  struct m0_fop *fop;
1020  struct ios_cob_req *icr;
1021 
1022  M0_ENTRY();
1023  M0_PRE(ref != NULL);
1024 
1025  fop = M0_AMB(fop, ref, f_ref);
1026  icr = (struct ios_cob_req *)fop->f_opaque;
1027  if (icr != NULL) {
1028  m0_ast_rc_bob_fini(&icr->icr_ar);
1029  ios_cob_req_bob_fini(icr);
1030  m0_free(icr);
1031  }
1032  m0_fop_fini(fop);
1033  m0_free(fop);
1034 
1035  M0_LEAVE();
1036 }
1037 
1044 static int cob_ios_fop_get(struct cob_req *cr,
1045  uint32_t i, uint32_t cob_type,
1046  struct m0_rpc_session *session)
1047 {
1048  int rc;
1049  struct m0_fop *fop;
1050  struct m0_fop_type *ftype = NULL;
1051  struct ios_cob_req *icr;
1052 
1053  if (cr->cr_ios_fop[i] != NULL) {
1054  /*
1055  * oo_ios_fop[i] != NULL could happen in the following 2 cases:
1056  * (1) resending a fop when Client has out of date pool version,
1057  * (2) sending ios cob io fops after ios cob md fops in oostore
1058  * mode.
1059  * In the case 2, fops for cob md and io have different values
1060  * like index. To make thing simple now, fop is freed first
1061  * then allocated.
1062  *
1063  * TODO: revisit to check if we can re-use fop.
1064  */
1065  fop = cr->cr_ios_fop[i];
1066  M0_ASSERT(fop->f_opaque != NULL);
1067 
1069  cr->cr_ios_fop[i] = NULL;
1070  }
1071 
1072  /* Select the fop type to be sent to the ioservice. */
1073  switch (cr->cr_opcode) {
1074  case M0_EO_CREATE:
1075  ftype = &m0_fop_cob_create_fopt;
1076  break;
1077  case M0_EO_DELETE:
1078  ftype = &m0_fop_cob_delete_fopt;
1079  break;
1080  case M0_EO_GETATTR:
1081  case M0_EO_LAYOUT_GET:
1082  ftype = &m0_fop_cob_getattr_fopt;
1083  break;
1084  case M0_EO_SETATTR:
1085  case M0_EO_LAYOUT_SET:
1086  ftype = &m0_fop_cob_setattr_fopt;
1087  break;
1088  default:
1089  M0_IMPOSSIBLE("Operation not supported");
1090  }
1091 
1092  /*
1093  * Allocate and set a cob fop. Set self-defined fop release
1094  * function to free ios cob request.
1095  */
1096  M0_ALLOC_PTR(fop);
1097  if (fop == NULL)
1098  return M0_ERR_INFO(-ENOMEM, "fop allocation failed");
1099 
1102  if (rc != 0) {
1104  return M0_ERR_INFO(rc, "fop data allocation failed");
1105  }
1106 
1107  /* The rpc's callback must know which oo's slot they work on. */
1108  if (cr->cr_flags & COB_REQ_ASYNC) {
1109  M0_ALLOC_PTR(icr);
1110  if (icr == NULL) {
1112  return M0_ERR_INFO(-ENOMEM, "failed allocation of"
1113  "ios_cob_request");
1114  }
1115  ios_cob_req_bob_init(icr);
1116  m0_ast_rc_bob_init(&icr->icr_ar);
1117  icr->icr_index = i;
1118  icr->icr_cr = cr;
1119  fop->f_opaque = icr;
1120  }
1121  cr->cr_ios_fop[i] = fop;
1122  return M0_RC(0);
1123 }
1124 
1135 static int cob_ios_prepare(struct cob_req *cr, uint32_t idx)
1136 {
1137  int rc;
1138  uint32_t cob_idx;
1139  uint32_t cob_type;
1140  struct m0_fid cob_fid;
1141  const struct m0_fid *gob_fid;
1142  struct m0_client *cinst;
1143  struct m0_rpc_session *session;
1144  struct m0_fop *fop;
1145  struct m0_pool_version *pv;
1146 
1147  M0_ENTRY();
1148 
1149  /*
1150  * Sanity checks. Note: ios_prepare may be called via ios_md_send
1151  * or ios_io_send. In the case of ios_md_send, the instance
1152  * lock has been held.
1153  */
1154  M0_PRE(cr != NULL);
1155  M0_PRE(M0_IN(cr->cr_cob_type, (M0_COB_IO, M0_COB_MD)));
1156  cinst = cr->cr_cinst;
1157  M0_PRE(cinst != NULL);
1159  &cr->cr_pver);
1160  M0_ASSERT(pv != NULL);
1161 
1162  /* Determine cob fid and idx */
1163  cob_type = cr->cr_cob_type;
1164  gob_fid = &cr->cr_fid;
1165  if (cob_type == M0_COB_IO) {
1167  cob_idx = m0_fid_cob_device_id(&cob_fid);
1168  M0_ASSERT(cob_idx != ~0);
1170  } else { /* M0_COB_MD */
1172  &cinst->m0c_reqh, gob_fid, idx);
1174  cob_idx = idx;
1175  }
1176  M0_ASSERT(cob_idx != ~0);
1177  M0_ASSERT(session != NULL);
1178 
1179  if (M0_FI_ENABLED("invalid_rpc_session")) {
1180  rc = M0_ERR(-EINVAL);
1181  goto exit;
1182  }
1183 
1185  if (rc != 0)
1186  goto exit;
1187 
1188  /* Allocate ios fop if necessary */
1189  rc = cob_ios_fop_get(cr, idx, cob_type, session);
1190  if (rc != 0)
1191  goto exit;
1192  M0_ASSERT(cr->cr_ios_fop[idx] != NULL);
1193  fop = cr->cr_ios_fop[idx];
1194 
1195  /* Fill the cob fop. */
1196  rc = cob_ios_fop_populate(cr, fop, &cob_fid, cob_idx);
1197  if (rc != 0)
1198  goto exit;
1199 
1200  /*
1201  * Set and send the rpc item. Note: ri_deadline is set to
1202  * COB_REQ_DEADLINE from 'now' to allow RPC formation to pack the fops
1203  * and to improve network utilization. (See commit 09c0a46368 for
1204  * details).
1205  */
1209  fop->f_item.ri_deadline = 0;
1210  /*m0_time_from_now(0, IOS_COB_REQ_DEADLINE);*/
1213 
1214 exit:
1215  if (rc != 0) {
1216  M0_LOG(M0_DEBUG, "fop prepare failed: rc=%d cr=%p idx=%"PRIu32,
1217  rc, cr, idx);
1218  if (cr->cr_ios_fop[idx] != NULL) {
1219  cob_ios_fop_fini(cr->cr_ios_fop[idx]);
1220  cr->cr_ios_fop[idx] = NULL;
1221  }
1222  }
1223  M0_POST(equi(rc == 0, cr->cr_ios_fop[idx] != NULL));
1224  return M0_RC(rc);
1225 }
1226 
1236 static int cob_ios_send(struct cob_req *cr, uint32_t idx)
1237 {
1238  int rc;
1239  struct m0_fop *fop;
1240 
1241  M0_ENTRY();
1242 
1243  /*
1244  * Sanity checks. Note: ios_send may be called via ios_md_send
1245  * or ios_io_send. In the case of ios_md_send, the instance
1246  * lock has been held.
1247  */
1248  M0_PRE(cr != NULL);
1249  M0_PRE(M0_IN(cr->cr_cob_type, (M0_COB_IO, M0_COB_MD)));
1250 
1251  fop = cr->cr_ios_fop[idx];
1252  M0_PRE(fop != NULL);
1253 
1254  if (cr->cr_flags & COB_REQ_ASYNC) {
1256  (void)m0_rpc_post(&fop->f_item);
1257  cob_req_to_rpc_map(cr, &fop->f_item);
1258  /*
1259  * Note: if m0_rpc_post() fails for some reason
1260  * m0_rpc_item_ops::rio_replied will be invoked. To
1261  * avoid double fini/free fop, simply return and do
1262  * nothing here.
1263  */
1264  } else {
1266  if (rc != 0) {
1268  cr->cr_ios_fop[idx] = NULL;
1269  return M0_ERR(rc);
1270  }
1272  }
1273  return M0_RC(0);
1274 }
1275 
1276 static int cob_ios_req_send_sync(struct cob_req *cr)
1277 {
1278  int rc = 0;
1279  uint32_t i;
1280  uint32_t icr_nr = cr->cr_icr_nr;
1281 
1282  M0_ENTRY("cr=%p cr->cr_cob_type=%"PRIu32, cr, cr->cr_cob_type);
1283  M0_PRE(cr->cr_flags & COB_REQ_SYNC);
1284 
1285  for (i = 0; i < icr_nr; ++i) {
1286  rc = cob_ios_prepare(cr, i) ?:
1287  cob_ios_send(cr, i);
1288 
1289  /*
1290  * Only one succeful request is enough for synchronous
1291  * GETATTR and LAYOUT_GET OPs.
1292  */
1293  if (rc == 0 && M0_IN(cr->cr_opcode, (M0_EO_GETATTR,
1294  M0_EO_LAYOUT_GET)))
1295  break;
1296  /*
1297  * One failure ios cob request fails the whole request
1298  * for other synchronous OPs.
1299  */
1300  if (rc != 0 && !M0_IN(cr->cr_opcode, (M0_EO_GETATTR,
1301  M0_EO_LAYOUT_GET)))
1302  break;
1303  }
1304  return M0_RC(rc);
1305 }
1306 
1307 static int cob_ios_req_send_async(struct cob_req *cr)
1308 {
1309  int rc = 0;
1310  bool all_failed = true;
1311  uint32_t i;
1312  uint32_t icr_nr = cr->cr_icr_nr;
1313 
1314  M0_ENTRY("cr=%p cr->cr_cob_type=%"PRIu32, cr, cr->cr_cob_type);
1315  M0_PRE(cr->cr_flags & COB_REQ_ASYNC);
1316 
1317  /*
1318  * Prepare all fops before sending. It avoids race between
1319  * setting cr->cr_ios_fop and icr_ast() execution.
1320  */
1321  for (i = 0; i < icr_nr; ++i) {
1322  rc = cob_ios_prepare(cr, i);
1323  /*
1324  * Silence possible compiler's warnings about re-assigning rc.
1325  * If prepare phase fails for all fops, we will return the last
1326  * non zero rc. Otherwise, rc will be assigned in the following
1327  * loop.
1328  */
1329  (void)rc;
1330  }
1331  for (i = 0; i < icr_nr; ++i) {
1332  if (cr->cr_ios_fop[i] != NULL) {
1333  rc = cob_ios_send(cr, i);
1334  all_failed = all_failed && (rc != 0);
1335  }
1336  }
1337  /*
1338  * For async OPs, report error to caller only if all ios cob requests
1339  * fail.
1340  */
1341  M0_POST(ergo(all_failed && icr_nr > 0, rc != 0));
1342  return M0_RC(all_failed ? rc : 0);
1343 }
1344 
1353  struct m0_sm_ast *ast)
1354 {
1355  int rc;
1356  uint32_t pool_width;
1357  struct m0_ast_rc *ar;
1358  struct m0_client *cinst;
1359  struct m0_pool_version *pv;
1360  struct cob_req *cr;
1361 
1362  M0_ENTRY();
1363 
1364  M0_PRE(grp != NULL);
1366  M0_PRE(ast != NULL);
1367 
1368  ar = bob_of(ast, struct m0_ast_rc, ar_ast, &ar_bobtype);
1369  cr = bob_of(ar, struct cob_req, cr_ar, &cr_bobtype);
1370 
1371  cinst = cr->cr_cinst;
1372  M0_ASSERT(cinst != NULL);
1373 
1375  if (pv == NULL) {
1376  rc = M0_ERR_INFO(-ENOENT, "Failed to get pool version "FID_F,
1377  FID_P(&cr->cr_pver));
1378  goto exit;
1379  }
1380  pool_width = pv->pv_attr.pa_P;
1381  M0_ASSERT(pool_width >= 1);
1382 
1383  /* Send a fop to each COB. */
1384  cr->cr_cob_type = M0_COB_IO;
1385  cr->cr_icr_nr = pool_width;
1386  rc = cob_ios_req_send_async(cr);
1387  /*
1388  * If all ios cob requests fail, rc != 0. Otherwise, the rpc item
1389  * callback handles those fops sent.
1390  */
1391 
1392 exit:
1393  if (rc != 0)
1394  cob_fail_cr(cr, rc);
1395 
1396  M0_LEAVE();
1397 }
1398 
1406 static int cob_ios_md_send(struct cob_req *cr)
1407 {
1408  int rc;
1409  struct m0_client *cinst;
1410 
1411  M0_ENTRY();
1412  M0_PRE(cr != NULL);
1413  cinst = cr->cr_cinst;
1414  M0_ASSERT(cinst != NULL);
1417 
1418  /*
1419  * Send to each redundant ioservice.
1420  * It is possible that ios_io_send is called right before ios_md_send
1421  * completes the for loop below (but all M0_COB_MD requests are sent and
1422  * replied). So the content of 'oo' may be changed. Be aware of this
1423  * race condition!
1424  */
1427  cr->cr_cob_type = M0_COB_MD;
1428  rc = (cr->cr_flags & COB_REQ_SYNC) ?
1429  cob_ios_req_send_sync(cr) :
1431 
1432  return M0_RC(rc);
1433 }
1434 
1435 /*----------------------------------------------------------------------------*
1436  * COB FOP's for mdservice *
1437  *----------------------------------------------------------------------------*/
1438 
1448 static struct cob_req* rpc_item_to_cr(struct m0_rpc_item *item)
1449 {
1450  struct m0_fop *fop;
1451  struct cob_req *cr;
1452 
1453  M0_ENTRY();
1454  M0_PRE(item != NULL);
1455 
1457  cr = (struct cob_req *)fop->f_opaque;
1458 
1459  M0_LEAVE();
1460  return cr;
1461 }
1462 
1473 {
1474  int rc;
1475  uint32_t rep_opcode;
1476  uint32_t req_opcode;
1477  struct m0_fop *rep_fop;
1478  struct m0_fop *req_fop;
1479  struct m0_fop_create_rep *create_rep;
1480  struct m0_fop_unlink_rep *unlink_rep;
1481  struct m0_fop_getattr_rep *getattr_rep;
1482  struct m0_fop_setattr_rep *setattr_rep;
1483  struct m0_client *cinst;
1484  struct cob_req *cr;
1485  struct m0_reqh_service_ctx *ctx;
1486  struct m0_be_tx_remid *remid = NULL;
1487 
1488  M0_ENTRY();
1489 
1490  M0_PRE(item != NULL);
1491  cr = rpc_item_to_cr(item);
1492  M0_ASSERT(cr != NULL);
1493  cinst = cr->cr_cinst;
1494  M0_ASSERT(cinst != NULL);
1495  req_fop = cr->cr_mds_fop;
1496  M0_ASSERT(req_fop != NULL);
1497  M0_ASSERT(cr->cr_op != NULL);
1498 
1499  /* Failure in rpc? */
1501  if (rc != 0) {
1502  M0_LOG(M0_ERROR, "rpc item error = %d", rc);
1503  goto error;
1504  }
1505 
1506  M0_ASSERT(item->ri_reply != NULL);
1508  cr->cr_rep_fop = rep_fop;
1509  req_opcode = m0_fop_opcode(req_fop);
1510  rep_opcode = m0_fop_opcode(rep_fop);
1511 
1512  /* Failure in operation specific phase? */
1513  switch (rep_opcode) {
1515  M0_ASSERT(req_opcode == M0_MDSERVICE_CREATE_OPCODE);
1516  create_rep = m0_fop_data(rep_fop);
1517  rc = create_rep->c_body.b_rc;
1518  remid = &create_rep->c_mod_rep.fmr_remid;
1519  break;
1520 
1522  M0_ASSERT(req_opcode == M0_MDSERVICE_UNLINK_OPCODE);
1523  unlink_rep = m0_fop_data(rep_fop);
1524  rc = unlink_rep->u_body.b_rc;
1525  remid = &unlink_rep->u_mod_rep.fmr_remid;
1526  break;
1527 
1529  getattr_rep = m0_fop_data(rep_fop);
1530  rc = getattr_rep->g_body.b_rc;
1531  M0_ASSERT(req_opcode == M0_MDSERVICE_GETATTR_OPCODE);
1532  break;
1533 
1535  M0_ASSERT(req_opcode == M0_MDSERVICE_SETATTR_OPCODE);
1536  setattr_rep = m0_fop_data(rep_fop);
1537  rc = setattr_rep->s_body.b_rc;
1538  remid = &setattr_rep->s_mod_rep.fmr_remid;
1539  break;
1540 
1541  default:
1542  M0_IMPOSSIBLE("Unsupported opcode:%d.", rep_opcode);
1543  break;
1544  }
1545  if (rc != 0)
1546  goto error;
1547 
1548  /* Update pending transaction number */
1549  if (remid != NULL) {
1551  sync_record_update(ctx, NULL, cr->cr_op != NULL ?
1552  cr->cr_op : NULL, remid);
1553  }
1554 
1555  /*
1556  * Commit 2332f298 introduced a optimisation for CREATE
1557  * which delays creating COBs to the first time they are
1558  * written to.
1559  */
1560  if (M0_IN(cr->cr_opcode,
1561  (M0_EO_CREATE,
1565  else
1568 
1569  M0_LEAVE();
1570  return;
1571 
1572 error:
1573  M0_ASSERT(rc != 0);
1575  cr->cr_ar.ar_rc = rc;
1577  M0_LEAVE();
1578 }
1579 
1583 static const struct m0_rpc_item_ops cob_mds_ri_ops = {
1585 };
1586 
1595 static int cob_mds_fop_populate(struct cob_req *cr,
1596  struct m0_fop *fop)
1597 {
1598  int rc = 0;
1599  int valid = 0;
1600  struct m0_cob_attr attr;
1601  struct m0_fop_create *create;
1602  struct m0_fop_unlink *unlink;
1603  struct m0_fop_getattr *getattr;
1604  struct m0_fop_cob *req;
1605 
1606  M0_ENTRY();
1607  M0_PRE(fop != NULL);
1608 
1609  cob_attr_init(cr, &attr, &valid);
1610 
1611  switch (m0_fop_opcode(fop)) {
1613  create = m0_fop_data(fop);
1614  req = &create->c_body;
1615  cob_body_mem2wire(req, &attr, valid, cr);
1616 #ifdef CLIENT_FOR_M0T1FS
1617  rc = cob_name_mem2wire(&create->c_name, &cr->cr_name);
1618 #endif
1619  break;
1621  unlink = m0_fop_data(fop);
1622  req = &unlink->u_body;
1623  cob_body_mem2wire(req, &attr, valid, cr);
1624 #ifdef CLIENT_FOR_M0T1FS
1625  rc = cob_name_mem2wire(&unlink->u_name, &cr->cr_name);
1626 #endif
1627  break;
1629  getattr = m0_fop_data(fop);
1630  req = &getattr->g_body;
1631  req->b_tfid = cr->cr_fid;
1632  req->b_valid = 0;
1633  break;
1634  default:
1635  rc = -ENOSYS;
1636  M0_IMPOSSIBLE("Can't send message of <unimplemented> type.");
1637  }
1638 
1639  return M0_RC(rc);
1640 }
1641 
1642 #ifdef CLIENT_FOR_M0T1FS /* if we want m0t1fs to reflect the changes */
1643 
1653 static struct m0_rpc_session *
1654 filename_to_mds_session(struct m0_client *cinst,
1655  const unsigned char *filename,
1656  m0_bcount_t len)
1657 {
1658  unsigned int hash;
1659  struct m0_reqh_service_ctx *mds_ctx;
1660  const struct m0_pools_common *pc;
1661 
1662  M0_ENTRY();
1663 
1664  M0_PRE(cinst != NULL);
1665  M0_PRE(filename != NULL);
1666  M0_PRE(len > 0);
1667 
1668  /* XXX implement use_cache_hint */
1669 
1670  /* XXX: possible uint overflow */
1671  /* XXX: no guarantee unsigned int == UINT32, we need a better way to
1672  * check this */
1674  hash = m0_full_name_hash(filename, (unsigned int)len);
1675 
1677  mds_ctx = pc->pc_mds_map[hash % pc->pc_nr_svcs[M0_CST_MDS]];
1678  M0_ASSERT(mds_ctx != NULL);
1679 
1680  M0_LEAVE();
1681  return &mds_ctx->sc_rlink.rlk_sess;
1682 }
1683 
1684 #else
1685 
1693 static struct m0_rpc_session *
1695 {
1696  const struct m0_pools_common *pc;
1697  struct m0_service_context *mds_ctx;
1698 
1699  M0_ENTRY();
1700 
1701  M0_PRE(cinst != NULL);
1702 
1703  /* XXX implement use_cache_hint */
1704 
1706  mds_ctx = pc->pc_mds_map[fid->f_key % pc->pc_nr_svcs[M0_CST_MDS]];
1707  M0_ASSERT(mds_ctx != NULL);
1708 
1709  M0_LEAVE();
1710  return &mds_ctx->sc_rlink.rlk_sess;
1711 }
1712 #endif
1713 
1721 static int cob_mds_send(struct cob_req *cr)
1722 {
1723  int rc;
1724  struct m0_fop *fop;
1725  struct m0_client *cinst;
1726  struct m0_rpc_session *session;
1727  struct m0_fop_type *ftype = NULL; /* Required */
1728 
1729  M0_ENTRY();
1730 
1731  M0_PRE(cr != NULL);
1732  cinst = cr->cr_cinst;
1733  M0_PRE(cinst != NULL);
1734 
1735  /* Get the mdservice's session. */
1736 #ifdef CLIENT_FOR_M0T1FS
1737  session = filename_to_mds_session(cinst,
1738  (unsigned char *)cr->cr_name.b_addr, cr->cr_name.b_nob);
1739 #else
1741 #endif
1742  M0_ASSERT(session != NULL);
1744  if (rc != 0)
1745  return M0_ERR(rc);
1746 
1747  /* Select the fop type to be sent to the mdservice. */
1748  switch (cr->cr_opcode) {
1749  case M0_EO_CREATE:
1750  ftype = &m0_fop_create_fopt;
1751  break;
1752  case M0_EO_DELETE:
1753  ftype = &m0_fop_unlink_fopt;
1754  break;
1755  case M0_EO_GETATTR:
1756  case M0_EO_LAYOUT_GET:
1757  ftype = &m0_fop_getattr_fopt;
1758  break;
1759  case M0_EO_SETATTR:
1760  case M0_EO_LAYOUT_SET:
1761  ftype = &m0_fop_setattr_fopt;
1762  break;
1763  default:
1764  M0_IMPOSSIBLE("Operation not supported:%d",
1765  cr->cr_opcode);
1766  }
1767  fop = m0_fop_alloc_at(session, ftype);
1768  if (fop == NULL) {
1769  rc = -ENOMEM;
1770  goto error;
1771  }
1772 
1773  rc = cob_mds_fop_populate(cr, fop);
1774  if (rc != 0)
1775  goto error;
1776  fop->f_opaque = cr;
1779  fop->f_item.ri_deadline = 0;
1782  cr->cr_mds_fop = fop;
1783 
1784  if (cr->cr_flags & COB_REQ_ASYNC) {
1786  rc = m0_rpc_post(&fop->f_item);
1787  if (rc != 0)
1788  goto error;
1789  } else {
1791  if (rc != 0)
1792  goto error;
1794  }
1795  return M0_RC(0);
1796 error:
1797  if (fop != NULL) {
1799  cr->cr_mds_fop = NULL;
1800  }
1801  return M0_RC(rc);
1802 }
1803 
1804 M0_INTERNAL int m0__obj_namei_send(struct m0_op_obj *oo)
1805 {
1806  int rc;
1807  struct m0_cob_attr *cob_attr;
1808  struct m0_client *cinst;
1809  struct m0_obj *obj;
1810  struct cob_req *cr;
1811  struct m0_pool_version *pv;
1812  struct m0_op *op;
1813  bool skip_meta_data = false;
1814 
1815  M0_ENTRY();
1816  M0_PRE(oo != NULL);
1817 
1818  cinst = m0__oo_instance(oo);
1819  M0_ASSERT(cinst != NULL);
1822  &oo->oo_pver);
1823  if (pv == NULL)
1824  return M0_ERR(-EINVAL);
1825  cr = cob_req_alloc(pv);
1826  if (cr == NULL)
1827  return M0_ERR(-ENOMEM);
1828 
1829  op = &oo->oo_oc.oc_op;
1830  cr->cr_cinst = cinst;
1831  cr->cr_fid = oo->oo_fid;
1832  cr->cr_op = op;
1833  cr->cr_op_sm_grp = oo->oo_sm_grp;
1834  cr->cr_flags |= COB_REQ_ASYNC;
1839  op->op_priv = cr;
1840 #ifdef CLIENT_FOR_M0T1FS
1841  cr->cr_name = oo->oo_name;
1842 #endif
1843  /* We need to perform getattr for OPEN op. */
1844  cr->cr_opcode = (OP_OBJ2CODE(oo) == M0_EO_OPEN)?
1846 
1847  M0_ALLOC_PTR(cob_attr);
1848  if (cob_attr == NULL) {
1849  cob_req_free(cr);
1850  return M0_ERR(-ENOMEM);
1851  }
1852  cr->cr_cob_attr = cob_attr;
1853 
1860  if ((M0_IN(cr->cr_opcode, (M0_EO_GETATTR, M0_EO_DELETE))) &&
1861  (obj->ob_entity.en_flags & M0_ENF_META))
1862  skip_meta_data = true;
1863 
1864  /* Set layout id and pver for CREATE op.*/
1865  if (cr->cr_opcode == M0_EO_CREATE) {
1866  cr->cr_cob_attr->ca_lid = obj->ob_attr.oa_layout_id;
1867  if (obj->ob_entity.en_flags & M0_ENF_META) {
1868  /* For create operation setting up pool version locally
1869  * found in pools common, so cob lookup call to server
1870  * can be skipped */
1871  obj->ob_attr.oa_pver = pv->pv_id;
1872  skip_meta_data = true;
1873  }
1874  }
1875 
1876  if (!skip_meta_data) {
1877  /* Send requests to services. */
1878  rc = cob_req_send(cr);
1879  if (rc != 0) {
1881  cr->cr_ar.ar_rc = rc;
1883  }
1884  } else {
1885  M0_LOG(M0_DEBUG, "skipped lookup, obj pver is:"FID_F"cr->cr_opcode:%d",
1886  FID_P(&obj->ob_attr.oa_pver), cr->cr_opcode);
1887  if (cr->cr_opcode == M0_EO_DELETE) {
1895  cr->cr_ar.ar_rc = 0;
1897  rc = 0;
1898  } else {
1899  /* We are skipping meta-data lookup here as we have received
1900  * pver from application, and hence need to move op state
1901  * LAUNCHED, EXECUTED and STABLE explicitly */
1902  m0_sm_move(&cr->cr_op->op_sm, 0, M0_OS_LAUNCHED);
1904  cob_complete_op(cr->cr_op);
1907  cob_req_free(cr);
1908  }
1909  }
1910 
1911  return M0_RC(rc);
1912 }
1913 
1914 
1915 M0_INTERNAL int m0__obj_namei_cancel(struct m0_op *op)
1916 {
1917  struct m0_fop *fop;
1918  struct cob_req *cr;
1919  int rc = 0;
1920  int i;
1921  M0_ENTRY();
1922  M0_PRE(op != NULL);
1923  M0_PRE(M0_IN(op->op_sm.sm_state, (M0_OS_LAUNCHED,
1925  M0_OS_STABLE,
1926  M0_OS_FAILED)));
1927 
1928  if (M0_IN(op->op_sm.sm_state, (M0_OS_STABLE,
1929  M0_OS_FAILED))) {
1930  /* cannot cancel a stable or failed operation */
1931  return M0_RC(rc);
1932  }
1933  m0_mutex_lock(&op->op_priv_lock);
1934  cr = op->op_priv;
1935  if (cr == NULL) {
1936  m0_mutex_unlock(&op->op_priv_lock);
1937  return M0_RC(0);
1938  }
1939  cob_req_ref_get(cr);
1940  m0_mutex_unlock(&op->op_priv_lock);
1941  M0_ASSERT(cr->cr_op == op);
1942  for (i = 0; i < cr->cr_icr_nr; ++i) {
1943  fop = cr->cr_ios_fop[i];
1945  }
1946  m0_mutex_lock(&op->op_priv_lock);
1947  op->op_priv = NULL;
1948  cob_req_ref_put(cr);
1949  m0_mutex_unlock(&op->op_priv_lock);
1950  return M0_RC(rc);
1951 }
1952 
1953 static int cob_getattr_rep_rc(struct cob_req *cr)
1954 {
1955  int rc;
1956  struct m0_fop_getattr_rep *getattr_rep;
1957  struct m0_fop_cob_getattr_reply *getattr_ios_rep;
1958 
1959  M0_PRE(cr != NULL);
1960  M0_PRE(cr->cr_cinst != NULL);
1961  M0_PRE(cr->cr_rep_fop != NULL);
1962 
1963  if (!cr->cr_cinst->m0c_config->mc_is_oostore) {
1964  getattr_rep = m0_fop_data(cr->cr_rep_fop);
1965  rc = getattr_rep->g_body.b_rc;
1966  } else {
1967  getattr_ios_rep = m0_fop_data(cr->cr_rep_fop);
1968  rc = getattr_ios_rep->cgr_body.b_rc;
1969  }
1970 
1971  return M0_RC(rc);
1972 }
1973 
1974 M0_INTERNAL int m0__obj_attr_get_sync(struct m0_obj *obj)
1975 {
1976  int rc;
1977  struct m0_client *cinst;
1978  struct cob_req *cr;
1979  struct m0_cob_attr *cob_attr;
1980  struct m0_pool_version *pv;
1981 
1982  M0_ENTRY();
1983 
1984  if (M0_FI_ENABLED("obj_attr_get_ok"))
1985  return 0;
1986 
1987  M0_PRE(obj != NULL);
1988 
1991  if (pv == NULL)
1992  return M0_ERR(-EINVAL);
1993  /* Allocate and initialise cob request. */
1994  cr = cob_req_alloc(pv);
1995  if (cr == NULL)
1996  return M0_ERR(-ENOMEM);
1997 
1998  m0_fid_gob_make(&cr->cr_fid,
1999  obj->ob_entity.en_id.u_hi, obj->ob_entity.en_id.u_lo);
2000  cr->cr_flags |= COB_REQ_SYNC;
2001  cr->cr_cinst = cinst;
2002  rc = cob_make_name(cr);
2003  if (rc != 0)
2004  goto free_req;
2005 
2006  M0_ALLOC_PTR(cob_attr);
2007  if (cob_attr == NULL) {
2008  rc = -ENOMEM;
2009  goto free_name;
2010  }
2011  cr->cr_cob_attr = cob_attr;
2012 
2013  /* Send GETATTR cob request and wait for the reply. */
2014  cr->cr_opcode = M0_EO_GETATTR;
2015  rc = cob_req_send(cr)?:
2016  cob_getattr_rep_rc(cr);
2017  if (rc != 0) {
2018  rc = (rc == -ENOENT)? M0_RC(rc) : M0_ERR(rc);
2019  goto free_attr;
2020  } else
2021  cob_rep_attr_copy(cr);
2022 
2023  /* Validate the pool version. */
2025  &cob_attr->ca_pver) == NULL) {
2026  M0_LOG(M0_ERROR, "Unable to find a suitable pool version");
2027  rc = M0_ERR(-EINVAL);
2028  goto free_attr;
2029  }
2030  m0__obj_attr_set(obj, cob_attr->ca_pver, cob_attr->ca_lid);
2031 
2032 free_attr:
2033  m0_free(cob_attr);
2034  cr->cr_cob_attr = NULL;
2035 free_name:
2036  m0_free(cr->cr_name.b_addr);
2037  M0_SET0(&cr->cr_name);
2038 free_req:
2039  cob_req_free(cr);
2040  return M0_RC(rc);
2041 }
2042 
2043 M0_INTERNAL int m0__obj_layout_send(struct m0_obj *obj,
2044  struct m0_op_layout *ol)
2045 {
2046  int rc;
2047  struct m0_uint128 ent_id;
2048  struct m0_cob_attr *cob_attr;
2049  struct m0_pool_version *pv;
2050  struct m0_client *cinst;
2051  struct cob_req *cr;
2052  struct m0_op *op = &ol->ol_oc.oc_op;
2053 
2054  M0_ENTRY();
2055  M0_PRE(M0_IN(op->op_code,
2057 
2058  ent_id = obj->ob_entity.en_id;
2059  cinst = m0__entity_instance(&obj->ob_entity);
2060  M0_ASSERT(m0_conf_fid_is_valid(&obj->ob_attr.oa_pver));
2062  &obj->ob_attr.oa_pver);
2063  M0_ASSERT(pv != NULL);
2064  cr = cob_req_alloc(pv);
2065  if (cr == NULL)
2066  return -ENOMEM;
2067 
2068  m0_fid_gob_make(&cr->cr_fid, ent_id.u_hi, ent_id.u_lo);
2069  cr->cr_flags |= COB_REQ_ASYNC;
2070  cr->cr_cinst = cinst;
2071  cr->cr_op = op;
2072  cr->cr_opcode = op->op_code;
2073  cr->cr_op_sm_grp = ol->ol_sm_grp;
2074  rc = cob_make_name(cr);
2075  if (rc != 0)
2076  goto free_req;
2077 
2078  M0_ALLOC_PTR(cob_attr);
2079  if (cob_attr == NULL) {
2080  rc = -ENOMEM;
2081  goto free_name;
2082  }
2083  cr->cr_cob_attr = cob_attr;
2084 
2085  /* Send out cob request. */
2086  if (op->op_code == M0_EO_LAYOUT_SET) {
2087  if (ol->ol_layout->ml_type == M0_LT_PDCLUST) {
2089  ol->ol_ops->olo_copy_from_app(ol->ol_layout, cob_attr);
2090  } else
2091  cr->cr_cob_attr->ca_lid = obj->ob_attr.oa_layout_id;
2092  }
2093  rc = cob_req_send(cr);
2094  if (rc != 0)
2095  goto free_attr;
2096  return M0_RC(0);
2097 
2098 free_attr:
2099  m0_free(cob_attr);
2100  cr->cr_cob_attr = NULL;
2101 free_name:
2102  m0_free(cr->cr_name.b_addr);
2103  M0_SET0(&cr->cr_name);
2104 free_req:
2105  cob_req_free(cr);
2106  return M0_RC(rc);
2107 }
2108 
2109 #undef M0_TRACE_SUBSYSTEM
2110 
2111 /*
2112  * Local variables:
2113  * c-indentation-style: "K&R"
2114 
2115  * c-basic-offset: 8
2116  * tab-width: 8
2117  * fill-column: 80
2118  * scroll-step: 1
2119  * End:
2120  */
2121 /*
2122  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
2123  */
static int cob_mds_fop_populate(struct cob_req *cr, struct m0_fop *fop)
Definition: cob.c:1595
uint64_t ca_lid
Definition: cob.h:380
uint32_t b_nlink
Definition: md_fops.h:81
M0_INTERNAL int m0_rpc_post(struct m0_rpc_item *item)
Definition: rpc.c:63
struct m0_fid m0c_root_fid
static bool ios_cob_req_invariant(struct ios_cob_req *icr)
Definition: cob.c:141
static struct m0_fid gob_fid
Definition: net.c:115
uint32_t m0_fop_opcode(const struct m0_fop *fop)
Definition: fop.c:226
struct m0_fop ** cr_ios_fop
Definition: cob.c:75
uint64_t c_flags
Definition: io_fops.h:477
const struct m0_bob_type ar_bobtype
Definition: client.c:73
m0_time_t ri_resend_interval
Definition: item.h:144
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
static void cob_ast_ios_io_send(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: cob.c:1352
M0_INTERNAL int m0__obj_layout_send(struct m0_obj *obj, struct m0_op_layout *ol)
Definition: cob.c:2043
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
M0_INTERNAL void m0_fid_gob_make(struct m0_fid *gob_fid, uint32_t container, uint64_t key)
Definition: fid_convert.c:46
struct m0_op * cr_op
Definition: cob.c:65
struct m0_cob_attr * cr_cob_attr
Definition: cob.c:80
M0_INTERNAL struct m0_fop_cob_common * m0_cobfop_common_get(struct m0_fop *fop)
Definition: io_fops.c:990
Definition: client.h:788
enum m0_rpc_item_priority ri_prio
Definition: item.h:133
static const struct m0_rpc_item_ops cob_ios_ri_ops
Definition: cob.c:920
M0_INTERNAL int m0__obj_attr_get_sync(struct m0_obj *obj)
Definition: cob.c:1974
uint32_t b_valid
Definition: md_fops.h:76
struct m0_sm_group * ol_sm_grp
Definition: layout.h:178
#define NULL
Definition: misc.h:38
static void cob_body_wire2mem(struct m0_cob_attr *attr, const struct m0_fop_cob *body)
Definition: cob.c:200
struct m0_fid b_tfid
Definition: md_fops.h:92
#define ergo(a, b)
Definition: misc.h:293
struct m0_buf oo_name
uint32_t cr_flags
Definition: cob.c:73
void(* sa_cb)(struct m0_sm_group *grp, struct m0_sm_ast *)
Definition: sm.h:506
static void cob_req_to_rpc_map(const struct cob_req *cr, const struct m0_rpc_item *item)
Definition: cob.c:128
void * b_addr
Definition: buf.h:39
const struct m0_bob_type op_bobtype
Definition: client.c:46
M0_INTERNAL struct m0_pool_version * m0_pool_version_find(struct m0_pools_common *pc, const struct m0_fid *id)
Definition: pool.c:586
static struct io_request req
Definition: file.c:100
static void cob_ast_fail_cr(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: cob.c:661
static void cob_req_free(struct cob_req *cr)
Definition: cob.c:342
M0_INTERNAL void m0_fop_init(struct m0_fop *fop, struct m0_fop_type *fopt, void *data, void(*fop_release)(struct m0_ref *))
Definition: fop.c:79
struct m0_pool_version * pv
Definition: dir.c:629
struct m0_fop_cob s_body
Definition: md_fops.h:193
struct m0_poolmach pv_mach
Definition: pool.h:133
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
M0_INTERNAL void m0_sm_ast_post(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: sm.c:135
struct m0_sm_group * oo_sm_grp
static void create(void)
Definition: service_ut.c:546
M0_INTERNAL struct cob_req * cob_req_ref_get(struct cob_req *cr)
Definition: cob.c:285
static void to_cob_req_map(const struct m0_op *op, const struct cob_req *cr)
Definition: cob.c:115
M0_INTERNAL int obj_fid_make_name(char *name, size_t name_len, const struct m0_fid *fid)
static int cob_req_send(struct cob_req *cr)
Definition: cob.c:363
struct m0_ast_rc cr_ar
Definition: cob.c:63
uint32_t cr_opcode
Definition: cob.c:68
struct m0_sm ri_sm
Definition: item.h:181
struct m0_fop_type m0_fop_getattr_fopt
Definition: md_fops.c:59
static void cob_rep_process(struct cob_req *cr)
Definition: cob.c:585
struct m0_op oc_op
void * m0_fop_data(const struct m0_fop *fop)
Definition: fop.c:220
uint32_t c_cob_type
Definition: io_fops.h:474
M0_INTERNAL void cob_rep_attr_copy(struct cob_req *cr)
Definition: cob.c:555
struct m0_fop_type m0_fop_create_fopt
Definition: md_fops.c:52
static int error
Definition: mdstore.c:64
static void cob_body_mem2wire(struct m0_fop_cob *body, struct m0_cob_attr *attr, int valid, struct cob_req *cr)
Definition: cob.c:178
static void cob_entity_sm_move(struct m0_op *op)
Definition: cob.c:409
static const struct m0_rpc_item_ops cob_mds_ri_ops
Definition: cob.c:1583
struct m0_fid c_cobfid
Definition: io_fops.h:465
static int cob_getattr_rep_rc(struct cob_req *cr)
Definition: cob.c:1953
static struct cob_req * rpc_item_to_cr(struct m0_rpc_item *item)
Definition: cob.c:1448
uint64_t m0_bcount_t
Definition: types.h:77
Definition: sm.h:504
static int icrs_rc(struct cob_req *cr)
Definition: cob.c:763
#define container_of(ptr, type, member)
Definition: misc.h:33
static struct m0_rpc_session session
Definition: formation2.c:38
#define M0_SET0(obj)
Definition: misc.h:64
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
static int cob_name_mem2wire(struct m0_fop_str *tgt, const struct m0_buf *name)
Definition: cob.c:154
M0_ADDB2_ADD(M0_AVI_FS_CREATE, new_fid.f_container, new_fid.f_key, mode, rc)
static struct m0_rpc_session * fid_to_mds_session(struct m0_client *cinst, const struct m0_fid *fid)
Definition: cob.c:1694
M0_INTERNAL bool m0_fid_is_set(const struct m0_fid *fid)
Definition: fid.c:106
static struct m0_rpc_item * item
Definition: item.c:56
struct m0_sm_group * cr_op_sm_grp
Definition: cob.c:66
uint32_t b_rc
Definition: md_fops.h:72
#define UINT32_MAX
Definition: types.h:41
static struct foo * obj
Definition: tlist.c:302
static void icr_ast(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: cob.c:806
const char * bt_name
Definition: bob.h:73
static void cob_ios_fop_fini(struct m0_fop *ios_fop)
Definition: cob.c:1002
static m0_bcount_t count
Definition: xcode.c:167
static struct m0_pools_common pc
Definition: iter_ut.c:59
Definition: dir.c:58
const struct m0_bob_type cr_bobtype
Definition: cob.c:91
struct m0_client * cr_cinst
Definition: cob.c:62
struct m0_fop_cob * body
Definition: dir.c:1436
static void cob_complete_op(struct m0_op *op)
Definition: cob.c:457
struct m0_ref cr_ref
Definition: cob.c:60
uint64_t pc_nr_svcs[M0_CST_NR]
Definition: pool.h:190
struct m0_fid fid
Definition: di.c:46
return M0_RC(rc)
op
Definition: libdemo.c:64
static int cob_ios_req_send_async(struct cob_req *cr)
Definition: cob.c:1307
#define equi(a, b)
Definition: misc.h:297
M0_INTERNAL struct m0_obj * m0__obj_entity(struct m0_entity *entity)
Definition: obj.c:51
static int cob_ios_req_send_sync(struct cob_req *cr)
Definition: cob.c:1276
#define M0_ENTRY(...)
Definition: trace.h:170
struct m0_fop_type m0_fop_cob_getattr_fopt
Definition: io_fops.c:80
struct m0_fid oo_pver
struct m0_fop_cob g_body
Definition: md_fops.h:198
Definition: buf.h:37
static struct m0_sm_ast ast[NR]
Definition: locality.c:44
M0_INTERNAL struct m0_pool_version * m0_pool_version_md_get(const struct m0_pools_common *pc)
Definition: pool.c:841
M0_INTERNAL void m0_sm_group_unlock(struct m0_sm_group *grp)
Definition: sm.c:96
M0_INTERNAL uint64_t m0_dummy_id_generate(void)
Definition: misc.c:425
enum m0_client_layout_type ml_type
Definition: client.h:798
int i
Definition: dir.c:1033
struct m0_fop_type * f_type
Definition: fop.h:81
uint64_t icr_magic
Definition: cob.c:48
struct m0_pools_common m0c_pools_common
Definition: client.h:641
struct m0_rpc_machine * m0_fop_rpc_machine(const struct m0_fop *fop)
Definition: fop.c:360
M0_INTERNAL void m0_ref_put(struct m0_ref *ref)
Definition: refs.c:38
#define M0_ERR_INFO(rc, fmt,...)
Definition: trace.h:215
struct m0_fop_cob cgr_body
Definition: io_fops.h:544
struct m0_reqh_service_ctx ** pc_mds_map
Definition: pool.h:180
void m0_ref_init(struct m0_ref *ref, int init_num, void(*release)(struct m0_ref *ref))
Definition: refs.c:24
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL void m0_ref_get(struct m0_ref *ref)
Definition: refs.c:32
uint32_t pc_md_redundancy
Definition: pool.h:210
struct m0_fid cr_fid
Definition: dir.c:63
static struct cob_req * cob_req_alloc(struct m0_pool_version *pv)
Definition: cob.c:305
struct m0_sm op_sm
Definition: client.h:656
const char * name
Definition: trace.c:110
M0_INTERNAL int m0_op_stable(struct m0_op *op)
Definition: client.c:520
struct m0_fop_mod_rep s_mod_rep
Definition: md_fops.h:194
void m0_rpc_item_cancel(struct m0_rpc_item *item)
Definition: item.c:932
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
Definition: refs.h:34
static void attr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:949
struct m0_fid pv_id
Definition: pool.h:113
struct cob_req * icr_cr
Definition: cob.c:45
if(value==NULL)
Definition: dir.c:350
bool * cr_ios_replied
Definition: cob.c:79
uint32_t cr_icr_nr
Definition: cob.c:74
struct m0_fop_type m0_fop_cob_setattr_fopt
Definition: io_fops.c:83
struct m0_ast_rc icr_ar
Definition: cob.c:46
M0_INTERNAL struct m0_client * m0__oo_instance(struct m0_op_obj *oo)
Definition: obj.c:43
uint64_t cr_id
Definition: cob.c:81
m0_bcount_t b_nob
Definition: buf.h:38
#define M0_ASSERT(cond)
static int cob_ios_fop_populate(struct cob_req *cr, struct m0_fop *fop, struct m0_fid *cob_fid, uint32_t cob_idx)
Definition: cob.c:957
struct m0_fop * cr_rep_fop
Definition: cob.c:78
uint32_t cr_cob_type
Definition: cob.c:72
struct m0_fop * cr_mds_fop
Definition: cob.c:76
static void icrs_fail(struct cob_req *cr, int rc)
Definition: cob.c:748
struct m0_fop_type m0_fop_unlink_fopt
Definition: md_fops.c:55
struct m0_fid pver
Definition: idx_dix.c:74
static void cob_ios_fop_release(struct m0_ref *ref)
Definition: cob.c:1017
struct m0_rpc_machine * m0_fop_session_machine(const struct m0_rpc_session *s)
Definition: fop.c:453
uint32_t c_cob_idx
Definition: io_fops.h:471
M0_INTERNAL void m0_rpc_session_cancel(struct m0_rpc_session *session)
Definition: session.c:850
struct m0_client_layout * ol_layout
Definition: layout.h:181
struct m0_reqh m0c_reqh
M0_INTERNAL struct m0_rpc_session * m0_reqh_mdpool_service_index_to_session(const struct m0_reqh *reqh, const struct m0_fid *gob_fid, uint32_t index)
Definition: reqh.c:177
#define bob_of(ptr, type, field, bt)
Definition: bob.h:140
static int cob_ios_fop_get(struct cob_req *cr, uint32_t i, uint32_t cob_type, struct m0_rpc_session *session)
Definition: cob.c:1044
static struct ios_cob_req * rpc_item_to_icr(struct m0_rpc_item *item)
Definition: cob.c:697
static void cob_fail_cr(struct cob_req *cr, int rc)
Definition: cob.c:642
bool mc_is_oostore
Definition: client.h:920
uint32_t icr_index
Definition: cob.c:47
struct m0_op_common ol_oc
Definition: layout.h:175
static int cob_make_name(struct cob_req *cr)
Definition: cob.c:383
static struct m0_fid cob_fid
Definition: net.c:116
enum m0_conf_service_type sc_type
Definition: reqh_service.h:757
uint64_t b_lid
Definition: md_fops.h:90
static void cob_ios_rio_replied(struct m0_rpc_item *item)
Definition: cob.c:873
uint64_t u_hi
Definition: types.h:36
struct m0_fid c_gobfid
Definition: io_fops.h:460
struct m0_rpc_item * ri_reply
Definition: item.h:163
void * m0_alloc(size_t size)
Definition: memory.c:126
static int cob_ios_md_send(struct cob_req *cr)
Definition: cob.c:1406
M0_INTERNAL uint32_t m0_fid_cob_device_id(const struct m0_fid *cob_fid)
Definition: fid_convert.c:81
int m0_rpc_post_sync(struct m0_fop *fop, struct m0_rpc_session *session, const struct m0_rpc_item_ops *ri_ops, m0_time_t deadline)
Definition: rpclib.c:284
static int cob_mds_send(struct cob_req *cr)
Definition: cob.c:1721
void * f_opaque
Definition: fop.h:84
struct m0_fid b_pver
Definition: md_fops.h:93
uint64_t ri_nr_sent_max
Definition: item.h:146
#define M0_POST(cond)
struct m0_fid oo_fid
Definition: xcode.c:55
static const struct m0_bob_type icr_bobtype
Definition: cob.c:100
static void cob_mds_rio_replied(struct m0_rpc_item *item)
Definition: cob.c:1472
M0_INTERNAL int m0_fop_data_alloc(struct m0_fop *fop)
Definition: fop.c:71
M0_INTERNAL void m0_fop_fini(struct m0_fop *fop)
Definition: fop.c:136
struct m0_op_common oo_oc
struct m0_fid cr_pver
Definition: dir.c:64
bool m0_conf_fid_is_valid(const struct m0_fid *fid)
Definition: obj.c:378
static struct fdmi_ctx ctx
Definition: main.c:80
#define FID_P(f)
Definition: fid.h:77
M0_INTERNAL int m0_op_executed(struct m0_op *op)
Definition: client.c:500
static void cob_ast_complete_cr(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: cob.c:618
struct m0_fid ca_pver
Definition: cob.h:366
static void cob_req_release(struct cob_req *cr)
Definition: cob.c:246
#define MOTR_MDCOB_LOOKUP_SKIP
static void cob_attr_init(struct cob_req *cr, struct m0_cob_attr *attr, int *valid)
Definition: cob.c:216
void(* rio_replied)(struct m0_rpc_item *item)
Definition: item.h:300
static struct m0_client cinst
Definition: sync.c:84
M0_INTERNAL int m0__obj_namei_cancel(struct m0_op *op)
Definition: cob.c:1915
M0_INTERNAL int m0_rpc_session_validate(struct m0_rpc_session *session)
Definition: session.c:573
struct m0_sm_ast ar_ast
const struct m0_bob_type ol_bobtype
Definition: layout.c:37
struct m0_fop_cob g_body
Definition: md_fops.h:204
int32_t m0_rpc_item_error(const struct m0_rpc_item *item)
Definition: item.c:973
#define PRIu32
Definition: types.h:66
M0_INTERNAL void m0__obj_attr_set(struct m0_obj *obj, struct m0_fid pver, uint64_t lid)
Definition: obj.c:151
struct m0_pdclust_tgt_addr tgt
Definition: fd.c:110
M0_INTERNAL int64_t m0_ref_read(const struct m0_ref *ref)
Definition: refs.c:44
int(* olo_copy_to_app)(struct m0_client_layout *to, void *data)
Definition: layout.h:169
struct m0_sm_group en_sm_group
Definition: client.h:734
struct m0_sm_group op_sm_group
Definition: client.h:654
static void cob_req_ref_release(struct m0_ref *ref)
Definition: cob.c:275
#define M0_FI_ENABLED(tag)
Definition: finject.h:231
Definition: fid.h:38
uint64_t f_key
Definition: fid.h:40
struct m0_fop_type m0_fop_setattr_fopt
Definition: md_fops.c:58
uint64_t b_version
Definition: md_fops.h:74
M0_INTERNAL int m0_op_failed(struct m0_op *op)
Definition: client.c:548
M0_INTERNAL void cob_req_ref_put(struct cob_req *cr)
Definition: cob.c:292
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
struct m0_entity * op_entity
Definition: client.h:660
const struct m0_rpc_item_ops * ri_ops
Definition: item.h:149
uint32_t pa_P
Definition: pdclust.h:115
struct m0_rpc_session * ri_session
Definition: item.h:147
struct m0_fop_type m0_fop_cob_create_fopt
Definition: io_fops.c:75
struct m0_buf cr_name
Definition: cob.c:71
struct m0_entity ob_entity
Definition: client.h:789
struct m0_fop * m0_fop_alloc_at(struct m0_rpc_session *sess, struct m0_fop_type *fopt)
Definition: fop.c:122
const struct m0_op_layout_ops * ol_ops
Definition: layout.h:185
M0_INTERNAL void m0_sm_move(struct m0_sm *mach, int32_t rc, int state)
Definition: sm.c:485
void m0_fop_put_lock(struct m0_fop *fop)
Definition: fop.c:199
static struct m0_fop * fop
Definition: item.c:57
M0_INTERNAL void m0_sm_group_lock(struct m0_sm_group *grp)
Definition: sm.c:83
struct m0_fop * m0_rpc_item_to_fop(const struct m0_rpc_item *item)
Definition: fop.c:346
M0_INTERNAL struct m0_client * m0__obj_instance(const struct m0_obj *obj)
Definition: client.c:261
struct m0_fid c_pver
Definition: io_fops.h:468
int(* olo_copy_from_app)(struct m0_client_layout *from, void *data)
Definition: layout.h:171
struct m0_fid b_pfid
Definition: md_fops.h:91
Definition: nucleus.c:42
static int cob_ios_send(struct cob_req *cr, uint32_t idx)
Definition: cob.c:1236
#define OP_OBJ2CODE(op_obj)
static void cob_fail_op(struct m0_op *op, int rc)
Definition: cob.c:489
M0_INTERNAL void m0_fid_convert_gob2cob(const struct m0_fid *gob_fid, struct m0_fid *cob_fid, uint32_t device_id)
Definition: fid_convert.c:55
uint64_t cr_magic
Definition: cob.c:61
#define out(...)
Definition: gen.c:41
struct m0_sm en_sm
Definition: client.h:732
M0_INTERNAL bool m0_fid_is_valid(const struct m0_fid *fid)
Definition: fid.c:96
uint64_t u_lo
Definition: types.h:37
struct m0_rpc_link sc_rlink
Definition: reqh_service.h:759
struct m0_rpc_machine * ri_rmachine
Definition: item.h:160
static void icrs_complete(struct cob_req *cr)
Definition: cob.c:712
M0_INTERNAL uint64_t m0_sm_id_get(const struct m0_sm *sm)
Definition: sm.c:1021
void sync_record_update(struct m0_reqh_service_ctx *service, struct m0_entity *ent, struct m0_op *op, struct m0_be_tx_remid *btr)
Definition: sync.c:788
void m0_free(void *data)
Definition: memory.c:146
struct m0_rpc_item f_item
Definition: fop.h:83
struct m0_fop_cob c_body
Definition: io_fops.h:456
uint32_t sm_state
Definition: sm.h:307
struct m0_pdclust_attr pv_attr
Definition: pool.h:122
cob_request_flags
Definition: cob.c:51
static int cob_ios_prepare(struct cob_req *cr, uint32_t idx)
Definition: cob.c:1135
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL struct m0_rpc_session * m0_obj_container_id_to_session(struct m0_pool_version *pver, uint64_t container_id)
Definition: cob.c:925
#define offsetof(typ, memb)
Definition: misc.h:29
struct m0_fop_mod_rep c_mod_rep
Definition: md_fops.h:111
M0_INTERNAL bool m0_sm_group_is_locked(const struct m0_sm_group *grp)
Definition: sm.c:107
M0_INTERNAL void m0_poolmach_gob2cob(struct m0_poolmach *pm, const struct m0_fid *gfid, uint32_t idx, struct m0_fid *cob_fid)
M0_INTERNAL unsigned int m0_full_name_hash(const unsigned char *name, unsigned int len)
Definition: misc.c:266
struct m0_be_tx_remid fmr_remid
Definition: fom_generic.h:243
M0_INTERNAL int m0__obj_namei_send(struct m0_op_obj *oo)
Definition: cob.c:1804
Definition: fop.h:79
static struct m0_sm_group * grp
Definition: cob.c:39
#define FID_F
Definition: fid.h:75
struct m0_fop * rep_fop
Definition: dir.c:334
struct m0_fop_cob c_body
Definition: md_fops.h:110
m0_time_t ri_deadline
Definition: item.h:141
struct m0_fop_type m0_fop_cob_delete_fopt
Definition: io_fops.c:76
struct m0_config * m0c_config
#define M0_IMPOSSIBLE(fmt,...)
M0_INTERNAL struct m0_reqh_service_ctx * m0_reqh_service_ctx_from_session(struct m0_rpc_session *session)
M0_INTERNAL struct m0_client * m0__entity_instance(const struct m0_entity *entity)
Definition: client.c:226
M0_BOB_DEFINE(M0_INTERNAL, &cr_bobtype, cob_req)