Motr  M0
rm_foms.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #undef M0_TRACE_SUBSYSTEM
24 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_RM
25 #include "lib/errno.h"
26 #include "lib/list.h"
27 #include "lib/memory.h"
28 #include "lib/misc.h" /* M0_IN */
29 #include "lib/trace.h"
30 #include "lib/finject.h"
31 #include "fop/fom_generic.h"
32 #include "rpc/service.h"
33 #include "rpc/rpc.h"
34 #include "reqh/reqh.h"
35 #include "conf/confc.h" /* m0_confc */
36 
37 #include "rm/rm_fops.h"
38 #include "rm/rm_foms.h"
39 #include "rm/rm_service.h"
40 
52 static int borrow_fom_create(struct m0_fop *fop, struct m0_fom **out,
53  struct m0_reqh *reqh);
54 static void borrow_fom_fini(struct m0_fom *fom);
55 static int revoke_fom_create(struct m0_fop *fop, struct m0_fom **out,
56  struct m0_reqh *reqh);
57 static void revoke_fom_fini(struct m0_fom *fom);
58 static int cancel_fom_create(struct m0_fop *fop, struct m0_fom **out,
59  struct m0_reqh *reqh);
60 static void cancel_fom_fini(struct m0_fom *fom);
61 static int borrow_fom_tick(struct m0_fom *);
62 static int revoke_fom_tick(struct m0_fom *);
63 static int cancel_process(struct m0_fom *fom);
64 static int cancel_fom_tick(struct m0_fom *);
65 static size_t locality(const struct m0_fom *fom);
66 
67 static void remote_incoming_complete(struct m0_rm_incoming *in, int32_t rc);
68 static void remote_incoming_conflict(struct m0_rm_incoming *in);
69 
74 };
75 
76 /*
77  * As part of of incoming_complete(), call remote_incoming complete.
78  * This will call request specific functions.
79  */
82  .rio_conflict = remote_incoming_conflict,
83 };
84 
85 /*
86  * Borrow FOM ops.
87  */
88 static struct m0_fom_ops rm_fom_borrow_ops = {
90  .fo_tick = borrow_fom_tick,
91  .fo_home_locality = locality,
92 };
93 
96 };
97 
98 /*
99  * Revoke FOM ops.
100  */
101 static struct m0_fom_ops rm_fom_revoke_ops = {
103  .fo_tick = revoke_fom_tick,
104  .fo_home_locality = locality,
105 };
106 
109 };
110 
111 /*
112  * Cancel FOM ops.
113  */
114 static struct m0_fom_ops rm_fom_cancel_ops = {
116  .fo_tick = cancel_fom_tick,
117  .fo_home_locality = locality,
118 };
119 
122 };
123 
125  [FOPH_RM_REQ_START] = {
127  .sd_name = "RM_Request_Begin",
128  .sd_allowed = M0_BITS(FOPH_RM_REQ_CREDIT_GET,
131  },
133  .sd_name = "RM_Credit_Get",
134  .sd_allowed = M0_BITS(FOPH_RM_REQ_WAIT)
135  },
136  [FOPH_RM_REQ_WAIT] = {
137  .sd_name = "RM_Request_Wait",
138  .sd_allowed = M0_BITS(FOPH_RM_REQ_FINISH)
139  },
140  [FOPH_RM_REQ_FINISH] = {
141  .sd_flags = M0_SDF_FINAL,
142  .sd_name = "RM_Request_Completion",
143  .sd_allowed = 0
144  },
146  .sd_name = "Debtor_Subscribe",
147  .sd_allowed = M0_BITS(FOPH_RM_REQ_CREDIT_GET)
148  },
149 };
150 
151 const struct m0_sm_conf borrow_sm_conf = {
152  .scf_name = "Borrow fom",
153  .scf_nr_states = ARRAY_SIZE(rm_req_phases),
154  .scf_state = rm_req_phases
155 };
156 
157 const struct m0_sm_conf canoke_sm_conf = {
158  .scf_name = "Canoke fom",
159  .scf_nr_states = ARRAY_SIZE(rm_req_phases),
160  .scf_state = rm_req_phases
161 };
162 
163 static void remote_incoming_complete(struct m0_rm_incoming *in, int32_t rc)
164 {
165  struct m0_rm_remote_incoming *rem_in;
166  struct rm_request_fom *rqfom;
167 
168  rem_in = container_of(in, struct m0_rm_remote_incoming, ri_incoming);
169  rqfom = container_of(rem_in, struct rm_request_fom, rf_in);
170  M0_ASSERT(M0_IN(m0_fom_phase(&rqfom->rf_fom),
172 
173  switch (in->rin_type) {
174  case FRT_BORROW:
175  rc = rc ?: m0_rm_borrow_commit(rem_in);
176  break;
177  case FRT_REVOKE:
178  rc = rc ?: m0_rm_revoke_commit(rem_in);
179  break;
180  default:
181  M0_IMPOSSIBLE("Unrecognized RM request");
182  break;
183  }
184 
185  /*
186  * Override the rc.
187  */
188  in->rin_rc = rc;
189  /*
190  * FOM may still executes, but for sure will be
191  * in the waiting state when wakeup AST is called.
192  */
193  m0_fom_wakeup(&rqfom->rf_fom);
194 }
195 
197 {
198  /* Do nothing */
199 }
200 
201 /*
202  * Generic RM request-FOM constructor.
203  */
205  struct m0_fop *fop, struct m0_fom **out,
206  struct m0_reqh *reqh)
207 {
208  struct rm_request_fom *rqfom;
209  struct m0_fop_type *fopt = NULL;
210  struct m0_fom_ops *fom_ops = NULL;
211  struct m0_fop *reply_fop;
212 
213  M0_ENTRY("creating FOM for request: %d", type);
214 
215  M0_PRE(fop != NULL);
216  M0_PRE(fop->f_type != NULL);
217  M0_PRE(out != NULL);
218 
219  M0_ALLOC_PTR(rqfom);
220  if (M0_FI_ENABLED("fom_alloc_failure"))
221  m0_free0(&rqfom);
222  if (rqfom == NULL)
223  return M0_ERR(-ENOMEM);
224 
225  switch (type) {
226  case FRT_BORROW:
228  fom_ops = &rm_fom_borrow_ops;
229  break;
230  case FRT_REVOKE:
232  fom_ops = &rm_fom_revoke_ops;
233  break;
234  case FRT_CANCEL:
236  fom_ops = &rm_fom_cancel_ops;
237  break;
238  default:
239  M0_IMPOSSIBLE("Unrecognised RM request");
240  break;
241  }
242 
244  if (reply_fop == NULL) {
245  m0_free(rqfom);
246  return M0_ERR(-ENOMEM);
247  }
248 
250  fom_ops, fop, reply_fop, reqh);
251  *out = &rqfom->rf_fom;
252  return M0_RC(0);
253 }
254 
255 /*
256  * Generic RM request-FOM destructor.
257  */
258 static void request_fom_fini(struct m0_fom *fom)
259 {
260  struct rm_request_fom *rfom;
261 
262  M0_PRE(fom != NULL);
263 
264  rfom = container_of(fom, struct rm_request_fom, rf_fom);
265  m0_fom_fini(fom);
266  m0_free(rfom);
267 }
268 
269 static size_t locality(const struct m0_fom *fom)
270 {
271  struct rm_request_fom *rfom;
272 
273  rfom = container_of(fom, struct rm_request_fom, rf_fom);
274  return (size_t)(rfom->rf_in.ri_owner_cookie.co_generation >> 32);
275 }
276 
277 /*
278  * This function will fill reply FOP data.
279  * However, it will not set the return code.
280  *
281  * @see reply_err_set()
282  */
283 static int reply_prepare(const enum m0_rm_incoming_type type,
284  struct m0_fom *fom)
285 {
286  struct m0_rm_fop_borrow_rep *breply_fop;
287  struct m0_rm_fop_revoke_rep *rreply_fop;
288  struct rm_request_fom *rfom;
289  struct m0_rm_loan *loan;
290  int rc = 0;
291 
292  M0_ENTRY("reply for fom: %p", fom);
293  rfom = container_of(fom, struct rm_request_fom, rf_fom);
294 
295  switch (type) {
296  case FRT_BORROW:
297  breply_fop = m0_fop_data(fom->fo_rep_fop);
298  breply_fop->br_loan.lo_cookie = rfom->rf_in.ri_loan_cookie;
299 
300  /*
301  * Get the loan pointer from the cookie to process the reply.
302  * It's safe to access loan as this get called when
303  * m0_credit_get() succeeds. Hence the loan cookie is valid.
304  */
305  loan = m0_cookie_of(&rfom->rf_in.ri_loan_cookie,
306  struct m0_rm_loan, rl_id);
307 
308  M0_ASSERT(loan != NULL);
309  m0_cookie_init(&breply_fop->br_creditor_cookie,
310  &loan->rl_credit.cr_owner->ro_id);
311  /*
312  * Memory for the buffer is allocated by the function.
313  */
315  &breply_fop->br_credit.cr_opaque);
316  break;
317  case FRT_REVOKE:
318  rreply_fop = m0_fop_data(fom->fo_rep_fop);
319  rreply_fop->rr_debtor_cookie = rfom->rf_in.ri_rem_owner_cookie;
320  break;
321  default:
322  break;
323  }
324  return M0_RC(rc);
325 }
326 
327 /*
328  * Set RM reply FOP error code.
329  */
331  struct m0_fom *fom, int rc)
332 {
333  struct m0_rm_fop_borrow_rep *bfop;
334  struct m0_rm_fop_revoke_rep *rfop;
335 
336  M0_ENTRY("reply for fom: %p type: %d error: %d", fom, type, rc);
337 
338  switch (type) {
339  case FRT_BORROW:
340  bfop = m0_fop_data(fom->fo_rep_fop);
341  bfop->br_rc = rc;
342  break;
343  case FRT_REVOKE:
344  rfop = m0_fop_data(fom->fo_rep_fop);
345  rfop->rr_rc = rc;
346  break;
347  case FRT_CANCEL:
348  break;
349  default:
350  M0_IMPOSSIBLE("Unrecognized RM request");
351  }
352  M0_LEAVE();
353 }
354 
355 M0_INTERNAL int m0_rm_reverse_session_get(struct m0_rm_remote_incoming *rem_in,
356  struct m0_rm_remote *remote)
357 {
358  int rc = 0;
359  struct rm_request_fom *rfom;
360  struct m0_fom *fom;
361  struct m0_reqh_service *service;
362  struct m0_rpc_item *item;
363 
364  M0_PRE(_0C(rem_in != NULL) && _0C(remote != NULL));
365  M0_ENTRY("remote incoming %p remote %p", rem_in, remote);
366  rfom = container_of(rem_in, struct rm_request_fom, rf_in);
367  fom = &rfom->rf_fom;
368  item = &fom->fo_fop->f_item;
369  if (item->ri_session != NULL) {
370  service = m0_reqh_rpc_service_find(fom->fo_service->rs_reqh);
371  M0_ASSERT(service != NULL);
374  M0_LOG(M0_DEBUG, "rem_session=%p", remote->rem_session);
375  if (remote->rem_session == NULL) {
379  &remote->rem_session);
380  }
381  }
382  return M0_RC(rc);
383 }
384 
385 /*
386  * Build an remote-incoming structure using remote request information.
387  */
389 {
390  struct m0_rm_fop_borrow *bfop;
391  struct m0_rm_fop_revoke *rfop;
392  struct m0_rm_fop_req *basefop = NULL;
393  struct m0_rm_incoming *in;
394  struct m0_rm_owner *owner;
395  struct rm_request_fom *rfom;
396  struct m0_buf *buf;
397  enum m0_rm_incoming_policy policy;
398  uint64_t flags;
399  int rc = 0;
400 
401  M0_ENTRY("prepare remote incoming request for fom: %p request: %d",
402  fom, type);
403 
404  rfom = container_of(fom, struct rm_request_fom, rf_fom);
405  switch (type) {
406  case FRT_BORROW:
407  bfop = m0_fop_data(fom->fo_fop);
408  basefop = &bfop->bo_base;
409  /* Remote owner (requester) cookie */
410  rfom->rf_in.ri_rem_owner_cookie = basefop->rrq_owner.ow_cookie;
411  /*
412  * Populate the owner cookie for creditor (local)
413  * This is used later by locality().
414  */
415  /* Possibly M0_COOKIE_NULL */
417  rfom->rf_in.ri_group_id = bfop->bo_group_id;
418  break;
419 
420  case FRT_REVOKE:
421  rfop = m0_fop_data(fom->fo_fop);
422  basefop = &rfop->fr_base;
423  /*
424  * Populate the owner cookie for debtor (local)
425  * This server is debtor; hence it received REVOKE request.
426  * This is used later by locality().
427  */
428  rfom->rf_in.ri_owner_cookie = basefop->rrq_owner.ow_cookie;
429  /*
430  * Populate the loan cookie.
431  */
432  rfom->rf_in.ri_loan_cookie = rfop->fr_loan.lo_cookie;
433  break;
434 
435  default:
436  M0_IMPOSSIBLE("Unrecognized RM request");
437  break;
438  }
439  policy = basefop->rrq_policy;
440  flags = basefop->rrq_flags;
441  buf = &basefop->rrq_credit.cr_opaque;
442  in = &rfom->rf_in.ri_incoming;
443  owner = m0_cookie_of(&rfom->rf_in.ri_owner_cookie,
444  struct m0_rm_owner, ro_id);
445  /*
446  * Owner is NULL, create owner for given resource.
447  * Resource description is provided in basefop->rrq_owner.ow_resource
448  */
449  if (owner == NULL) {
450  /* Owner cannot be NULL for a revoke request */
452  rc = m0_rm_svc_owner_create(fom->fo_service, &owner,
453  &basefop->rrq_owner.ow_resource);
454  if (rc != 0) {
455  m0_free(owner);
456  return M0_RC(rc);
457  }
458  }
459  /*
460  * Owner may be on its way of finalising, so no further credit operation
461  * makes sense with the owner, thus incoming request to be just rejected
462  *
463  * When not rejected, m0_rm_incoming finalisation is going to suffer
464  * from possible race in destruction of state machine lock object done
465  * in concurrent thread.
466  */
467  if (owner_state(owner) > ROS_ACTIVE) {
468  M0_LOG(M0_DEBUG, "Owner bad state: %d", owner_state(owner));
469  return M0_ERR(-ESTALE);
470  }
471  m0_rm_incoming_init(in, owner, type, policy, flags);
473  in->rin_reserve.rrp_time = basefop->rrq_orig_time;
474  in->rin_reserve.rrp_owner = basefop->rrq_orig_owner;
475  in->rin_reserve.rrp_seq = basefop->rrq_orig_seq;
477  if (rc != 0)
480 
481  return M0_RC(rc);
482 }
483 
484 static int remote_create(struct m0_rm_remote **rem,
485  struct m0_rm_remote_incoming *rem_in)
486 {
487  struct m0_cookie *cookie = &rem_in->ri_rem_owner_cookie;
489  struct m0_rm_remote *other;
490  int rc;
491 
492  M0_ALLOC_PTR(other);
493  if (other != NULL) {
494  m0_rm_remote_init(other, res);
495  rc = m0_rm_reverse_session_get(rem_in, other);
496  if (rc != 0) {
497  m0_free(other);
498  return M0_ERR(rc);
499  }
501  other->rem_cookie = *cookie;
502  /* @todo - Figure this out */
503  /* other->rem_id = 0; */
504  m0_remotes_tlist_add(&res->r_remotes, other);
505  } else
506  rc = M0_ERR(-ENOMEM);
507  *rem = other;
508  return M0_RC(rc);
509 }
510 
517 static int rfom_debtor_subscribe(struct rm_request_fom *rfom,
518  struct m0_rm_remote *debtor)
519 {
520  struct m0_confc *confc;
521  struct m0_rpc_item *item;
522  const char *ep;
523  struct m0_fom *fom;
524  int rc;
525 
526  M0_PRE(rfom != NULL);
527  fom = &rfom->rf_fom;
528  item = &fom->fo_fop->f_item;
530  M0_ASSERT(ep != NULL);
531  /* Already subscribed? Then we are fine. */
533  return M0_RC(-EEXIST);
534  /* get confc instance HA to be notifying on */
536  rc = m0_rm_ha_subscriber_init(&rfom->rf_sbscr, &fom->fo_loc->fl_group,
537  confc, ep, &debtor->rem_tracker);
538  if (rc == 0) {
541  &fom->fo_cb);
543  }
544 
545  return M0_RC(rc);
546 }
547 
548 /*
549  * Prepare incoming request. Send request for the credits.
550  */
551 static int request_pre_process(struct m0_fom *fom,
553 {
554  struct rm_request_fom *rfom;
555  struct m0_rm_remote *debtor;
556  int rc;
557 
558  M0_ENTRY("pre-processing fom: %p request : %d", fom, type);
559 
560  M0_PRE(fom != NULL);
561  rfom = container_of(fom, struct rm_request_fom, rf_fom);
562 
564  if (rc != 0) {
565  /*
566  * This will happen if owner cookie is stale or
567  * copying of credit data fails.
568  */
569  goto err;
570  }
571 
572  if (type == M0_RIT_BORROW) {
573  debtor = m0_rm_remote_find(&rfom->rf_in);
574  if (debtor == NULL) {
575  rc = remote_create(&debtor, &rfom->rf_in);
576  if (rc != 0) {
578  goto err;
579  }
580  M0_RM_REMOTE_GET(debtor);
581  } else if (debtor->rem_dead) {
582  /*
583  * There is nobody to reply to, as request originator
584  * has been announced dead to the moment.
585  */
586  rc = M0_ERR(-ECANCELED);
588  goto err;
589  }
590  rfom->rf_in.ri_incoming.rin_remote = debtor;
591  /*
592  * Subscribe debtor to HA notifications. If subscription
593  * fails, proceed as usual to the next step.
594  */
595  if (!M0_FI_ENABLED("no-subscription")) {
596  rc = rfom_debtor_subscribe(rfom, debtor);
597  if (rc == 0)
598  return M0_RC(M0_FSO_WAIT);
599  }
600  }
601 
603  /*
604  * Don't try to analyse incoming_state(in), because access to 'in' is
605  * not synchronised here. Return always M0_FSO_WAIT, fom will wakeup
606  * from remote_incoming_complete().
607  */
608  return M0_RC(M0_FSO_AGAIN);
609 
610 err:
612  m0_rpc_reply_post(&fom->fo_fop->f_item,
613  m0_fop_to_rpc_item(fom->fo_rep_fop));
615  return M0_RC(M0_FSO_WAIT);
616 }
617 
618 static int request_post_process(struct m0_fom *fom)
619 {
620  struct rm_request_fom *rfom;
621  struct m0_rm_incoming *in;
622  int rc;
623 
624  M0_ENTRY("post-processing fom: %p", fom);
625  M0_PRE(fom != NULL);
626 
627  rfom = container_of(fom, struct rm_request_fom, rf_fom);
628  in = &rfom->rf_in.ri_incoming;
629 
630  rc = in->rin_rc;
631  M0_ASSERT(ergo(rc == 0, incoming_state(in) == RI_SUCCESS));
632  M0_ASSERT(ergo(rc != 0, incoming_state(in) == RI_FAILURE));
633  /*
634  * Owner is allowed to be in ROS_FINAL state, otherwise its resource
635  * must be set up
636  */
638  incoming_to_resource(in) != NULL);
639 
640  if (incoming_state(in) == RI_SUCCESS) {
641  rc = reply_prepare(in->rin_type, fom);
642  m0_rm_credit_put(in);
643  }
644 
645  reply_err_set(in->rin_type, fom, rc);
647 
648  if (M0_FI_ENABLED("no_rpc_reply_post"))
649  return M0_RC(M0_FSO_WAIT);
650 
651  m0_rpc_reply_post(&fom->fo_fop->f_item,
652  m0_fop_to_rpc_item(fom->fo_rep_fop));
653 
654  return M0_RC(M0_FSO_WAIT);
655 }
656 
657 static int request_fom_tick(struct m0_fom *fom,
659 {
660  struct rm_request_fom *rfom;
661  int rc = 0;
662 
663  M0_ENTRY("running fom: %p for request: %d", fom, type);
664 
665  switch (m0_fom_phase(fom)) {
666  case FOPH_RM_REQ_START:
667  if (type == (enum m0_rm_incoming_type)FRT_CANCEL)
668  rc = cancel_process(fom);
669  else
671  break;
673  rfom = container_of(fom, struct rm_request_fom, rf_fom);
676  rc = M0_FSO_WAIT;
677  break;
678  case FOPH_RM_REQ_WAIT:
681  break;
682  default:
683  M0_IMPOSSIBLE("Unrecognized RM FOM phase");
684  break;
685  }
686  return M0_RC(rc);
687 }
688 
690 {
691  struct rm_request_fom *rfom;
692  int rc;
693 
694  rfom = container_of(fom, struct rm_request_fom, rf_fom);
695  if (M0_IN(rfom->rf_sbscr.rhs_sm.sm_state,
697  if (rfom->rf_sbscr.rhs_sm.sm_rc != 0) {
698  struct m0_rm_remote *rem;
699  rem = m0_rm_remote_find(&rfom->rf_in);
700  M0_ASSERT(rem != NULL);
701  M0_LOG(M0_DEBUG, "Can't subscribe to debtor with ep %s:"
702  " rc=%d", rem->rem_tracker.rht_ep,
703  rfom->rf_sbscr.rhs_sm.sm_rc);
704  M0_RM_REMOTE_PUT(rem);
705  }
707  /* Ignore subscriber return code, procced to getting credit */
709  rc = M0_FSO_AGAIN;
710  }
711  else {
713  &fom->fo_cb);
714  rc = M0_FSO_WAIT;
715  }
716  return M0_RC(rc);
717 }
718 
730 static int borrow_fom_tick(struct m0_fom *fom)
731 {
732  int rc;
733 
734  M0_ENTRY("running fom: %p for request: %d", fom, FRT_BORROW);
735  switch (m0_fom_phase(fom)) {
738  break;
739  default:
741  }
742  return M0_RC(rc);
743 }
744 
754 static int revoke_fom_tick(struct m0_fom *fom)
755 {
757 }
758 
759 static int cancel_process(struct m0_fom *fom)
760 {
761  struct m0_rm_fop_cancel *cfop;
762  struct m0_rm_loan *loan;
763  struct m0_rm_owner *owner;
764  int rc = 0;
765 
766  cfop = m0_fop_data(fom->fo_fop);
767 
768  owner = m0_cookie_of(&cfop->fc_creditor_cookie,
769  struct m0_rm_owner, ro_id);
770  /* Creditors are alive as long as RM service is running */
771  M0_ASSERT(owner != NULL);
772  /* Lock owner to exclude races with processing HA notification */
773  m0_rm_owner_lock(owner);
774  loan = m0_cookie_of(&cfop->fc_loan.lo_cookie,
775  struct m0_rm_loan, rl_id);
776  /*
777  * Loan can be absent if debtor is considered dead and this loan has
778  * already been revoked.
779  */
780  if (loan != NULL) {
781  M0_ASSERT(loan->rl_other != NULL);
782  M0_ASSERT(!loan->rl_other->rem_dead);
783  M0_LOG(M0_DEBUG, "loan=%p rl_other=%p", loan, loan->rl_other);
784  rc = m0_rm_loan_settle(owner, loan);
785  } else {
786  M0_LOG(M0_WARN, "loan %p is not found!",
787  (void *)cfop->fc_loan.lo_cookie.co_addr);
788  rc = -ENOENT;
789  }
791  m0_rpc_reply_post(&fom->fo_fop->f_item,
792  m0_fop_to_rpc_item(fom->fo_rep_fop));
793  m0_rm_owner_unlock(owner);
794 
796  return M0_RC(M0_FSO_WAIT);
797 }
798 
799 static int cancel_fom_tick(struct m0_fom *fom)
800 {
802 }
803 
804 /*
805  * A borrow FOM constructor.
806  */
807 static int borrow_fom_create(struct m0_fop *fop, struct m0_fom **out,
808  struct m0_reqh *reqh)
809 {
811 }
812 
813 /*
814  * A borrow FOM destructor.
815  */
816 static void borrow_fom_fini(struct m0_fom *fom)
817 {
819 }
820 
821 /*
822  * A revoke FOM constructor.
823  */
824 static int revoke_fom_create(struct m0_fop *fop, struct m0_fom **out,
825  struct m0_reqh *reqh)
826 {
828 }
829 
830 /*
831  * A revoke FOM destructor.
832  */
833 static void revoke_fom_fini(struct m0_fom *fom)
834 {
836 }
837 
838 /*
839  * A cancel FOM constructor.
840  */
841 static int cancel_fom_create(struct m0_fop *fop, struct m0_fom **out,
842  struct m0_reqh *reqh)
843 {
845 }
846 
847 /*
848  * A cancel FOM destructor.
849  */
850 static void cancel_fom_fini(struct m0_fom *fom)
851 {
853 }
854 
struct m0_rm_ha_subscriber rf_sbscr
Definition: rm_foms.h:64
struct m0_rm_fop_credit br_credit
Definition: rm_fops.h:112
static struct m0_fom_ops rm_fom_borrow_ops
Definition: rm_foms.c:88
M0_INTERNAL void m0_fom_wakeup(struct m0_fom *fom)
Definition: fom.c:532
struct m0_rm_fop_loan fc_loan
Definition: rm_fops.h:140
#define M0_PRE(cond)
static struct m0_fom_ops rm_fom_revoke_ops
Definition: rm_foms.c:101
uint64_t rrq_orig_seq
Definition: rm_fops.h:100
struct m0_uint128 bo_group_id
Definition: rm_fops.h:106
enum m0_rm_remote_state rem_state
Definition: rm.h:748
m0_time_t rrq_orig_time
Definition: rm_fops.h:99
struct m0_rm_fop_owner rrq_owner
Definition: rm_fops.h:91
int const char const void size_t int flags
Definition: dir.c:328
M0_INTERNAL int m0_rm_ha_subscriber_init(struct m0_rm_ha_subscriber *sbscr, struct m0_sm_group *grp, struct m0_confc *confc, const char *rem_ep, struct m0_rm_ha_tracker *tracker)
Definition: rm_ha.c:340
#define NULL
Definition: misc.h:38
struct m0_cookie ri_rem_owner_cookie
Definition: rm_internal.h:59
enum m0_rm_incoming_type rin_type
Definition: rm.h:1435
struct m0_rm_fop_req fr_base
Definition: rm_fops.h:124
struct m0_clink rem_rev_sess_clink
Definition: rm.h:754
static int revoke_fom_tick(struct m0_fom *)
Definition: rm_foms.c:754
static size_t locality(const struct m0_fom *fom)
Definition: rm_foms.c:269
#define ergo(a, b)
Definition: misc.h:293
static int debtor_subscription_check(struct m0_fom *fom)
Definition: rm_foms.c:689
void(* rio_complete)(struct m0_rm_incoming *in, int32_t rc)
Definition: rm.h:1493
Definition: sm.h:350
M0_INTERNAL int m0_rm_credit_decode(struct m0_rm_credit *credit, struct m0_buf *buf)
Definition: rm.c:3376
struct m0_fid rrp_owner
Definition: rm.h:1255
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
struct m0_cookie ri_loan_cookie
Definition: rm_internal.h:60
static void remote_incoming_conflict(struct m0_rm_incoming *in)
Definition: rm_foms.c:196
int(* fto_create)(struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: fom.h:650
struct m0_sm rhs_sm
Definition: rm_ha.h:132
static int revoke_fom_create(struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: rm_foms.c:824
struct m0_rm_ha_tracker rem_tracker
Definition: rm.h:784
void * m0_fop_data(const struct m0_fop *fop)
Definition: fop.c:220
uint64_t rrq_flags
Definition: rm_fops.h:94
struct m0_fop_type m0_rm_fop_borrow_rep_fopt
Definition: rm_fops.c:68
struct m0_rm_fop_credit rrq_credit
Definition: rm_fops.h:92
static int remote_create(struct m0_rm_remote **rem, struct m0_rm_remote_incoming *rem_in)
Definition: rm_foms.c:484
const struct m0_fom_type_ops rm_cancel_fom_type_ops
Definition: rm_foms.c:120
static int borrow_fom_create(struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: rm_foms.c:807
m0_time_t rrp_time
Definition: rm.h:1251
M0_INTERNAL bool m0_clink_is_armed(const struct m0_clink *link)
Definition: chan.c:303
M0_INTERNAL void m0_fom_wait_on(struct m0_fom *fom, struct m0_chan *chan, struct m0_fom_callback *cb)
Definition: fom.c:1490
#define M0_BITS(...)
Definition: misc.h:236
M0_INTERNAL void m0_rm_remote_init(struct m0_rm_remote *rem, struct m0_rm_resource *res)
Definition: rm.c:1411
uint64_t ro_id
Definition: rm.h:1066
M0_INTERNAL int m0_rm_reverse_session_get(struct m0_rm_remote_incoming *rem_in, struct m0_rm_remote *remote)
Definition: rm_foms.c:355
void m0_remotes_tlist_add(struct m0_tl *tl, struct m0_rm_remote *rem)
const struct m0_fom_type_ops rm_borrow_fom_type_ops
Definition: rm_foms.c:94
static int void * buf
Definition: dir.c:1019
#define container_of(ptr, type, member)
Definition: misc.h:33
struct m0_rm_credit rin_want
Definition: rm.h:1450
struct m0_rpc_session * rem_session
Definition: rm.h:755
static int cancel_fom_tick(struct m0_fom *)
Definition: rm_foms.c:799
static struct m0_rpc_item * item
Definition: item.c:56
struct m0_cookie ri_owner_cookie
Definition: rm_internal.h:55
m0_fom_phase
Definition: fom.h:372
M0_INTERNAL int m0_rm_credit_encode(struct m0_rm_credit *credit, struct m0_buf *buf)
Definition: rm.c:3350
struct m0_rm_owner * cr_owner
Definition: rm.h:501
Definition: sock.c:887
struct m0_cookie br_creditor_cookie
Definition: rm_fops.h:120
static void cancel_fom_fini(struct m0_fom *fom)
Definition: rm_foms.c:850
struct m0_fom_type ft_fom_type
Definition: fop.h:232
M0_INTERNAL int m0_rm_svc_owner_create(struct m0_reqh_service *service, struct m0_rm_owner **out, struct m0_buf *resbuf)
Definition: rm_service.c:224
static int cancel_process(struct m0_fom *fom)
Definition: rm_foms.c:759
return M0_RC(rc)
struct m0_cookie lo_cookie
Definition: rm_fops.h:82
uint64_t rrp_seq
Definition: rm.h:1265
Definition: sock.c:754
static struct m0_fom_ops rm_fom_cancel_ops
Definition: rm_foms.c:114
#define M0_ENTRY(...)
Definition: trace.h:170
struct m0_rm_fop_req bo_base
Definition: rm_fops.h:104
Definition: buf.h:37
void m0_fom_init(struct m0_fom *fom, const struct m0_fom_type *fom_type, const struct m0_fom_ops *ops, struct m0_fop *fop, struct m0_fop *reply, struct m0_reqh *reqh)
Definition: fom.c:1372
struct m0_rm_credit rl_credit
Definition: rm.h:1099
struct m0_fop_type * f_type
Definition: fop.h:81
M0_INTERNAL void m0_rm_ha_subscribe(struct m0_rm_ha_subscriber *sbscr)
Definition: rm_ha.c:355
struct m0_fom rf_fom
Definition: rm_foms.h:57
static int incoming_prepare(enum m0_rm_incoming_type type, struct m0_fom *fom)
Definition: rm_foms.c:388
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL int m0_rm_loan_settle(struct m0_rm_owner *owner, struct m0_rm_loan *loan)
Definition: rm.c:2818
static enum m0_rm_owner_state owner_state(const struct m0_rm_owner *owner)
Definition: rm_internal.h:297
M0_INTERNAL void m0_rm_incoming_init(struct m0_rm_incoming *in, struct m0_rm_owner *owner, enum m0_rm_incoming_type type, enum m0_rm_incoming_policy policy, uint64_t flags)
Definition: rm.c:1060
M0_INTERNAL struct m0_confc * m0_reqh2confc(struct m0_reqh *reqh)
Definition: reqh.c:753
M0_INTERNAL struct m0_reqh_service * m0_reqh_rpc_service_find(struct m0_reqh *reqh)
Definition: service.c:287
static void borrow_fom_fini(struct m0_fom *fom)
Definition: rm_foms.c:816
struct m0_fid rrq_orig_owner
Definition: rm_fops.h:98
void m0_fom_fini(struct m0_fom *fom)
Definition: fom.c:1324
#define m0_free0(pptr)
Definition: memory.h:77
static void request_fom_fini(struct m0_fom *fom)
Definition: rm_foms.c:258
#define M0_ASSERT(cond)
const char * scf_name
Definition: sm.h:352
static struct m0_confc * confc
Definition: file.c:94
Definition: rm.h:828
static enum m0_rm_incoming_state incoming_state(const struct m0_rm_incoming *in)
Definition: rm_internal.h:285
#define M0_RM_REMOTE_PUT(remote)
Definition: rm.h:1971
static int request_post_process(struct m0_fom *fom)
Definition: rm_foms.c:618
static struct m0_fop reply_fop
Definition: fsync.c:64
struct m0_buf cr_opaque
Definition: rm_fops.h:86
struct m0_sm_state_descr rm_req_phases[]
Definition: rm_foms.c:124
char * rht_ep
Definition: rm_ha.h:118
static int cancel_fom_create(struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: rm_foms.c:841
const struct m0_rm_incoming_ops * rin_ops
Definition: rm.h:1471
int32_t rin_rc
Definition: rm.h:1446
M0_INTERNAL struct m0_rpc_session * m0_rpc_service_reverse_session_lookup(struct m0_reqh_service *service, const struct m0_rpc_item *item)
Definition: service.c:141
Definition: reqh.h:94
struct m0_cookie ow_cookie
Definition: rm_fops.h:77
int32_t sm_rc
Definition: sm.h:336
Definition: dump.c:103
const struct m0_fom_type_ops rm_revoke_fom_type_ops
Definition: rm_foms.c:107
struct m0_rm_remote * rl_other
Definition: rm.h:1105
void m0_rpc_reply_post(struct m0_rpc_item *request, struct m0_rpc_item *reply)
Definition: rpc.c:135
static struct m0_rm_resource * incoming_to_resource(struct m0_rm_incoming *in)
Definition: rm_internal.h:291
struct m0_rm_remote * rin_remote
Definition: rm.h:1477
m0_rm_incoming_policy
Definition: rm.h:1155
const struct m0_sm_conf borrow_sm_conf
Definition: rm_foms.c:151
struct m0_fop_type m0_fop_generic_reply_fopt
Definition: fom_generic.c:50
M0_INTERNAL int m0_rm_revoke_commit(struct m0_rm_remote_incoming *rem_in)
Definition: rm.c:1615
struct m0_fop * m0_fop_reply_alloc(struct m0_fop *req, struct m0_fop_type *rept)
Definition: fop.c:129
struct m0_rm_fop_loan fr_loan
Definition: rm_fops.h:125
static int request_pre_process(struct m0_fom *fom, enum m0_rm_incoming_type type)
Definition: rm_foms.c:551
struct m0_rm_fop_owner bo_creditor
Definition: rm_fops.h:105
uint32_t sd_flags
Definition: sm.h:378
fop_request_type
Definition: rm_foms.c:70
Definition: fom.h:481
M0_INTERNAL void m0_rm_credit_put(struct m0_rm_incoming *in)
Definition: rm.c:1797
static int rfom_debtor_subscribe(struct rm_request_fom *rfom, struct m0_rm_remote *debtor)
Definition: rm_foms.c:517
static int request_fom_create(enum m0_rm_incoming_type type, struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: rm_foms.c:204
struct m0_reqh reqh
Definition: rm_foms.c:48
#define M0_RM_REMOTE_GET(remote)
Definition: rm.h:1957
struct m0_cookie rr_debtor_cookie
Definition: rm_fops.h:136
char * ep
Definition: sw.h:132
struct m0_rm_incoming ri_incoming
Definition: rm_internal.h:50
#define M0_FI_ENABLED(tag)
Definition: finject.h:231
struct m0_cookie fc_creditor_cookie
Definition: rm_fops.h:141
struct m0_rm_fop_loan br_loan
Definition: rm_fops.h:111
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
struct m0_chan sm_chan
Definition: sm.h:331
struct m0_buf ow_resource
Definition: rm_fops.h:78
M0_INTERNAL void m0_rm_ha_subscriber_fini(struct m0_rm_ha_subscriber *sbscr)
Definition: rm_ha.c:394
Definition: rm.h:863
M0_INTERNAL int m0_rpc_service_reverse_session_get(struct m0_reqh_service *service, const struct m0_rpc_item *item, struct m0_clink *clink, struct m0_rpc_session **session)
Definition: service.c:164
static struct m0_rm_remote * remote
Definition: rm_fops.c:35
struct m0_rpc_session * ri_session
Definition: item.h:147
struct m0_rpc_item * m0_fop_to_rpc_item(const struct m0_fop *fop)
Definition: fop.c:338
m0_rm_incoming_type
Definition: rm.h:247
#define _0C(exp)
Definition: assert.h:311
static struct m0_fop * fop
Definition: item.c:57
static void remote_incoming_complete(struct m0_rm_incoming *in, int32_t rc)
Definition: rm_foms.c:163
static struct m0_rm_incoming_ops remote_incoming_ops
Definition: rm_foms.c:80
M0_INTERNAL void m0_rm_incoming_fini(struct m0_rm_incoming *in)
Definition: rm.c:1099
M0_INTERNAL void m0_rm_owner_unlock(struct m0_rm_owner *owner)
Definition: rm.c:603
void(* fo_fini)(struct m0_fom *fom)
Definition: fom.h:657
const struct m0_sm_conf canoke_sm_conf
Definition: rm_foms.c:157
struct m0_cookie rem_cookie
Definition: rm.h:768
#define out(...)
Definition: gen.c:41
void m0_fom_phase_set(struct m0_fom *fom, int phase)
Definition: fom.c:1688
int type
Definition: dir.c:1031
M0_INTERNAL void m0_rm_owner_lock(struct m0_rm_owner *owner)
Definition: rm.c:592
uint64_t rl_id
Definition: rm.h:1111
struct m0_uint128 cr_group_id
Definition: rm.h:506
M0_INTERNAL struct m0_rm_remote * m0_rm_remote_find(struct m0_rm_remote_incoming *rem_in)
Definition: rm.c:1366
static int reply_prepare(const enum m0_rm_incoming_type type, struct m0_fom *fom)
Definition: rm_foms.c:283
static int borrow_fom_tick(struct m0_fom *)
Definition: rm_foms.c:730
struct m0_uint128 ri_group_id
Definition: rm_internal.h:61
struct m0_rpc_machine * ri_rmachine
Definition: item.h:160
static void reply_err_set(enum m0_rm_incoming_type type, struct m0_fom *fom, int rc)
Definition: rm_foms.c:330
struct m0_fop_type m0_rm_fop_revoke_rep_fopt
Definition: rm_fops.c:76
void m0_free(void *data)
Definition: memory.c:146
uint32_t sm_state
Definition: sm.h:307
M0_INTERNAL int m0_rm_borrow_commit(struct m0_rm_remote_incoming *rem_in)
Definition: rm.c:1564
static struct m0_reqh_service * service[REQH_IN_UT_MAX]
Definition: long_lock_ut.c:46
struct m0_clink rht_clink
Definition: rm_ha.h:104
struct m0_rm_reserve_prio rin_reserve
Definition: rm.h:1475
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
struct m0_reqh * rm_reqh
Definition: rpc_machine.h:105
static void revoke_fom_fini(struct m0_fom *fom)
Definition: rm_foms.c:833
Definition: fop.h:79
M0_INTERNAL void m0_rm_credit_get(struct m0_rm_incoming *in)
Definition: rm.c:1758
uint64_t rrq_policy
Definition: rm_fops.h:93
Definition: trace.h:478
M0_INTERNAL const char * m0_rpc_item_remote_ep_addr(const struct m0_rpc_item *item)
Definition: item.c:1188
struct m0_rm_remote_incoming rf_in
Definition: rm_foms.h:59
#define M0_IMPOSSIBLE(fmt,...)
bool rem_dead
Definition: rm.h:788
static int request_fom_tick(struct m0_fom *fom, enum m0_rm_incoming_type type)
Definition: rm_foms.c:657