Motr  M0
cob_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 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_COB
24 #include "lib/trace.h"
25 #include "lib/finject.h"
26 
27 #include "ioservice/io_addb2.h" /* M0_AVI_IOS_IO_ATTR_FOMCOB_FOP_TYPE */
28 #include "ioservice/cob_foms.h" /* m0_fom_cob_create */
29 #include "ioservice/fid_convert.h" /* m0_fid_convert_cob2stob */
30 #include "ioservice/io_service.h" /* m0_reqh_io_service */
31 #include "ioservice/storage_dev.h" /* m0_storage_dev_stob_find */
32 #include "motr/setup.h" /* m0_cs_ctx_get */
33 #include "stob/domain.h" /* m0_stob_domain_find_by_stob_id */
34 
35 struct m0_poolmach;
36 
37 /* Forward Declarations. */
38 static void cc_fom_fini(struct m0_fom *fom);
39 static int cob_ops_fom_tick(struct m0_fom *fom);
40 static void cob_op_credit(struct m0_fom *fom, enum m0_cob_op opcode,
41  struct m0_be_tx_credit *accum);
42 static int cc_cob_create(struct m0_fom *fom,
43  struct m0_fom_cob_op *cc,
44  const struct m0_cob_attr *attr);
45 
46 static void cd_fom_fini(struct m0_fom *fom);
47 static int cd_cob_delete(struct m0_fom *fom,
48  struct m0_fom_cob_op *cd,
49  const struct m0_cob_attr *attr);
50 static void ce_stob_destroy_credit(struct m0_fom_cob_op *cob_op,
51  struct m0_be_tx_credit *accum);
52 static int ce_stob_edit_credit(struct m0_fom *fom, struct m0_fom_cob_op *cc,
53  struct m0_be_tx_credit *accum, uint32_t cot);
54 static int ce_stob_edit(struct m0_fom *fom, struct m0_fom_cob_op *cd,
55  uint32_t cot);
56 static int cob_fom_populate(struct m0_fom *fom);
57 static int cob_op_fom_create(struct m0_fom **out);
58 static size_t cob_fom_locality_get(const struct m0_fom *fom);
59 static inline struct m0_fom_cob_op *cob_fom_get(const struct m0_fom *fom);
60 static int cob_getattr_fom_tick(struct m0_fom *fom);
61 static void cob_getattr_fom_fini(struct m0_fom *fom);
62 static int cob_getattr(struct m0_fom *fom,
63  struct m0_fom_cob_op *gop,
64  struct m0_cob_attr *attr);
65 static int cob_setattr_fom_tick(struct m0_fom *fom);
66 static void cob_setattr_fom_fini(struct m0_fom *fom);
67 static int cob_setattr(struct m0_fom *fom,
68  struct m0_fom_cob_op *gop,
69  struct m0_cob_attr *attr);
70 static int cob_locate(const struct m0_fom *fom, struct m0_cob **cob);
71 static int cob_attr_get(struct m0_cob *cob,
72  struct m0_cob_attr *attr);
73 static void cob_stob_create_credit(struct m0_fom *fom);
74 static int cob_stob_delete_credit(struct m0_fom *fom);
75 static struct m0_cob_domain *cdom_get(const struct m0_fom *fom);
76 static int cob_ops_stob_find(struct m0_fom_cob_op *co);
77 static int cob_bytecount_decrement(struct m0_cob *cob, struct m0_cob_bckey *key,
78  uint64_t bytecount, struct m0_be_tx *tx);
79 
80 enum {
84 };
85 
88  .sd_name = "COB OP Prepare",
89  .sd_allowed = M0_BITS(M0_FOPH_COB_OPS_EXECUTE,
91  },
93  .sd_name = "COB OP EXECUTE",
94  .sd_allowed = M0_BITS(M0_FOPH_SUCCESS,
96  }
97 };
98 
99 const struct m0_sm_conf cob_ops_conf = {
100  .scf_name = "COB create/delete/getattr",
101  .scf_nr_states = ARRAY_SIZE(cob_ops_phases),
102  .scf_state = cob_ops_phases
103 };
104 
111 };
112 
114 static const struct m0_fom_ops cc_fom_ops = {
115  .fo_fini = cc_fom_fini,
116  .fo_tick = cob_ops_fom_tick,
117  .fo_home_locality = cob_fom_locality_get
118 };
119 
121 static const struct m0_fom_ops cd_fom_ops = {
122  .fo_fini = cd_fom_fini,
123  .fo_tick = cob_ops_fom_tick,
124  .fo_home_locality = cob_fom_locality_get
125 };
126 
128 static const struct m0_fom_ops ct_fom_ops = {
129  .fo_fini = cd_fom_fini,
130  .fo_tick = cob_ops_fom_tick,
131  .fo_home_locality = cob_fom_locality_get
132 };
133 
135 static const struct m0_fom_ops cob_getattr_fom_ops = {
137  .fo_tick = cob_getattr_fom_tick,
138  .fo_home_locality = cob_fom_locality_get
139 };
140 
142 static const struct m0_fom_ops cob_setattr_fom_ops = {
144  .fo_tick = cob_setattr_fom_tick,
145  .fo_home_locality = cob_fom_locality_get
146 };
147 
148 static bool cob_is_md(const struct m0_fom_cob_op *cfom)
149 {
150  return cfom->fco_cob_type == M0_COB_MD;
151 }
152 
153 static void cob_fom_stob2fid_map(const struct m0_fom_cob_op *cfom,
154  struct m0_fid *out)
155 {
156  if (cob_is_md(cfom))
157  *out = cfom->fco_gfid;
158  else
160 }
161 
162 static void addb2_add_cob_fom_attrs(const struct m0_fom_cob_op *cfom)
163 {
164  const struct m0_fom *fom = &cfom->fco_fom;
165 
166  M0_ADDB2_ADD(M0_AVI_ATTR, m0_sm_id_get(&fom->fo_sm_phase),
168  cfom->fco_fop_type);
169  M0_ADDB2_ADD(M0_AVI_ATTR, m0_sm_id_get(&fom->fo_sm_phase),
171  cfom->fco_gfid.f_container);
172  M0_ADDB2_ADD(M0_AVI_ATTR, m0_sm_id_get(&fom->fo_sm_phase),
174  cfom->fco_gfid.f_key);
175  M0_ADDB2_ADD(M0_AVI_ATTR, m0_sm_id_get(&fom->fo_sm_phase),
177  cfom->fco_cfid.f_container);
178  M0_ADDB2_ADD(M0_AVI_ATTR, m0_sm_id_get(&fom->fo_sm_phase),
180  cfom->fco_cfid.f_key);
181 }
182 
183 M0_INTERNAL int m0_cob_fom_create(struct m0_fop *fop, struct m0_fom **out,
184  struct m0_reqh *reqh)
185 {
186  int rc;
187  struct m0_fop *rfop;
188  struct m0_fom *fom;
189  const struct m0_fom_ops *fom_ops;
190  struct m0_fom_cob_op *cfom;
191  struct m0_fop_type *reptype;
192 
193  M0_PRE(fop != NULL);
194  M0_PRE(fop->f_type != NULL);
195  M0_PRE(out != NULL);
199 
201  if (rc != 0) {
202  return M0_RC(rc);
203  }
204  cfom = cob_fom_get(*out);
205  fom = *out;
206  M0_ASSERT(fom != NULL);
207 
208  if (m0_is_cob_create_fop(fop)) {
209  fom_ops = &cc_fom_ops;
210  reptype = &m0_fop_cob_op_reply_fopt;
211  } else if (m0_is_cob_delete_fop(fop)) {
212  fom_ops = &cd_fom_ops;
213  reptype = &m0_fop_cob_op_reply_fopt;
214  } else if (m0_is_cob_truncate_fop(fop)) {
215  fom_ops = &ct_fom_ops;
216  reptype = &m0_fop_cob_op_reply_fopt;
217  } else if (m0_is_cob_getattr_fop(fop)) {
218  fom_ops = &cob_getattr_fom_ops;
220  } else if (m0_is_cob_setattr_fop(fop)) {
221  fom_ops = &cob_setattr_fom_ops;
223  } else
224  M0_IMPOSSIBLE("Invalid fop type!");
225 
226  rfop = m0_fop_reply_alloc(fop, reptype);
227  if (rfop == NULL) {
228  m0_free(cfom);
229  return M0_ERR(-ENOMEM);
230  }
231 
232  m0_fom_init(fom, &fop->f_type->ft_fom_type, fom_ops, fop, rfop, reqh);
234 
235  return M0_RC(rc);
236 }
237 
238 static int cob_op_fom_create(struct m0_fom **out)
239 {
240  struct m0_fom_cob_op *cfom;
241 
242  M0_PRE(out != NULL);
243 
244  M0_ALLOC_PTR(cfom);
245  if (cfom == NULL)
246  return M0_ERR(-ENOMEM);
247 
248  *out = &cfom->fco_fom;
249  return 0;
250 }
251 
252 static inline struct m0_fom_cob_op *cob_fom_get(const struct m0_fom *fom)
253 {
254  M0_PRE(fom != NULL);
255 
256  return container_of(fom, struct m0_fom_cob_op, fco_fom);
257 }
258 
259 static void cc_fom_fini(struct m0_fom *fom)
260 {
261  struct m0_fom_cob_op *cfom;
262 
263  M0_PRE(fom != NULL);
264 
265  cfom = cob_fom_get(fom);
267  m0_fom_fini(fom);
268  m0_free(cfom);
269 }
270 
271 M0_INTERNAL size_t m0_cob_io_fom_locality(const struct m0_fid *fid)
272 {
273  uint64_t hash = m0_fid_hash(fid);
274 
275  return m0_rnd(1 << 30, &hash) >> 1;
276 }
277 
278 static size_t cob_fom_locality_get(const struct m0_fom *fom)
279 {
280  M0_PRE(fom != NULL);
281 
283 }
284 
285 static int cob_fom_populate(struct m0_fom *fom)
286 {
287  struct m0_fom_cob_op *cfom;
288  struct m0_fop_cob_common *common;
289  struct m0_fop *fop;
290  int rc;
291  M0_PRE(fom != NULL);
292  M0_PRE(fom->fo_fop != NULL);
293 
294  fop = fom->fo_fop;
295  common = m0_cobfop_common_get(fom->fo_fop);
296  cfom = cob_fom_get(fom);
297  cfom->fco_gfid = common->c_gobfid;
298  cfom->fco_cfid = common->c_cobfid;
300  cfom->fco_cob_idx = common->c_cob_idx;
301  cfom->fco_cob_type = common->c_cob_type;
302  cfom->fco_flags = common->c_flags;
306  cfom->fco_recreate = false;
307  cfom->fco_is_done = false;
308  M0_LOG(M0_DEBUG, "Cob %s operation for "FID_F"/%x "FID_F" for %s",
309  m0_fop_name(fop), FID_P(&cfom->fco_cfid),
310  cfom->fco_cob_idx, FID_P(&cfom->fco_gfid),
311  cob_is_md(cfom) ? "MD" : "IO");
312 
313  if (M0_IN(cfom->fco_fop_type,(M0_COB_OP_DELETE, M0_COB_OP_TRUNCATE))) {
314  rc = m0_indexvec_alloc(&cfom->fco_range, 1);
315  if (rc != 0)
316  return M0_ERR(-ENOMEM);
317  rc = m0_indexvec_alloc(&cfom->fco_want, 1);
318  if (rc != 0) {
319  m0_indexvec_free(&cfom->fco_range);
320  return M0_ERR(-ENOMEM);
321  }
322  rc = m0_indexvec_alloc(&cfom->fco_got, 1);
323  if (rc != 0) {
324  m0_indexvec_free(&cfom->fco_range);
325  m0_indexvec_free(&cfom->fco_want);
326  return M0_ERR(-ENOMEM);
327  }
328  cfom->fco_range.iv_index[0] = 0;
329  cfom->fco_range.iv_vec.v_count[0] = M0_BINDEX_MAX + 1;
330  cfom->fco_range_idx = 0;
331  }
332  return M0_RC(0);
333 }
334 
335 static int cob_ops_stob_find(struct m0_fom_cob_op *co)
336 {
337  struct m0_storage_devs *devs = m0_cs_storage_devs_get();
338  int rc;
339 
340  rc = m0_storage_dev_stob_find(devs, &co->fco_stob_id, &co->fco_stob);
341  if (rc == 0 && m0_stob_state_get(co->fco_stob) == CSS_NOENT) {
343  rc = -ENOENT;
344  }
345  return M0_RC(rc);
346 }
347 
348 static void cob_tick_tail(struct m0_fom *fom,
349  struct m0_fop_cob_op_rep_common *r_common)
350 {
351  M0_PRE(fom != NULL);
352 
354  /* Piggyback some information about the transaction */
355  m0_fom_mod_rep_fill(&r_common->cor_mod_rep, fom);
356 }
357 
358 static int cob_getattr_fom_tick(struct m0_fom *fom)
359 {
360  struct m0_cob_attr attr = { { 0, } };
361  int rc = 0;
362  struct m0_fom_cob_op *cob_op;
363  const char *ops;
364  struct m0_fop *fop;
365  struct m0_fop_cob_op_rep_common *r_common;
367 
368  M0_PRE(fom != NULL);
369  M0_PRE(fom->fo_ops != NULL);
370  M0_PRE(fom->fo_type != NULL);
371 
372  cob_op = cob_fom_get(fom);
373  M0_ENTRY("cob_getattr for "FID_F", phase %s", FID_P(&cob_op->fco_gfid),
375 
376  fop = fom->fo_fop;
377  reply = m0_fop_data(fom->fo_rep_fop);
378  r_common = &reply->cgr_common;
379 
380  if (m0_fom_phase(fom) < M0_FOPH_NR) {
382  return M0_RC(rc);
383  }
384 
385  ops = m0_fop_name(fop);
386 
387  switch (m0_fom_phase(fom)) {
389  M0_LOG(M0_DEBUG, "Cob %s operation prepare", ops);
391  reply->cgr_rc = 0;
392  return M0_FSO_AGAIN;
394  M0_LOG(M0_DEBUG, "Cob %s operation started for "FID_F,
395  ops, FID_P(&cob_op->fco_gfid));
396  rc = cob_getattr(fom, cob_op, &attr);
397  m0_md_cob_mem2wire(&reply->cgr_body, &attr);
399  M0_LOG(M0_DEBUG, "Cob %s operation for "FID_F" finished with "
400  "%d", ops, FID_P(&cob_op->fco_gfid), rc);
401  break;
402  default:
403  M0_IMPOSSIBLE("Invalid phase for cob getattr fom.");
404  rc = -EINVAL;
406  }
407 
408  if (rc != 0)
409  reply->cgr_rc = rc;
410  cob_tick_tail(fom, r_common);
411  return M0_RC(M0_FSO_AGAIN);
412 }
413 
414 static int cob_setattr_fom_tick(struct m0_fom *fom)
415 {
416  struct m0_cob_attr attr = { { 0, } };
417  int rc = 0;
418  struct m0_fom_cob_op *cob_op;
419  const char *ops;
420  struct m0_fop *fop;
422  struct m0_fop_cob_op_rep_common *r_common;
424  struct m0_be_tx_credit *tx_cred;
425 
426  M0_PRE(fom != NULL);
427  M0_PRE(fom->fo_ops != NULL);
428  M0_PRE(fom->fo_type != NULL);
429 
430  cob_op = cob_fom_get(fom);
431  M0_ENTRY("cob_setattr for "FID_F", phase %s", FID_P(&cob_op->fco_gfid),
433 
434  fop = fom->fo_fop;
436  reply = m0_fop_data(fom->fo_rep_fop);
437  r_common = &reply->csr_common;
438  ops = m0_fop_name(fop);
439 
440  if (m0_fom_phase(fom) < M0_FOPH_NR) {
441  switch(m0_fom_phase(fom)) {
442  case M0_FOPH_TXN_OPEN:
443  tx_cred = m0_fom_tx_credit(fom);
445  if (cob_op->fco_flags & M0_IO_FLAG_CROW)
447  break;
448  }
450  return M0_RC(rc);
451  }
452 
453  switch (m0_fom_phase(fom)) {
455  M0_LOG(M0_DEBUG, "Cob %s operation prepare", ops);
457  reply->csr_rc = 0;
458  return M0_FSO_AGAIN;
460  M0_LOG(M0_DEBUG, "Cob %s operation started for "FID_F,
461  ops, FID_P(&cob_op->fco_gfid));
464  rc = cob_setattr(fom, cob_op, &attr);
466  M0_LOG(M0_DEBUG, "Cob %s operation finished with %d", ops, rc);
467  break;
468  default:
469  M0_IMPOSSIBLE("Invalid phase for cob setattr fom.");
470  rc = -EINVAL;
472  }
473 
474  if (rc != 0)
475  reply->csr_rc = rc;
476  cob_tick_tail(fom, r_common);
477  return M0_RC(M0_FSO_AGAIN);
478 }
479 
480 static bool cob_pool_version_mismatch(const struct m0_fom *fom)
481 {
482  int rc;
483  struct m0_cob *cob;
484  struct m0_fop_cob_common *common;
485 
486  common = m0_cobfop_common_get(fom->fo_fop);
487  rc = cob_locate(fom, &cob);
488  if (rc == 0 && cob != NULL) {
489  M0_LOG(M0_DEBUG, "cob pver"FID_F", common pver"FID_F,
491  FID_P(&common->c_body.b_pver));
492  return !m0_fid_eq(&cob->co_nsrec.cnr_pver,
493  &common->c_body.b_pver);
494  }
495  return false;
496 }
497 
498 static void cob_stob_create_credit(struct m0_fom *fom)
499 {
500  struct m0_fom_cob_op *cob_op;
501  struct m0_be_tx_credit *tx_cred;
502 
503  cob_op = cob_fom_get(fom);
504  tx_cred = m0_fom_tx_credit(fom);
505  if (!cob_is_md(cob_op))
506  m0_cc_stob_cr_credit(&cob_op->fco_stob_id, tx_cred);
508  cob_op->fco_is_done = true;
509 }
510 
511 static int cob_stob_create(struct m0_fom *fom, struct m0_cob_attr *attr)
512 {
513  int rc = 0;
514  struct m0_fom_cob_op *cob_op;
515 
516  cob_op = cob_fom_get(fom);
517  if (!cob_is_md(cob_op))
518  rc = m0_cc_stob_create(fom, &cob_op->fco_stob_id);
519  return rc ?: cc_cob_create(fom, cob_op, attr);
520 }
521 
522 static int cob_stob_delete_credit(struct m0_fom *fom)
523 {
524  int rc = 0;
525  struct m0_fom_cob_op *cob_op;
526  uint32_t fop_type;
527  struct m0_be_tx_credit *tx_cred;
528  struct m0_be_tx_credit cob_op_tx_credit = {};
529 
530  cob_op = cob_fom_get(fom);
531  tx_cred = m0_fom_tx_credit(fom);
532  fop_type = cob_op->fco_fop_type;
533  if (cob_is_md(cob_op)) {
536  if (cob_op->fco_recreate)
538  cob_op->fco_is_done = true;
539  return M0_RC(rc);
540  }
541  rc = ce_stob_edit_credit(fom, cob_op, tx_cred, fop_type);
542  if (rc == 0) {
543  M0_SET0(&cob_op_tx_credit);
544  cob_op_credit(fom, fop_type, &cob_op_tx_credit);
545  if (cob_op->fco_recreate)
547  if (fop_type == M0_COB_OP_DELETE &&
548  !m0_be_should_break(m0_fom_tx(fom)->t_engine, tx_cred,
549  &cob_op_tx_credit)) {
550  m0_be_tx_credit_add(tx_cred, &cob_op_tx_credit);
551  ce_stob_destroy_credit(cob_op, tx_cred);
552  m0_be_tx_credit_add(tx_cred, &cob_op_tx_credit);
553  cob_op->fco_is_done = true;
554  }
555  }
556  return M0_RC(rc);
557 }
558 
559 static int cob_stob_ref_drop_wait(struct m0_fom *fom)
560 {
561  struct m0_stob *stob = cob_fom_get(fom)->fco_stob;
562 
563  M0_PRE(cob_fom_get(fom)->fco_fop_type == M0_COB_OP_DELETE);
566 
568  m0_fom_wait_on(fom, &stob->so_ref_chan, &fom->fo_cb);
570  M0_LOG(M0_DEBUG, "fom %p, stob %p, stob->so_ref = %"PRIu64
571  ", waiting for ref to drop to 1", fom, stob, stob->so_ref);
572 
573  return M0_RC(M0_FSO_WAIT);
574 }
575 
576 static int cob_ops_fom_tick(struct m0_fom *fom)
577 {
578  struct m0_fom_cob_op *cob_op;
579  struct m0_fop_cob_common *common;
580  struct m0_cob_attr attr = { { 0, } };
581  int rc = 0;
582  uint32_t fop_type;
583  const char *ops;
584  struct m0_fop *fop;
585  struct m0_fop_cob_op_rep_common *r_common;
586  struct m0_fop_cob_op_reply *reply;
587  struct m0_stob *stob = NULL;
588  struct m0_be_tx *tx = m0_fom_tx(fom);
589 
590  M0_PRE(fom != NULL);
591  M0_PRE(fom->fo_ops != NULL);
592  M0_PRE(fom->fo_type != NULL);
593 
594  fop = fom->fo_fop;
595  common = m0_cobfop_common_get(fop);
596  reply = m0_fop_data(fom->fo_rep_fop);
597  r_common = &reply->cor_common;
598  cob_op = cob_fom_get(fom);
599  fop_type = cob_op->fco_fop_type;
600 
601  M0_ENTRY("fom %p, fop %p, item %p[%u], phase %s, "FID_F" stob %p",
602  fom, fom->fo_fop, m0_fop_to_rpc_item(fom->fo_fop),
603  m0_fop_opcode(fom->fo_fop),
605  FID_P(&cob_op->fco_cfid), cob_op->fco_stob);
606  if (m0_fom_phase(fom) < M0_FOPH_NR) {
607  switch (m0_fom_phase(fom)) {
608  case M0_FOPH_INIT:
609  /*
610  * If M0_FOPH_INIT phase is being entered the second
611  * time or beyond, specifically by the cob-delete fom,
612  * after waiting for so_ref to drop to 1, then there is
613  * nothing more to be done in this phase.
614  */
615  if (!cob_is_md(cob_op) &&
617  cob_op->fco_stob != NULL) {
618  stob = cob_op->fco_stob;
619  if (stob->so_ref > 1)
620  return M0_RC(
622  M0_LOG(M0_DEBUG, "fom %p, fom_type %d, "
623  "stob %p, Finished waiting for "
624  "ref to drop to 1", fom,
625  cob_op->fco_fop_type, stob);
626  /* Mark the stob state as CSS_DELETE */
627  m0_stob_delete_mark(cob_op->fco_stob);
628  break;
629  }
630 
631  /* Check if cob with different pool version exists. */
632  if (fop_type == M0_COB_OP_CREATE &&
634  M0_CNT_DEC(common->c_body.b_nlink);
635  fop_type = cob_op->fco_fop_type =
637  cob_op->fco_recreate = true;
638  }
639 
640  if (fop_type == M0_COB_OP_CREATE)
641  break;
642  /*
643  * Find the stob and handle non-existing stob error
644  * earlier, before initialising the transaction.
645  * This avoids complications in handling transaction
646  * cleanup.
647  */
648  rc = cob_is_md(cob_op) ? 0 : cob_ops_stob_find(cob_op);
649  if (rc != 0) {
650  if (rc == -ENOENT &&
651  cob_op->fco_flags & M0_IO_FLAG_CROW) {
652  /* nothing to delete or truncate */
653  M0_ASSERT(M0_IN(fop_type,
656  rc = 0;
659  } else {
662  }
663  cob_op->fco_is_done = true;
664  goto tail;
665  }
666 
667  /*
668  * TODO Optimise this code with the similar code above
669  * for entering the M0_FOPH_INIT state for the
670  * second time and beyond.
671  */
672  if (!cob_is_md(cob_op) &&
674  if (cob_op->fco_stob->so_ref > 1)
675  return M0_RC(
677  else
678  /* Mark the stob state as CSS_DELETE */
679  m0_stob_delete_mark(cob_op->fco_stob);
680  }
681 
683  struct m0_fop_cob_truncate *trunc =
684  m0_fop_data(fop);
685  if (trunc->ct_io_ivec.ci_nr > 0) {
686  uint32_t bshift;
687 
688  bshift = m0_stob_block_shift(
689  cob_op->fco_stob);
691  &trunc->ct_io_ivec,
692  trunc->ct_io_ivec.ci_nr,
693  bshift, &cob_op->fco_range);
694  }
695  M0_LOG(M0_DEBUG, "trunc count%"PRIu64,
696  trunc->ct_size);
697  }
698  break;
699  case M0_FOPH_TXN_OPEN:
700  switch (fop_type) {
701  case M0_COB_OP_CREATE:
703  break;
704  case M0_COB_OP_DELETE:
705  case M0_COB_OP_TRUNCATE:
707  if (rc == -EAGAIN)
708  rc = 0;
709  if (rc != 0)
710  goto tail;
711  break;
712  default:
713  M0_IMPOSSIBLE("Invalid fop type!");
714  break;
715  }
716  break;
717  case M0_FOPH_QUEUE_REPLY:
718  /*
719  * When an operation can't be done in a single
720  * transaction due to insufficient credits, it is split
721  * into multiple trasactions.
722  * As the the operation is incomplete, skip the sending
723  * of reply and reinitialise the trasaction.
724  * i.e move fom phase to M0_FOPH_TXN_LOGGED_WAIT and
725  * then to M0_FOPH_TXN_INIT.
726  */
727  if (!cob_op->fco_is_done && m0_fom_rc(fom) == 0) {
729  return M0_FSO_AGAIN;
730  }
731 
732  if (cob_op->fco_fop_type == M0_COB_OP_CREATE &&
734  M0_LOG(M0_DEBUG, "fom wait for tx to be logged");
735  m0_fom_wait_on(fom, &tx->t_sm.sm_chan, &fom->fo_cb);
736  return M0_FSO_WAIT;
737  }
738  break;
740  if (!cob_op->fco_is_done && m0_fom_rc(fom) == 0) {
742  if (rc == M0_FSO_AGAIN) {
743  M0_SET0(tx);
745  } else
746  return M0_RC(rc);
747  }
748  break;
749  }
751  return M0_RC(rc);
752  }
753  ops = m0_fop_name(fop);
754 
755  switch (m0_fom_phase(fom)) {
758  reply->cor_rc = 0;
759  return M0_RC(M0_FSO_AGAIN);
761  fop_type = cob_op->fco_fop_type;
762  M0_LOG(M0_DEBUG, "Cob %s operation for "FID_F"/%x "FID_F" for %s",
763  ops, FID_P(&cob_op->fco_cfid),
764  cob_op->fco_cob_idx,
765  FID_P(&cob_op->fco_gfid),
766  cob_is_md(cob_op) ? "MD" : "IO");
767  m0_md_cob_wire2mem(&attr, &common->c_body);
768  if (fop_type == M0_COB_OP_CREATE) {
769  rc = cob_stob_create(fom, &attr);
770  } else if (fop_type == M0_COB_OP_DELETE) {
771  if (cob_op->fco_is_done) {
772  rc = cob_is_md(cob_op) ? 0 :
773  ce_stob_edit(fom, cob_op,
775  rc = rc ?: cd_cob_delete(fom, cob_op, &attr);
776  if (rc == 0 && cob_op->fco_recreate) {
777  cob_op->fco_fop_type = M0_COB_OP_CREATE;
778  M0_CNT_INC(attr.ca_nlink);
779  rc = cob_stob_create(fom, &attr);
780  }
781  } else
782  rc = ce_stob_edit(fom, cob_op,
784  } else {
786  if (cob_op->fco_is_done)
788  cob_op->fco_stob);
789  }
790 
792  M0_LOG(M0_DEBUG, "Cob %s operation finished with %d", ops, rc);
793  break;
794  default:
795  M0_IMPOSSIBLE("Invalid phase for cob create/delete fom.");
796  rc = -EINVAL;
798  }
799 
800 tail:
801  if (rc != 0)
802  reply->cor_rc = rc;
803  cob_tick_tail(fom, r_common);
804  return M0_RC(M0_FSO_AGAIN);
805 }
806 
807 M0_INTERNAL int m0_cc_stob_cr_credit(struct m0_stob_id *sid,
808  struct m0_be_tx_credit *accum)
809 {
810  struct m0_stob_domain *sdom;
811 
812  M0_ENTRY("stob_fid="FID_F, FID_P(&sid->si_fid));
813 
815  if (sdom == NULL) {
816  return M0_ERR(-EINVAL);
817  }
818 
819  m0_stob_create_credit(sdom, accum);
820 
821  return M0_RC(0);
822 }
823 
824 M0_INTERNAL int m0_cc_stob_create(struct m0_fom *fom, struct m0_stob_id *sid)
825 {
826  int rc;
827 
828  M0_ENTRY("stob create fid="FID_F, FID_P(&sid->si_fid));
830  sid, &fom->fo_tx);
831  return M0_RC(rc);
832 }
833 
834 static struct m0_cob_domain *cdom_get(const struct m0_fom *fom)
835 {
836  struct m0_reqh_io_service *ios;
837 
838  M0_PRE(fom != NULL);
839 
840  ios = container_of(fom->fo_service, struct m0_reqh_io_service,
841  rios_gen);
842 
843  return ios->rios_cdom;
844 }
845 
846 M0_INTERNAL int m0_cc_cob_nskey_make(struct m0_cob_nskey **nskey,
847  const struct m0_fid *gfid,
848  uint32_t cob_idx)
849 {
850  char nskey_name[M0_FID_STR_LEN] = { 0 };
851  uint32_t nskey_name_len;
852 
854 
855  nskey_name_len = sprintf(nskey_name, "%u", cob_idx);
856 
857  return m0_cob_nskey_make(nskey, gfid, nskey_name, nskey_name_len);
858 }
859 
860 static int cc_md_cob_nskey_make(struct m0_cob_nskey **nskey,
861  const struct m0_fid *gfid)
862 {
864 
865  return m0_cob_nskey_make(nskey, gfid, (const char*)gfid, sizeof *gfid);
866 }
867 
868 static void cob_op_credit(struct m0_fom *fom, enum m0_cob_op opcode,
869  struct m0_be_tx_credit *accum)
870 {
871  struct m0_cob_domain *cdom;
872 
873  M0_PRE(fom != NULL);
874  cdom = cdom_get(fom);
875  M0_ASSERT(cdom != NULL);
876  m0_cob_tx_credit(cdom, opcode, accum);
877 }
878 
882 };
883 
884 static int cob_attr_get(struct m0_cob *cob,
885  struct m0_cob_attr *attr)
886 {
887  /* copy attr from cob to @attr */
888  M0_SET0(attr);
889  attr->ca_valid = 0;
890  attr->ca_tfid = cob->co_nsrec.cnr_fid;
891  attr->ca_pfid = cob->co_nskey->cnk_pfid;
892 
893  /*
894  * Copy permissions and owner info into rep.
895  */
896  if (cob->co_flags & M0_CA_OMGREC) {
897  attr->ca_valid |= M0_COB_UID | M0_COB_GID | M0_COB_MODE;
898  attr->ca_uid = cob->co_omgrec.cor_uid;
899  attr->ca_gid = cob->co_omgrec.cor_gid;
900  attr->ca_mode = cob->co_omgrec.cor_mode;
901  }
902 
903  /*
904  * Copy nsrec fields into response.
905  */
906  if (cob->co_flags & M0_CA_NSREC) {
907  attr->ca_valid |= M0_COB_ATIME | M0_COB_CTIME | M0_COB_MTIME |
910  attr->ca_atime = cob->co_nsrec.cnr_atime;
911  attr->ca_ctime = cob->co_nsrec.cnr_ctime;
912  attr->ca_mtime = cob->co_nsrec.cnr_mtime;
913  attr->ca_blksize = cob->co_nsrec.cnr_blksize;
914  attr->ca_blocks = cob->co_nsrec.cnr_blocks;
915  attr->ca_nlink = cob->co_nsrec.cnr_nlink;
916  attr->ca_size = cob->co_nsrec.cnr_size;
917  attr->ca_lid = cob->co_nsrec.cnr_lid;
918  attr->ca_pver = cob->co_nsrec.cnr_pver;
919  }
920  return 0;
921 }
922 
923 static int cob_locate(const struct m0_fom *fom, struct m0_cob **cob_out)
924 {
925  struct m0_cob_oikey oikey;
926  struct m0_cob_domain *cdom;
927  struct m0_fid fid;
928  struct m0_fom_cob_op *cob_op;
929  struct m0_cob *cob;
930  int rc;
931 
932  cob_op = cob_fom_get(fom);
933  M0_ASSERT(cob_op != NULL);
934  cdom = cdom_get(fom);
935  M0_ASSERT(cdom != NULL);
936  cob_fom_stob2fid_map(cob_op, &fid);
937  m0_cob_oikey_make(&oikey, &fid, 0);
938  rc = m0_cob_locate(cdom, &oikey, 0, &cob);
939  if (rc == 0)
940  *cob_out = cob;
941  return rc;
942 }
943 
944 static int cob_attr_op(struct m0_fom *fom,
945  struct m0_fom_cob_op *gop,
946  struct m0_cob_attr *attr,
947  enum cob_attr_operation op)
948 {
949  int rc;
950  struct m0_cob *cob;
951  struct m0_be_tx *tx;
952  uint32_t valid = attr->ca_valid;
953 
954  M0_PRE(fom != NULL);
955  M0_PRE(gop != NULL);
957 
958  M0_LOG(M0_DEBUG, "cob attr for "FID_F"/%x "FID_F" %s",
959  FID_P(&gop->fco_cfid), gop->fco_cob_idx,
960  FID_P(&gop->fco_gfid),
961  cob_is_md(gop) ? "MD" : "IO");
962 
963  rc = cob_locate(fom, &cob);
964  if (rc != 0) {
965  if (valid & M0_COB_NLINK)
966  M0_LOG(M0_DEBUG, "nlink = %u", attr->ca_nlink);
967  /*
968  * CROW setattr must have non-zero nlink set
969  * to avoid creation of invalid cobs.
970  */
971  if (rc != -ENOENT || !(gop->fco_flags & M0_IO_FLAG_CROW) ||
972  !(valid & M0_COB_NLINK) || attr->ca_nlink == 0)
973  return M0_RC(rc);
976  if (rc != 0)
977  return M0_RC(rc);
978  }
979 
980  M0_ASSERT(cob != NULL);
982  switch (op) {
983  case COB_ATTR_GET:
984  rc = cob_attr_get(cob, attr);
985  M0_ASSERT(ergo(attr->ca_valid & M0_COB_PVER,
986  m0_fid_is_set(&attr->ca_pver) &&
987  m0_fid_is_valid(&attr->ca_pver)));
988  break;
989  case COB_ATTR_SET:
990  tx = m0_fom_tx(fom);
991  rc = m0_cob_setattr(cob, attr, tx);
992  break;
993  }
994  m0_cob_put(cob);
995 
996  M0_LOG(M0_DEBUG, "Cob attr: %d rc: %d", op, rc);
997  return M0_RC(rc);
998 }
999 
1000 static int cob_getattr(struct m0_fom *fom,
1001  struct m0_fom_cob_op *gop,
1002  struct m0_cob_attr *attr)
1003 {
1004  return cob_attr_op(fom, gop, attr, COB_ATTR_GET);
1005 }
1006 
1007 static int cob_setattr(struct m0_fom *fom,
1008  struct m0_fom_cob_op *gop,
1009  struct m0_cob_attr *attr)
1010 {
1011  return cob_attr_op(fom, gop, attr, COB_ATTR_SET);
1012 }
1013 
1014 static int cc_cob_create(struct m0_fom *fom,
1015  struct m0_fom_cob_op *cc,
1016  const struct m0_cob_attr *attr)
1017 {
1018  struct m0_cob_domain *cdom;
1019  struct m0_be_tx *tx;
1020  int rc;
1021 
1022  M0_PRE(fom != NULL);
1023  M0_PRE(cc != NULL);
1024 
1025  cdom = cdom_get(fom);
1026  M0_ASSERT(cdom != NULL);
1027  tx = m0_fom_tx(fom);
1028  rc = m0_cc_cob_setup(cc, cdom, attr, tx);
1029 
1030  return M0_RC(rc);
1031 }
1032 
1033 M0_INTERNAL int m0_cc_cob_setup(struct m0_fom_cob_op *cc,
1034  struct m0_cob_domain *cdom,
1035  const struct m0_cob_attr *attr,
1036  struct m0_be_tx *ctx)
1037 {
1038  int rc;
1039  struct m0_cob *cob;
1040  struct m0_cob_nskey *nskey = NULL;
1041  struct m0_cob_nsrec nsrec = {};
1042 
1043  M0_PRE(cc != NULL);
1044  M0_PRE(cdom != NULL);
1045 
1046  rc = m0_cob_alloc(cdom, &cob);
1047  if (rc != 0)
1048  return M0_RC(rc);
1049 
1050  rc = cob_is_md(cc) ?
1051  cc_md_cob_nskey_make(&nskey, &cc->fco_gfid) :
1052  m0_cc_cob_nskey_make(&nskey, &cc->fco_gfid, cc->fco_cob_idx);
1053  if (rc != 0) {
1054  m0_cob_put(cob);
1055  return M0_RC(rc);
1056  }
1057 
1058  cob_fom_stob2fid_map(cc, &nsrec.cnr_fid);
1059  m0_cob_nsrec_init(&nsrec);
1060  nsrec.cnr_nlink = attr->ca_nlink;
1061  nsrec.cnr_size = attr->ca_size;
1062  nsrec.cnr_blksize = attr->ca_blksize;
1063  nsrec.cnr_blocks = attr->ca_blocks;
1064  nsrec.cnr_atime = attr->ca_atime;
1065  nsrec.cnr_mtime = attr->ca_mtime;
1066  nsrec.cnr_ctime = attr->ca_ctime;
1067  nsrec.cnr_lid = attr->ca_lid;
1068  nsrec.cnr_pver = attr->ca_pver;
1069 
1070  rc = m0_cob_create(cob, nskey, &nsrec, NULL, NULL, ctx);
1071  if (rc != 0) {
1072  /*
1073  * Cob does not free nskey and fab rec on errors. We need to do
1074  * so ourself. In case cob created successfully, it frees things
1075  * on last put.
1076  */
1077  m0_free(nskey);
1078  }
1079  m0_cob_put(cob);
1080 
1081  return M0_RC(rc);
1082 }
1083 
1084 static void cd_fom_fini(struct m0_fom *fom)
1085 {
1086  struct m0_fom_cob_op *cfom;
1087 
1088  M0_PRE(fom != NULL);
1089 
1090  cfom = cob_fom_get(fom);
1092  m0_indexvec_free(&cfom->fco_range);
1093  m0_indexvec_free(&cfom->fco_want);
1094  m0_indexvec_free(&cfom->fco_got);
1095  m0_fom_fini(fom);
1096  m0_free(cfom);
1097 }
1098 
1099 static void cob_getattr_fom_fini(struct m0_fom *fom)
1100 {
1101  struct m0_fom_cob_op *cfom;
1102  M0_PRE(fom != NULL);
1103 
1104  cfom = cob_fom_get(fom);
1105  m0_fom_fini(fom);
1106  m0_free(cfom);
1107 }
1108 
1109 static void cob_setattr_fom_fini(struct m0_fom *fom)
1110 {
1111  struct m0_fom_cob_op *cfom;
1112  M0_PRE(fom != NULL);
1113 
1114  cfom = cob_fom_get(fom);
1115  m0_fom_fini(fom);
1116  m0_free(cfom);
1117 }
1118 
1119 static int cd_cob_delete(struct m0_fom *fom,
1120  struct m0_fom_cob_op *cd,
1121  const struct m0_cob_attr *attr)
1122 {
1123  int rc;
1124  uint64_t byte_count;
1125  struct m0_fid pver;
1126  struct m0_cob *cob;
1127  struct m0_cob_bckey key;
1128 
1129  M0_PRE(fom != NULL);
1130  M0_PRE(cd != NULL);
1131 
1132  M0_LOG(M0_DEBUG, "Deleting cob for "FID_F"/%x",
1133  FID_P(&cd->fco_cfid), cd->fco_cob_idx);
1134 
1135  rc = cob_locate(fom, &cob);
1136  if (rc != 0)
1137  return M0_RC(rc);
1138 
1139  M0_ASSERT(cob != NULL);
1140 
1143 
1144  byte_count = cob->co_nsrec.cnr_bytecount;
1145 
1147  M0_ASSERT(attr->ca_nlink == 0);
1149 
1150  key.cbk_pfid = pver;
1151  key.cbk_user_id = M0_BYTECOUNT_USER_ID;
1152  rc = cob_bytecount_decrement(cob, &key, byte_count, m0_fom_tx(fom));
1153  if (rc != 0)
1154  M0_ERR_INFO(rc, "Bytecount decrement unsuccesfull");
1155 
1157  if (rc == 0)
1158  M0_LOG(M0_DEBUG, "Cob deleted successfully.");
1159 
1160  return M0_RC(rc);
1161 }
1162 
1164  struct m0_be_tx_credit *accum)
1165 {
1166  m0_stob_destroy_credit(cc->fco_stob, accum);
1167 }
1168 
1169 static int ce_stob_edit_credit(struct m0_fom *fom, struct m0_fom_cob_op *cc,
1170  struct m0_be_tx_credit *accum, uint32_t cot)
1171 {
1172  struct m0_stob *stob;
1173  int rc;
1174  uint32_t idx = cc->fco_range_idx;
1175 
1176  M0_PRE(M0_IN(cot, (M0_COB_OP_DELETE, M0_COB_OP_TRUNCATE)));
1177  stob = cc->fco_stob;
1178  M0_ASSERT(stob != NULL);
1180 
1181  cc->fco_want.iv_index[0] = cc->fco_range.iv_index[idx];
1182  cc->fco_want.iv_vec.v_count[0] = cc->fco_range.iv_vec.v_count[idx];
1183  rc = m0_stob_punch_credit(stob, &cc->fco_want, &cc->fco_got, accum);
1184  if (rc != 0)
1185  return M0_RC(rc);
1186 
1187  if (cot == M0_COB_OP_TRUNCATE) {
1188  cc->fco_range.iv_index[idx] += cc->fco_got.iv_vec.v_count[0];
1189  cc->fco_range.iv_vec.v_count[idx] -=
1190  cc->fco_got.iv_vec.v_count[0];
1191  if (cc->fco_range.iv_vec.v_count[idx] == 0) {
1192  cc->fco_range_idx++;
1193  if (cc->fco_range_idx == cc->fco_range.iv_vec.v_nr)
1194  cc->fco_is_done = true;
1195  }
1196  } else if (cc->fco_got.iv_vec.v_count[0] != M0_BINDEX_MAX + 1)
1197  rc = -EAGAIN;
1198 
1199  /* To update the cob size post truncate. */
1200  if (rc == 0)
1202 
1203  return M0_RC(rc);
1204 }
1205 
1206 static int ce_stob_edit(struct m0_fom *fom, struct m0_fom_cob_op *cd,
1207  uint32_t cot)
1208 {
1209  struct m0_storage_devs *devs = m0_cs_storage_devs_get();
1210  struct m0_stob *stob = cd->fco_stob;
1211  int rc;
1212 
1213  M0_PRE(M0_IN(cot, (M0_COB_OP_DELETE, M0_COB_OP_TRUNCATE)));
1214  M0_PRE(!cob_is_md(cd));
1215 
1216  M0_PRE(stob != NULL);
1218  cot == M0_COB_OP_DELETE),
1220  stob->so_ref == 1)));
1222  cot == M0_COB_OP_TRUNCATE &&
1223  stob->so_ref > 1),
1226  cot == M0_COB_OP_TRUNCATE &&
1227  stob->so_ref == 1),
1230  (cot == M0_COB_OP_TRUNCATE &&
1232 
1233  M0_ENTRY("fom %p, fom_type %d, cot %d, stob %p, "FID_F,
1234  fom, cd->fco_fop_type, cot, stob, FID_P(&stob->so_id.si_fid));
1235 
1236  rc = m0_stob_punch(stob, &cd->fco_got, &fom->fo_tx);
1237  if (rc != 0)
1238  return M0_ERR(rc);
1239 
1240  if (cot == M0_COB_OP_DELETE)
1241  rc = m0_storage_dev_stob_destroy(devs, stob, &fom->fo_tx);
1242 
1243  return M0_RC(rc);
1244 }
1245 
1246 static int cob_bytecount_decrement(struct m0_cob *cob, struct m0_cob_bckey *key,
1247  uint64_t bytecount, struct m0_be_tx *tx)
1248 {
1249  int rc;
1250  struct m0_cob_bcrec rec = {};
1251 
1252  M0_ENTRY();
1253 
1254  M0_PRE(key != NULL);
1255  if(!m0_fid_is_set(&key->cbk_pfid))
1256  return M0_ERR_INFO(-EINVAL, "Invalid Key");
1257 
1258  M0_LOG(M0_DEBUG, "KEY: "FID_F"/%" PRIu64, FID_P(&key->cbk_pfid), key->cbk_user_id);
1259 
1260  rc = m0_cob_bc_lookup(cob, key, &rec);
1261  if (rc == 0) {
1262  if (rec.cbr_bytecount < bytecount)
1263  rec.cbr_bytecount = 0;
1264  else
1265  rec.cbr_bytecount -= bytecount;
1266  rc = m0_cob_bc_update(cob, key, &rec, tx);
1267  if (rc != 0)
1268  return M0_ERR(rc);
1269  M0_LOG(M0_DEBUG, "Bytecount reduced by %" PRIu64
1270  " to %" PRIu64 , bytecount, rec.cbr_bytecount);
1271  } else
1272  M0_ERR(rc);
1273 
1274  return M0_RC(rc);
1275 }
1276 
1277 #undef M0_TRACE_SUBSYSTEM
1278 
1279 /*
1280  * Local variables:
1281  * c-indentation-style: "K&R"
1282  * c-basic-offset: 8
1283  * tab-width: 8
1284  * fill-column: 80
1285  * scroll-step: 1
1286  * End:
1287  */
struct m0_cob_nsrec co_nsrec
Definition: cob.h:590
static struct ctx cc
uint32_t b_nlink
Definition: md_fops.h:81
struct m0_fop_type m0_fop_cob_op_reply_fopt
Definition: io_fops.c:78
void m0_fom_phase_moveif(struct m0_fom *fom, int32_t rc, int phase0, int phase1)
Definition: fom.c:1710
uint32_t m0_fop_opcode(const struct m0_fop *fop)
Definition: fop.c:226
uint64_t c_flags
Definition: io_fops.h:477
uint64_t cnr_mtime
Definition: cob.h:435
M0_INTERNAL int m0_cc_cob_setup(struct m0_fom_cob_op *cc, struct m0_cob_domain *cdom, const struct m0_cob_attr *attr, struct m0_be_tx *ctx)
Definition: cob_foms.c:1033
#define M0_PRE(cond)
uint32_t cnr_nlink
Definition: cob.h:426
static int cob_locate(const struct m0_fom *fom, struct m0_cob **cob)
Definition: cob_foms.c:923
Definition: cob.h:581
struct m0_fop_type m0_fop_cob_setattr_reply_fopt
Definition: io_fops.c:84
M0_INTERNAL struct m0_fop_cob_common * m0_cobfop_common_get(struct m0_fop *fop)
Definition: io_fops.c:990
uint64_t cnr_size
Definition: cob.h:430
M0_INTERNAL int m0_indexvec_alloc(struct m0_indexvec *ivec, uint32_t len)
Definition: vec.c:532
static int cob_stob_create(struct m0_fom *fom, struct m0_cob_attr *attr)
Definition: cob_foms.c:511
M0_INTERNAL uint64_t m0_fid_hash(const struct m0_fid *fid)
Definition: fid.c:295
static const struct m0_fom_ops cd_fom_ops
Definition: cob_foms.c:121
#define NULL
Definition: misc.h:38
bool fco_recreate
Definition: cob_foms.h:68
cob_attr_operation
Definition: cob_foms.c:879
uint64_t co_flags
Definition: cob.h:585
#define ergo(a, b)
Definition: misc.h:293
uint64_t cnr_blocks
Definition: cob.h:433
M0_INTERNAL int m0_storage_dev_stob_find(struct m0_storage_devs *devs, struct m0_stob_id *sid, struct m0_stob **stob)
Definition: storage_dev.c:868
m0_be_tx_state
Definition: tx.h:214
Definition: sm.h:350
M0_INTERNAL void m0_storage_dev_stob_put(struct m0_storage_devs *devs, struct m0_stob *stob)
Definition: storage_dev.c:912
M0_INTERNAL bool m0_chan_has_waiters(struct m0_chan *chan)
Definition: chan.c:185
static struct m0_cob_domain * cdom_get(const struct m0_fom *fom)
Definition: cob_foms.c:834
#define M0_LOG(level,...)
Definition: trace.h:167
static struct m0_be_tx_credit * m0_fom_tx_credit(struct m0_fom *fom)
Definition: fom.h:542
static void cob_op_credit(struct m0_fom *fom, enum m0_cob_op opcode, struct m0_be_tx_credit *accum)
Definition: cob_foms.c:868
uint64_t cnr_blksize
Definition: cob.h:432
static int cob_stob_ref_drop_wait(struct m0_fom *fom)
Definition: cob_foms.c:559
uint64_t fco_flags
Definition: cob_foms.h:95
static bool cob_pool_version_mismatch(const struct m0_fom *fom)
Definition: cob_foms.c:480
int(* fto_create)(struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: fom.h:650
enum m0_cob_type fco_cob_type
Definition: cob_foms.h:64
static int cc_cob_create(struct m0_fom *fom, struct m0_fom_cob_op *cc, const struct m0_cob_attr *attr)
Definition: cob_foms.c:1014
M0_INTERNAL bool m0_is_cob_truncate_fop(const struct m0_fop *fop)
Definition: io_fops.c:964
struct m0_fop_cob_common cs_common
Definition: io_fops.h:280
M0_INTERNAL void m0_cob_put(struct m0_cob *cob)
Definition: cob.c:1095
static void cob_tick_tail(struct m0_fom *fom, struct m0_fop_cob_op_rep_common *r_common)
Definition: cob_foms.c:348
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 m0_indexvec_free(struct m0_indexvec *ivec)
Definition: vec.c:553
struct m0_reqh_service rios_gen
Definition: io_service.h:96
uint64_t cnr_atime
Definition: cob.h:434
static int cob_attr_op(struct m0_fom *fom, struct m0_fom_cob_op *gop, struct m0_cob_attr *attr, enum cob_attr_operation op)
Definition: cob_foms.c:944
M0_INTERNAL void m0_md_cob_wire2mem(struct m0_cob_attr *attr, const struct m0_fop_cob *body)
Definition: md_foms.c:53
uint32_t fco_cob_idx
Definition: cob_foms.h:62
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
struct m0_fid c_cobfid
Definition: io_fops.h:465
M0_INTERNAL void m0_chan_lock(struct m0_chan *ch)
Definition: chan.c:68
#define container_of(ptr, type, member)
Definition: misc.h:33
#define M0_SET0(obj)
Definition: misc.h:64
uint32_t ci_nr
Definition: vec.h:635
M0_ADDB2_ADD(M0_AVI_FS_CREATE, new_fid.f_container, new_fid.f_key, mode, rc)
static void addb2_add_cob_fom_attrs(const struct m0_fom_cob_op *cfom)
Definition: cob_foms.c:162
M0_INTERNAL bool m0_fid_is_set(const struct m0_fid *fid)
Definition: fid.c:106
static struct m0_cob_domain * cdom
Definition: xform.c:55
m0_cob_op
Definition: cob.h:1068
m0_fom_phase
Definition: fom.h:372
struct m0_fid fco_gfid
Definition: cob_foms.h:58
static struct m0_be_tx * m0_fom_tx(struct m0_fom *fom)
Definition: fom.h:537
struct m0_indexvec fco_range
Definition: cob_foms.h:75
struct m0_fom_type ft_fom_type
Definition: fop.h:232
struct m0_stob * fco_stob
Definition: cob_foms.h:65
const struct m0_fom_type * fo_type
Definition: dump.c:107
M0_INTERNAL int m0_cob_nskey_make(struct m0_cob_nskey **keyh, const struct m0_fid *pfid, const char *name, size_t namelen)
Definition: cob.c:148
static const struct m0_fom_ops cob_getattr_fom_ops
Definition: cob_foms.c:135
struct m0_fid fid
Definition: di.c:46
struct m0_vec iv_vec
Definition: vec.h:139
return M0_RC(rc)
op
Definition: libdemo.c:64
M0_INTERNAL void m0_cob_tx_credit(struct m0_cob_domain *dom, enum m0_cob_op optype, struct m0_be_tx_credit *accum)
Definition: cob.c:2281
static int cc_md_cob_nskey_make(struct m0_cob_nskey **nskey, const struct m0_fid *gfid)
Definition: cob_foms.c:860
M0_INTERNAL uint32_t m0_stob_block_shift(struct m0_stob *stob)
Definition: stob.c:270
bool fco_is_done
Definition: cob_foms.h:66
#define M0_ENTRY(...)
Definition: trace.h:170
struct m0_cob_nskey * co_nskey
Definition: cob.h:588
m0_bindex_t * iv_index
Definition: vec.h:141
int opcode
Definition: crate.c:301
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
static int cob_setattr_fom_tick(struct m0_fom *fom)
Definition: cob_foms.c:414
struct m0_fop_type * f_type
Definition: fop.h:81
#define PRIu64
Definition: types.h:58
M0_INTERNAL bool m0_is_cob_setattr_fop(const struct m0_fop *fop)
Definition: io_fops.c:978
struct m0_fop_type m0_fop_cob_getattr_reply_fopt
Definition: io_fops.c:81
const struct m0_fom_type_ops cob_fom_type_ops
Definition: cob_foms.c:109
#define M0_ERR_INFO(rc, fmt,...)
Definition: trace.h:215
M0_INTERNAL int m0_cob_fom_create(struct m0_fop *fop, struct m0_fom **out, struct m0_reqh *reqh)
Definition: cob_foms.c:183
struct m0_fom fco_fom
Definition: cob_foms.h:54
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL const char * m0_fop_name(const struct m0_fop *fop)
Definition: fop.c:55
M0_INTERNAL int m0_cob_bc_update(struct m0_cob *cob, struct m0_cob_bckey *bc_key, struct m0_cob_bcrec *bc_val, struct m0_be_tx *tx)
Definition: cob.c:1161
static int cob_getattr(struct m0_fom *fom, struct m0_fom_cob_op *gop, struct m0_cob_attr *attr)
Definition: cob_foms.c:1000
static int ce_stob_edit_credit(struct m0_fom *fom, struct m0_fom_cob_op *cc, struct m0_be_tx_credit *accum, uint32_t cot)
Definition: cob_foms.c:1169
M0_INTERNAL uint64_t m0_rnd(uint64_t max, uint64_t *seed)
Definition: misc.c:115
struct m0_cob_domain * rios_cdom
Definition: io_service.h:100
static int cob_bytecount_decrement(struct m0_cob *cob, struct m0_cob_bckey *key, uint64_t bytecount, struct m0_be_tx *tx)
Definition: cob_foms.c:1246
static void attr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:949
Definition: stob.h:163
int m0_fom_tick_generic(struct m0_fom *fom)
Definition: fom_generic.c:848
static int cob_getattr_fom_tick(struct m0_fom *fom)
Definition: cob_foms.c:358
void m0_fom_fini(struct m0_fom *fom)
Definition: fom.c:1324
static struct m0_stob * stob
Definition: storage.c:39
static void cob_stob_create_credit(struct m0_fom *fom)
Definition: cob_foms.c:498
static int cob_ops_stob_find(struct m0_fom_cob_op *co)
Definition: cob_foms.c:335
static struct m0_cob * cob
Definition: bytecount.c:40
#define M0_ASSERT(cond)
const char * scf_name
Definition: sm.h:352
struct m0_fid pver
Definition: idx_dix.c:74
M0_INTERNAL void m0_stob_destroy_credit(struct m0_stob *stob, struct m0_be_tx_credit *accum)
Definition: stob.c:187
M0_INTERNAL int m0_storage_dev_stob_destroy(struct m0_storage_devs *devs, struct m0_stob *stob, struct m0_dtx *dtx)
Definition: storage_dev.c:836
uint32_t c_cob_idx
Definition: io_fops.h:471
M0_INTERNAL void m0_cob_nsrec_init(struct m0_cob_nsrec *nsrec)
Definition: cob.c:2058
M0_INTERNAL void m0_md_cob_mem2wire(struct m0_fop_cob *body, const struct m0_cob_attr *attr)
Definition: md_foms.c:89
void m0_fom_phase_move(struct m0_fom *fom, int32_t rc, int phase)
Definition: fom.c:1699
M0_INTERNAL void m0_cob_oikey_make(struct m0_cob_oikey *oikey, const struct m0_fid *fid, int linkno)
Definition: cob.c:141
M0_INTERNAL void m0_be_tx_credit_add(struct m0_be_tx_credit *c0, const struct m0_be_tx_credit *c1)
Definition: tx_credit.c:44
M0_INTERNAL void m0_fid_convert_cob2stob(const struct m0_fid *cob_fid, struct m0_stob_id *stob_id)
Definition: fid_convert.c:141
M0_INTERNAL int m0_indexvec_wire2mem(struct m0_io_indexvec *wire_ivec, int max_frags_nr, uint32_t bshift, struct m0_indexvec *mem_ivec)
Definition: vec.c:1058
M0_INTERNAL int m0_cob_create(struct m0_cob *cob, struct m0_cob_nskey *nskey, struct m0_cob_nsrec *nsrec, struct m0_cob_fabrec *fabrec, struct m0_cob_omgrec *omgrec, struct m0_be_tx *tx)
Definition: cob.c:1681
static const struct m0_fom_ops cob_setattr_fom_ops
Definition: cob_foms.c:142
M0_INTERNAL void m0_fom_mod_rep_fill(struct m0_fop_mod_rep *rep, struct m0_fom *fom)
Definition: fom_generic.c:68
const struct m0_sm_conf cob_ops_conf
Definition: cob_foms.c:99
struct m0_fid si_fid
Definition: stob.h:105
static int ce_stob_edit(struct m0_fom *fom, struct m0_fom_cob_op *cd, uint32_t cot)
Definition: cob_foms.c:1206
static void cd_fom_fini(struct m0_fom *fom)
Definition: cob_foms.c:1084
uint32_t cor_mode
Definition: cob.h:498
static void cc_fom_fini(struct m0_fom *fom)
Definition: cob_foms.c:259
struct m0_chan so_ref_chan
Definition: stob.h:170
struct m0_fid c_gobfid
Definition: io_fops.h:460
uint32_t cor_uid
Definition: cob.h:497
static int cob_ops_fom_tick(struct m0_fom *fom)
Definition: cob_foms.c:576
M0_INTERNAL int m0_fom_tx_done_wait(struct m0_fom *fom)
Definition: fom_generic.c:490
struct m0_fid b_pver
Definition: md_fops.h:93
uint64_t f_container
Definition: fid.h:39
M0_INTERNAL int m0_cc_stob_create(struct m0_fom *fom, struct m0_stob_id *sid)
Definition: cob_foms.c:824
Definition: reqh.h:94
static void ce_stob_destroy_credit(struct m0_fom_cob_op *cob_op, struct m0_be_tx_credit *accum)
Definition: cob_foms.c:1163
Definition: dump.c:103
static void cob_getattr_fom_fini(struct m0_fom *fom)
Definition: cob_foms.c:1099
m0_bcount_t * v_count
Definition: vec.h:53
uint64_t so_ref
Definition: stob.h:168
struct m0_sm t_sm
Definition: tx.h:281
struct m0_io_indexvec ct_io_ivec
Definition: io_fops.h:509
static void cob_fom_stob2fid_map(const struct m0_fom_cob_op *cfom, struct m0_fid *out)
Definition: cob_foms.c:153
#define FID_P(f)
Definition: fid.h:77
M0_INTERNAL struct m0_storage_devs * m0_cs_storage_devs_get(void)
Definition: setup.c:1783
struct m0_sm_state_descr cob_ops_phases[]
Definition: cob_foms.c:86
M0_INTERNAL void m0_chan_unlock(struct m0_chan *ch)
Definition: chan.c:73
M0_INTERNAL struct m0_stob_domain * m0_stob_domain_find_by_stob_id(const struct m0_stob_id *stob_id)
Definition: domain.c:294
M0_INTERNAL bool m0_is_cob_create_fop(const struct m0_fop *fop)
Definition: io_fops.c:950
static int cd_cob_delete(struct m0_fom *fom, struct m0_fom_cob_op *cd, const struct m0_cob_attr *attr)
Definition: cob_foms.c:1119
struct m0_indexvec fco_want
Definition: cob_foms.h:81
struct m0_fop * m0_fop_reply_alloc(struct m0_fop *req, struct m0_fop_type *rept)
Definition: fop.c:129
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
M0_INTERNAL int m0_stob_punch_credit(struct m0_stob *stob, struct m0_indexvec *want, struct m0_indexvec *got, struct m0_be_tx_credit *accum)
Definition: stob.c:223
Definition: fom.h:481
M0_INTERNAL enum m0_stob_state m0_stob_state_get(struct m0_stob *stob)
Definition: stob.c:265
struct m0_reqh reqh
Definition: rm_foms.c:48
const char * sd_name
Definition: sm.h:383
struct m0_fid cnr_pver
Definition: cob.h:438
Definition: stob.h:91
static void cob_setattr_fom_fini(struct m0_fom *fom)
Definition: cob_foms.c:1109
#define M0_CNT_INC(cnt)
Definition: arith.h:226
Definition: fid.h:38
#define M0_BYTECOUNT_USER_ID
Definition: io_service.h:72
uint64_t f_key
Definition: fid.h:40
uint64_t cbr_bytecount
Definition: cob.h:522
static size_t cob_fom_locality_get(const struct m0_fom *fom)
Definition: cob_foms.c:278
M0_INTERNAL int m0_cob_bc_lookup(struct m0_cob *cob, struct m0_cob_bckey *bc_key, struct m0_cob_bcrec *bc_rec)
Definition: cob.c:1120
M0_INTERNAL size_t m0_cob_io_fom_locality(const struct m0_fid *fid)
Definition: cob_foms.c:271
struct m0_stob_id fco_stob_id
Definition: cob_foms.h:52
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
struct m0_chan sm_chan
Definition: sm.h:331
M0_INTERNAL int m0_storage_dev_stob_create(struct m0_storage_devs *devs, struct m0_stob_id *sid, struct m0_dtx *dtx)
Definition: storage_dev.c:810
struct m0_indexvec fco_got
Definition: cob_foms.h:91
uint32_t fco_range_idx
Definition: cob_foms.h:86
M0_INTERNAL int m0_fom_rc(const struct m0_fom *fom)
Definition: fom.c:1727
struct m0_rpc_item * m0_fop_to_rpc_item(const struct m0_fop *fop)
Definition: fop.c:338
M0_INTERNAL bool m0_be_should_break(struct m0_be_engine *eng, const struct m0_be_tx_credit *accum, const struct m0_be_tx_credit *delta)
Definition: tx.c:714
M0_INTERNAL int m0_cc_stob_cr_credit(struct m0_stob_id *sid, struct m0_be_tx_credit *accum)
Definition: cob_foms.c:807
struct m0_fop_mod_rep cor_mod_rep
Definition: io_fops.h:518
static struct m0_fop * fop
Definition: item.c:57
static const struct m0_fom_ops ct_fom_ops
Definition: cob_foms.c:128
static bool cob_is_md(const struct m0_fom_cob_op *cfom)
Definition: cob_foms.c:148
struct m0_cob_omgrec co_omgrec
Definition: cob.h:592
M0_INTERNAL int m0_cob_delete(struct m0_cob *cob, struct m0_be_tx *tx)
Definition: cob.c:1789
M0_INTERNAL int m0_cob_locate(struct m0_cob_domain *dom, struct m0_cob_oikey *oikey, uint64_t flags, struct m0_cob **out)
Definition: cob.c:1407
M0_INTERNAL int m0_cob_setattr(struct m0_cob *cob, struct m0_cob_attr *attr, struct m0_be_tx *tx)
Definition: cob.c:2068
#define M0_CNT_DEC(cnt)
Definition: arith.h:219
static int cob_fom_populate(struct m0_fom *fom)
Definition: cob_foms.c:285
void(* fo_fini)(struct m0_fom *fom)
Definition: fom.h:657
static int cob_stob_delete_credit(struct m0_fom *fom)
Definition: cob_foms.c:522
enum m0_cob_op fco_fop_type
Definition: cob_foms.h:67
M0_INTERNAL bool m0_is_cob_getattr_fop(const struct m0_fop *fop)
Definition: io_fops.c:971
static int cob_attr_get(struct m0_cob *cob, struct m0_cob_attr *attr)
Definition: cob_foms.c:884
M0_INTERNAL void m0_stob_delete_mark(struct m0_stob *stob)
Definition: stob.c:193
M0_INTERNAL int m0_cob_alloc(struct m0_cob_domain *dom, struct m0_cob **out)
Definition: cob.c:1100
Definition: nucleus.c:42
uint64_t ct_size
Definition: io_fops.h:507
#define out(...)
Definition: gen.c:41
M0_INTERNAL int m0_stob_punch(struct m0_stob *stob, struct m0_indexvec *range, struct m0_dtx *dtx)
Definition: stob.c:232
M0_INTERNAL void m0_stob_create_credit(struct m0_stob_domain *dom, struct m0_be_tx_credit *accum)
Definition: stob.c:148
M0_INTERNAL bool m0_is_cob_delete_fop(const struct m0_fop *fop)
Definition: io_fops.c:957
void m0_fom_phase_set(struct m0_fom *fom, int phase)
Definition: fom.c:1688
struct m0_fid gfid
Definition: dir.c:626
static const struct m0_fom_ops cc_fom_ops
Definition: cob_foms.c:114
uint32_t cor_gid
Definition: cob.h:499
static int cob_op_fom_create(struct m0_fom **out)
Definition: cob_foms.c:238
M0_INTERNAL bool m0_fid_is_valid(const struct m0_fid *fid)
Definition: fid.c:96
struct m0_fom_ops ops
Definition: io_foms.c:623
M0_INTERNAL void m0_dump_cob_attr(const struct m0_cob_attr *attr)
Definition: io_fops.c:132
static struct m0_dtm_oper_descr reply
Definition: transmit.c:94
M0_INTERNAL uint64_t m0_sm_id_get(const struct m0_sm *sm)
Definition: sm.c:1021
static struct m0_fom_cob_op * cob_fom_get(const struct m0_fom *fom)
Definition: cob_foms.c:252
uint64_t cnr_ctime
Definition: cob.h:436
void m0_free(void *data)
Definition: memory.c:146
M0_INTERNAL void m0_fid_convert_stob2cob(const struct m0_stob_id *stob_id, struct m0_fid *cob_fid)
Definition: fid_convert.c:152
struct m0_fop_cob c_body
Definition: io_fops.h:456
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
struct m0_stob_id so_id
Definition: stob.h:166
struct m0_fid cnk_pfid
Definition: cob.h:391
fop_type
Definition: stats_ut_svc.c:51
Definition: fop.h:79
uint64_t cnr_lid
Definition: cob.h:437
#define FID_F
Definition: fid.h:75
static int tail(struct m0_sm *mach)
Definition: sm.c:474
M0_INTERNAL int m0_cc_cob_nskey_make(struct m0_cob_nskey **nskey, const struct m0_fid *gfid, uint32_t cob_idx)
Definition: cob_foms.c:846
uint64_t cnr_bytecount
Definition: cob.h:431
Definition: tx.h:280
struct m0_fid fco_cfid
Definition: cob_foms.h:60
Definition: idx_mock.c:47
static struct m0_stob_domain * sdom
Definition: reqh_fom_ut.c:73
M0_INTERNAL const char * m0_fom_phase_name(const struct m0_fom *fom, int phase)
Definition: fom.c:1722
#define M0_IMPOSSIBLE(fmt,...)
struct m0_fid cnr_fid
Definition: cob.h:419
static int cob_setattr(struct m0_fom *fom, struct m0_fom_cob_op *gop, struct m0_cob_attr *attr)
Definition: cob_foms.c:1007