Motr  M0
cob.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2020 Seagate Technology LLC and/or its Affiliates
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * For any questions about this software or licensing,
17  * please email opensource@seagate.com or cortx-questions@seagate.com.
18  *
19  */
20 
21 
22 #include "fid/fid.h"
23 
24 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_COB
25 #include "lib/trace.h"
26 
27 #define M0_COB_KEY_LOG(logger, fmt, key, fid_member, str_member, ...) \
28  M0_ ## logger (fmt, (long)(key)->fid_member.f_container, \
29  (long)(key)->fid_member.f_key, \
30  m0_bitstring_len_get(&((key)->str_member)), \
31  (char *)m0_bitstring_buf_get(&((key)->str_member)), \
32  ## __VA_ARGS__)
33 #define M0_COB_NSKEY_LOG(logger, fmt, key, ...)\
34  M0_COB_KEY_LOG(logger, fmt, key, cnk_pfid, cnk_name, ## __VA_ARGS__)
35 
36 #include "lib/misc.h" /* M0_SET0 */
37 #include "lib/arith.h" /* M0_3WAY */
38 #include "lib/errno.h"
39 #include "lib/assert.h"
40 #include "lib/memory.h"
41 #include "lib/bitstring.h"
42 #include "lib/locality.h"
43 
44 #include "cob/cob.h"
45 
46 #include "be/domain.h"
47 #include "be/btree.h"
48 #include "be/seg0.h"
49 #include "be/tx.h"
50 
51 #include "module/instance.h"
52 #include "reqh/reqh_service.h"
53 #include "reqh/reqh.h"
54 
55 #include "format/format.h" /* m0_format_footer_update */
56 
62 /*
63  * TODO: Move m0_be_tx_init() out of create/destroy functions and let user
64  * control tx. This will simplify respective interfaces.
65  */
66 
67 enum {
70 };
71 
72 static int cob0_init(struct m0_be_domain *dom, const char *suffix,
73  const struct m0_buf *data)
74 {
75  struct m0_cob_domain *cdom = *(struct m0_cob_domain**)data->b_addr;
76  struct m0_reqh *reqh = dom->bd_cfg.bc_engine.bec_reqh;
77  unsigned key;
78 
79  M0_ENTRY("suffix: %s, data: %p, cdom: %p", suffix, data->b_addr, cdom);
80 
81  /* @todo:
82  * The following code is a workaround until full-scale m0mkfs is ready.
83  * It's planned to put cob-domains inside rehq_{io, mds, ..}_services.
84  *
85  * During mkfs phase, rehq_{io, mds, ..}_services have to be allocated
86  * with service_ops->rsto_service_allocate(). Identifiers of the service
87  * and cob-domain will be the same: cob-domain will take the id of the
88  * containing service.
89  *
90  * During reload phase cob_0type->b0_init() will initialize the
91  * corresponding cob domain and {io, mds, ...}srv_0type->b0_init()
92  * will initialise containing service.
93  */
94 
97 
98  if (m0_reqh_lockers_get(reqh, key) == NULL)
99  m0_reqh_lockers_set(reqh, key, cdom);
100 
101  return M0_RC(0);
102 }
103 
104 static void cob0_fini(struct m0_be_domain *dom, const char *suffix,
105  const struct m0_buf *data)
106 {
107  M0_ENTRY();
108  M0_LEAVE();
109 }
110 
112  .b0_name = "M0_BE:COB",
113  .b0_init = cob0_init,
114  .b0_fini = cob0_fini,
115 };
116 
117 const struct m0_fid_type m0_cob_fid_type = {
118  .ft_id = 'C',
119  .ft_name = "cob fid"
120 };
121 
122 M0_INTERNAL const struct m0_fid *m0_cob_fid(const struct m0_cob *cob)
123 {
124  M0_PRE(cob != NULL);
125 
126  return cob->co_file.fi_fid;
127 }
128 
129 M0_INTERNAL int m0_cob_mod_init(void)
130 {
132  return 0;
133 }
134 
135 M0_INTERNAL void m0_cob_mod_fini(void)
136 {
138 }
139 
140 #ifndef __KERNEL__
141 M0_INTERNAL void m0_cob_oikey_make(struct m0_cob_oikey *oikey,
142  const struct m0_fid *fid, int linkno)
143 {
144  oikey->cok_fid = *fid;
145  oikey->cok_linkno = linkno;
146 }
147 
148 M0_INTERNAL int m0_cob_nskey_make(struct m0_cob_nskey **keyh,
149  const struct m0_fid *pfid,
150  const char *name, size_t namelen)
151 {
152  struct m0_cob_nskey *key;
153 
154  key = m0_alloc(sizeof *key + namelen);
155  if (key == NULL)
156  return M0_ERR(-ENOMEM);
157  key->cnk_pfid = *pfid;
158  m0_bitstring_copy(&key->cnk_name, name, namelen);
159  *keyh = key;
160  return 0;
161 }
162 
163 M0_INTERNAL int m0_cob_nskey_cmp(const struct m0_cob_nskey *k0,
164  const struct m0_cob_nskey *k1)
165 {
166  int rc;
167 
168  M0_PRE(m0_fid_is_set(&k0->cnk_pfid));
169  M0_PRE(m0_fid_is_set(&k1->cnk_pfid));
170 
171  rc = m0_fid_cmp(&k0->cnk_pfid, &k1->cnk_pfid);
172  return rc ?: m0_bitstring_cmp(&k0->cnk_name, &k1->cnk_name);
173 }
174 
175 M0_INTERNAL size_t m0_cob_nskey_size(const struct m0_cob_nskey *cnk)
176 {
177  return sizeof *cnk +
179 }
180 
181 M0_INTERNAL int m0_cob_eakey_make(struct m0_cob_eakey **keyh,
182  const struct m0_fid *fid,
183  const char *name, size_t namelen)
184 {
185  struct m0_cob_eakey *key;
186 
187  key = m0_alloc(sizeof *key + namelen);
188  if (key == NULL)
189  return M0_ERR(-ENOMEM);
190  key->cek_fid = *fid;
191  m0_bitstring_copy(&key->cek_name, name, namelen);
192  *keyh = key;
193  return 0;
194 }
195 
199 static int m0_cob_max_eakey_make(struct m0_cob_eakey **keyh,
200  const struct m0_fid *fid,
201  const char *name,
202  int namelen)
203 {
204  struct m0_cob_eakey *key;
205 
206  key = m0_alloc(sizeof *key + M0_COB_NAME_MAX);
207  if (key == NULL)
208  return M0_ERR(-ENOMEM);
209  key->cek_fid = *fid;
210  m0_bitstring_copy(&key->cek_name, name, namelen);
211  *keyh = key;
212  return 0;
213 }
214 
215 M0_INTERNAL int m0_cob_eakey_cmp(const struct m0_cob_eakey *k0,
216  const struct m0_cob_eakey *k1)
217 {
218  int rc;
219 
220  M0_PRE(m0_fid_is_set(&k0->cek_fid));
221  M0_PRE(m0_fid_is_set(&k1->cek_fid));
222 
223  rc = m0_fid_cmp(&k0->cek_fid, &k1->cek_fid);
224  return rc ?: m0_bitstring_cmp(&k0->cek_name, &k1->cek_name);
225 }
226 
227 M0_INTERNAL size_t m0_cob_eakey_size(const struct m0_cob_eakey *cek)
228 {
229  return sizeof *cek +
231 }
232 
233 static size_t m0_cob_earec_size(const struct m0_cob_earec *rec)
234 {
235  return sizeof *rec + rec->cer_size;
236 }
237 
241 M0_INTERNAL size_t m0_cob_max_earec_size(void)
242 {
243  return sizeof(struct m0_cob_earec) + M0_COB_EA_MAX;
244 }
245 
249 static size_t m0_cob_max_eakey_size(void)
250 {
251  return sizeof(struct m0_cob_eakey) + M0_COB_NAME_MAX;
252 }
253 
257 static size_t m0_cob_fabrec_size(const struct m0_cob_fabrec *rec)
258 {
259  return sizeof *rec + rec->cfb_linklen;
260 }
261 
262 M0_INTERNAL int m0_cob_fabrec_make(struct m0_cob_fabrec **rech,
263  const char *link, size_t linklen)
264 {
265  struct m0_cob_fabrec *rec;
266 
267  rec = m0_alloc(sizeof(struct m0_cob_fabrec) + linklen);
268  if (rec == NULL)
269  return M0_ERR(-ENOMEM);
270  rec->cfb_linklen = linklen;
271  if (linklen > 0)
272  memcpy(rec->cfb_link, link, linklen);
273  *rech = rec;
274  return 0;
275 }
276 
280 static size_t m0_cob_max_fabrec_size(void)
281 {
282  return sizeof(struct m0_cob_fabrec) + M0_COB_NAME_MAX;
283 }
284 
288 static int m0_cob_max_fabrec_make(struct m0_cob_fabrec **rech)
289 {
290  struct m0_cob_fabrec *rec;
291 
293  if (rec == NULL)
294  return M0_ERR(-ENOMEM);
296  *rech = rec;
297  return 0;
298 }
299 
303 static int m0_cob_max_nskey_make(struct m0_cob_nskey **keyh,
304  const struct m0_fid *pfid,
305  const char *name,
306  int namelen)
307 {
308  struct m0_cob_nskey *key;
309 
310  key = m0_alloc(sizeof *key + M0_COB_NAME_MAX);
311  if (key == NULL)
312  return M0_ERR(-ENOMEM);
313  key->cnk_pfid = *pfid;
314  m0_bitstring_copy(&key->cnk_name, name, namelen);
315  *keyh = key;
316  return 0;
317 }
318 
324 static size_t m0_cob_max_nskey_size(void)
325 {
326  return sizeof(struct m0_cob_nskey) + M0_COB_NAME_MAX;
327 }
328 
332 static int ns_cmp(const void *key0, const void *key1)
333 {
334  return m0_cob_nskey_cmp((const struct m0_cob_nskey *)key0,
335  (const struct m0_cob_nskey *)key1);
336 }
337 
338 static m0_bcount_t ns_ksize(const void *key)
339 {
340  return m0_cob_nskey_size(key);
341 }
342 
343 static m0_bcount_t ns_vsize(const void *val)
344 {
345  return sizeof(struct m0_cob_nsrec);
346 }
347 
348 static const struct m0_be_btree_kv_ops cob_ns_ops = {
350  .ko_ksize = ns_ksize,
351  .ko_vsize = ns_vsize,
352  .ko_compare = ns_cmp
353 };
354 
358 static size_t m0_cob_bckey_size(void)
359 {
360  return sizeof(struct m0_cob_bckey);
361 }
362 
366 static size_t m0_cob_bcrec_size(void)
367 {
368  return sizeof(struct m0_cob_bcrec);
369 }
370 
371 static m0_bcount_t bc_ksize(const void *key)
372 {
373  return sizeof(struct m0_cob_bckey);
374 }
375 
376 static m0_bcount_t bc_vsize(const void *val)
377 {
378  return sizeof(struct m0_cob_bcrec);
379 }
380 
384 static int m0_cob_bckey_make(struct m0_cob_bckey **keyh,
385  const struct m0_fid *pver_fid,
386  uint64_t user_id)
387 {
388  struct m0_cob_bckey *key;
389 
391  if (key == NULL)
392  return M0_ERR(-ENOMEM);
393  key->cbk_pfid = *pver_fid;
394  key->cbk_user_id = user_id;
395  *keyh = key;
396  return 0;
397 }
398 
399 M0_INTERNAL int m0_cob_bckey_cmp(const struct m0_cob_bckey *k0,
400  const struct m0_cob_bckey *k1)
401 {
402  int rc;
403 
404  M0_PRE(m0_fid_is_set(&k0->cbk_pfid));
405  M0_PRE(m0_fid_is_set(&k1->cbk_pfid));
406 
407  rc = m0_fid_cmp(&k0->cbk_pfid, &k1->cbk_pfid);
408  return rc ?: k0->cbk_user_id == k1->cbk_user_id ? 0 : -EINVAL;
409 }
410 
414 static int bc_cmp(const void *key0, const void *key1)
415 {
416  return m0_cob_bckey_cmp((const struct m0_cob_bckey *)key0,
417  (const struct m0_cob_bckey *)key1);
418 }
419 
420 M0_INTERNAL int m0_cob_bc_iterator_init(struct m0_cob *cob,
421  struct m0_cob_bc_iterator *it,
422  const struct m0_fid *pver_fid,
423  uint64_t user_id)
424 {
425  int rc;
426 
427  /* Prepare entry key using passed started position. */
428  rc = m0_cob_bckey_make(&it->ci_key, pver_fid, user_id);
429  if (rc != 0)
430  return M0_RC(rc);
431 
432  it->ci_rec = m0_alloc(m0_cob_bcrec_size());
433  if (it->ci_rec == NULL) {
434  m0_free(it->ci_key);
435  return M0_RC(rc);
436  }
437 
439  it->ci_cob = cob;
440  return M0_RC(rc);
441 }
442 
444 {
445  struct m0_cob_bckey *bckey;
446  struct m0_cob_bcrec *bcrec;
447  struct m0_buf key;
448  struct m0_buf val;
449  int rc;
450 
451  m0_buf_init(&key, it->ci_key, m0_cob_bckey_size());
452  m0_buf_init(&val, it->ci_rec, m0_cob_bcrec_size());
453  rc = m0_be_btree_cursor_get_sync(&it->ci_cursor, &key, true);
454  if (rc == 0) {
455  m0_be_btree_cursor_kv_get(&it->ci_cursor, &key, &val);
456  bckey = (struct m0_cob_bckey *)key.b_addr;
457  bcrec = (struct m0_cob_bcrec *)val.b_addr;
458 
459  M0_ASSERT(sizeof(bckey) <= m0_cob_bckey_size());
460  M0_ASSERT(sizeof(bcrec) <= m0_cob_bcrec_size());
461  memcpy(it->ci_key, bckey, m0_cob_bckey_size());
462  memcpy(it->ci_rec, bcrec, m0_cob_bcrec_size());
463  }
464  return M0_RC(rc);
465 }
466 
468 {
469  struct m0_cob_bckey *bckey;
470  struct m0_cob_bcrec *bcrec;
471  struct m0_buf key;
472  struct m0_buf val;
473  int rc;
474 
475  rc = m0_be_btree_cursor_next_sync(&it->ci_cursor);
476  if (rc == 0) {
477  m0_be_btree_cursor_kv_get(&it->ci_cursor, &key, &val);
478  bckey = (struct m0_cob_bckey *)key.b_addr;
479  bcrec = (struct m0_cob_bcrec *)val.b_addr;
480 
481  M0_ASSERT(sizeof(bckey) <= m0_cob_bckey_size());
482  M0_ASSERT(sizeof(bcrec) <= m0_cob_bcrec_size());
483  memcpy(it->ci_key, bckey, m0_cob_bckey_size());
484  memcpy(it->ci_rec, bcrec, m0_cob_bcrec_size());
485  }
486  return M0_RC(rc);
487 }
488 
490 {
491  m0_be_btree_cursor_fini(&it->ci_cursor);
492  m0_free(it->ci_key);
493  m0_free(it->ci_rec);
494 }
495 
496 M0_INTERNAL int m0_cob_bc_entries_dump(struct m0_cob_domain *cdom,
497  struct m0_buf **out_keys,
498  struct m0_buf **out_recs,
499  uint32_t *out_count)
500 {
501  struct m0_cob_bc_iterator it;
502  struct m0_buf key_buf;
503  struct m0_buf rec_buf;
504  struct m0_cob_bckey *key_cursor;
505  struct m0_cob_bcrec *rec_cursor;
506  int rc;
507 
508  M0_ENTRY();
509 
510  M0_PRE(*out_keys == NULL);
511  M0_PRE(*out_recs == NULL);
512 
513  if (cdom->cd_bytecount.bb_root == NULL)
514  return M0_ERR(-ENOENT);
515 
516  *out_count = 0;
518  rc = m0_be_btree_cursor_first_sync(&it.ci_cursor);
519 
520  while (rc != -ENOENT) {
521  rc = m0_be_btree_cursor_next_sync(&it.ci_cursor);
522  ++(*out_count);
523  }
524 
525  M0_LOG(M0_DEBUG, "Found %" PRIu32 " entries in btree", *out_count);
526 
527  M0_ALLOC_PTR(*out_keys);
528  if (*out_keys == NULL)
529  return M0_ERR(-ENOMEM);
530  M0_ALLOC_PTR(*out_recs);
531  if (*out_recs == NULL) {
532  m0_free(*out_keys);
533  return M0_ERR(-ENOMEM);
534  }
535 
536  rc = m0_buf_alloc(*out_keys, sizeof(struct m0_cob_bckey) *
537  (*out_count));
538  if (rc != 0) {
539  m0_free(*out_keys);
540  m0_free(*out_recs);
541  return M0_ERR(rc);
542  }
543  rc = m0_buf_alloc(*out_recs, sizeof(struct m0_cob_bcrec) *
544  (*out_count));
545  if (rc != 0) {
546  m0_buf_free(*out_keys);
547  m0_free(*out_keys);
548  m0_free(*out_recs);
549  return M0_ERR(rc);
550  }
551 
552  key_cursor = (struct m0_cob_bckey *)(*out_keys)->b_addr;
553  rec_cursor = (struct m0_cob_bcrec *)(*out_recs)->b_addr;
554 
555  rc = m0_be_btree_cursor_first_sync(&it.ci_cursor);
556 
561  while (rc != -ENOENT) {
562  m0_be_btree_cursor_kv_get(&it.ci_cursor, &key_buf, &rec_buf);
563 
564  memcpy(key_cursor, key_buf.b_addr, key_buf.b_nob);
565  memcpy(rec_cursor, rec_buf.b_addr, rec_buf.b_nob);
566  key_cursor++;
567  rec_cursor++;
568 
569  rc = m0_be_btree_cursor_next_sync(&it.ci_cursor);
570  }
571 
572  m0_be_btree_cursor_fini(&it.ci_cursor);
573 
574  return M0_RC(0);
575 }
576 
577 static const struct m0_be_btree_kv_ops cob_bc_ops = {
579  .ko_ksize = bc_ksize,
580  .ko_vsize = bc_vsize,
581  .ko_compare = bc_cmp
582 };
583 
587 static int oi_cmp(const void *key0, const void *key1)
588 {
589  const struct m0_cob_oikey *cok0 = key0;
590  const struct m0_cob_oikey *cok1 = key1;
591  int rc;
592 
593  M0_PRE(m0_fid_is_set(&cok0->cok_fid));
594  M0_PRE(m0_fid_is_set(&cok1->cok_fid));
595 
596  rc = m0_fid_cmp(&cok0->cok_fid, &cok1->cok_fid);
597  return rc ?: M0_3WAY(cok0->cok_linkno, cok1->cok_linkno);
598 }
599 
600 static m0_bcount_t oi_ksize(const void *key)
601 {
602  return sizeof(struct m0_cob_oikey);
603 }
604 
605 static const struct m0_be_btree_kv_ops cob_oi_ops = {
607  .ko_ksize = oi_ksize,
608  .ko_vsize = ns_ksize,
609  .ko_compare = oi_cmp
610 };
611 
615 static int fb_cmp(const void *key0, const void *key1)
616 {
617  const struct m0_cob_fabkey *cok0 = key0;
618  const struct m0_cob_fabkey *cok1 = key1;
619 
620  M0_PRE(m0_fid_is_set(&cok0->cfb_fid));
621  M0_PRE(m0_fid_is_set(&cok1->cfb_fid));
622 
623  return m0_fid_cmp(&cok0->cfb_fid, &cok1->cfb_fid);
624 }
625 
626 static m0_bcount_t fb_ksize(const void *key)
627 {
628  return sizeof(struct m0_cob_fabkey);
629 }
630 
631 static m0_bcount_t fb_vsize(const void *val)
632 {
633  return m0_cob_fabrec_size(val);
634 }
635 
636 static const struct m0_be_btree_kv_ops cob_fab_ops = {
638  .ko_ksize = fb_ksize,
639  .ko_vsize = fb_vsize,
640  .ko_compare = fb_cmp
641 };
642 
646 static int ea_cmp(const void *key0, const void *key1)
647 {
648  return m0_cob_eakey_cmp(key0, key1);
649 }
650 
651 static m0_bcount_t ea_ksize(const void *key)
652 {
653  return m0_cob_eakey_size(key);
654 }
655 
656 static m0_bcount_t ea_vsize(const void *val)
657 {
658  return m0_cob_earec_size(val);
659 }
660 
661 static const struct m0_be_btree_kv_ops cob_ea_ops = {
663  .ko_ksize = ea_ksize,
664  .ko_vsize = ea_vsize,
665  .ko_compare = ea_cmp
666 };
667 
671 static int omg_cmp(const void *key0, const void *key1)
672 {
673  const struct m0_cob_omgkey *cok0 = key0;
674  const struct m0_cob_omgkey *cok1 = key1;
675  return M0_3WAY(cok0->cok_omgid, cok1->cok_omgid);
676 }
677 
678 static m0_bcount_t omg_ksize(const void *key)
679 {
680  return sizeof(struct m0_cob_omgkey);
681 }
682 
683 static m0_bcount_t omg_vsize(const void *val)
684 {
685  return sizeof(struct m0_cob_omgrec);
686 }
687 
688 static const struct m0_be_btree_kv_ops cob_omg_ops = {
690  .ko_ksize = omg_ksize,
691  .ko_vsize = omg_vsize,
692  .ko_compare = omg_cmp
693 };
694 
695 M0_UNUSED static char *cob_dom_id_make(char *buf, const struct m0_cob_domain_id *id,
696  const char *prefix)
697 {
698  sprintf(buf, "%s%lu", prefix ? prefix : "", (unsigned long)id->id);
699  return buf;
700 }
701 
709 {
710  M0_ENTRY("dom=%p id=%" PRIx64 "", dom, dom != NULL ? dom->cd_id.id : 0);
711 
712  M0_PRE(dom != NULL);
713  M0_PRE(dom->cd_id.id != 0);
714 
722 
723  return M0_RC(0);
724 }
725 
727 {
735 }
736 
737 static void cob_domain_id2str(char **s, const struct m0_cob_domain_id *cdid)
738 {
739  return m0_asprintf(s, "%016" PRIX64 "", cdid->id);
740 }
741 
743  struct m0_be_domain *bedom,
744  struct m0_be_seg *seg,
745  const struct m0_cob_domain_id *cdid,
746  struct m0_be_tx_credit *cred)
747 {
748  char *cdid_str;
749  struct m0_buf data = {}; /*XXX*/
750  struct m0_be_btree dummy = { .bb_seg = seg }; /* XXX */
751 
752  cob_domain_id2str(&cdid_str, cdid);
753  if (cdid_str == NULL)
754  return M0_ERR(-ENOMEM);
755  m0_be_0type_add_credit(bedom, &m0_be_cob0, cdid_str, &data, cred);
757  m0_be_btree_create_credit(&dummy, 6 /* XXX */, cred);
758  m0_free(cdid_str);
759  return M0_RC(0);
760 }
761 
762 M0_INTERNAL
764  struct m0_sm_group *grp,
765  const struct m0_cob_domain_id *cdid,
766  struct m0_be_domain *bedom,
767  struct m0_be_seg *seg,
768  struct m0_be_tx *tx)
769 {
770  struct m0_cob_domain *dom;
771  char *cdid_str;
772  struct m0_buf data = {}; /*XXX*/
773  int rc;
774 
775  cob_domain_id2str(&cdid_str, cdid);
776  if (cdid_str == NULL)
777  return M0_ERR(-ENOMEM);
778 
780  if (dom == NULL) {
781  m0_free(cdid_str);
782  return M0_ERR(-ENOMEM);
783  }
784 
786  .ot_version = M0_COB_DOMAIN_FORMAT_VERSION,
787  .ot_type = M0_FORMAT_TYPE_COB_DOMAIN,
788  .ot_footer_offset = offsetof(struct m0_cob_domain, cd_footer)
789  });
790 
791  dom->cd_id = *cdid;
792 
795 
797  M0_ASSERT(rc == 0); /* XXX */
798 
799  M0_BE_OP_SYNC(o,
801  &M0_FID_TINIT('b',
803  cdid->id)));
804  M0_BE_OP_SYNC(o,
806  &M0_FID_TINIT('b',
808  cdid->id)));
809  M0_BE_OP_SYNC(o,
811  &M0_FID_TINIT('b',
813  cdid->id)));
814  M0_BE_OP_SYNC(o,
816  &M0_FID_TINIT('b',
818  cdid->id)));
819  M0_BE_OP_SYNC(o,
821  &M0_FID_TINIT('b',
823  cdid->id)));
824  M0_BE_OP_SYNC(o,
826  &M0_FID_TINIT('b',
828  cdid->id)));
829 
831  rc = m0_be_0type_add(&m0_be_cob0, bedom, tx, cdid_str, &data);
832  M0_ASSERT(rc == 0);
833  m0_free(cdid_str);
834 
835  *out = dom;
836 
837  return M0_RC(0);
838 }
839 
841  struct m0_sm_group *grp,
842  const struct m0_cob_domain_id *cdid,
843  struct m0_be_domain *bedom,
844  struct m0_be_seg *seg)
845 {
846  struct m0_be_tx_credit cred = {};
847  struct m0_be_tx *tx;
848  int rc;
849 
850  M0_PRE(cdid->id != 0);
851 
852  M0_ALLOC_PTR(tx);
853  if (tx == NULL)
854  return M0_ERR(-ENOMEM);
855 
856  m0_cob_domain_credit_add(*dom, bedom, seg, cdid, &cred);
857  m0_be_tx_init(tx, 0, bedom, grp, NULL, NULL, NULL, NULL);
858  m0_be_tx_prep(tx, &cred);
860  if (rc != 0)
861  goto tx_fini;
862 
863  rc = m0_cob_domain_create_prepared(dom, grp, cdid, bedom, seg, tx);
865 tx_fini:
866  m0_be_tx_fini(tx);
867  m0_free(tx);
868  return M0_RC(rc);
869 }
870 
872  struct m0_sm_group *grp,
873  struct m0_be_domain *bedom)
874 {
875  struct m0_be_tx_credit cred = {};
876  struct m0_be_seg *seg;
877  char *cdid_str;
878  struct m0_be_tx *tx;
879  int rc;
880 
881  M0_PRE(dom != NULL);
882 
883  M0_ALLOC_PTR(tx);
884  if (tx == NULL)
885  return M0_ERR(-ENOMEM);
886 
887  cob_domain_id2str(&cdid_str, &dom->cd_id);
888  if (cdid_str == NULL) {
889  m0_free(tx);
890  return M0_ERR(-ENOMEM);
891  }
892 
893  seg = m0_be_domain_seg(bedom, dom);
894  m0_be_0type_del_credit(bedom, &m0_be_cob0, cdid_str, &cred);
895  M0_BE_FREE_CREDIT_PTR(dom, seg, &cred);
896 
903 
904 
905  m0_be_tx_init(tx, 0, bedom, grp, NULL, NULL, NULL, NULL);
906  m0_be_tx_prep(tx, &cred);
908  if (rc != 0)
909  goto tx_fini_return;
910 
911  rc = m0_be_0type_del(&m0_be_cob0, bedom, tx, cdid_str);
912  M0_ASSERT(rc == 0);
913 
920 
922 
923  dom->cd_id.id = 0;
926 
928 tx_fini_return:
929  m0_be_tx_fini(tx);
930  m0_free(cdid_str);
931  m0_free(tx);
932 
933  return M0_RC(rc);
934 }
935 
936 #include <sys/stat.h> /* S_ISDIR */
937 
938 #define MKFS_ROOT_SIZE 4096
939 #define MKFS_ROOT_BLKSIZE 4096
940 #define MKFS_ROOT_BLOCKS 16
941 
942 static int cob_table_delete(struct m0_be_btree *tree, struct m0_be_tx *tx,
943  struct m0_buf *key)
944 {
945  return M0_BE_OP_SYNC_RET(op, m0_be_btree_delete(tree, tx, &op, key),
946  bo_u.u_btree.t_rc);
947 }
948 
949 
950 static int cob_table_update(struct m0_be_btree *tree, struct m0_be_tx *tx,
951  struct m0_buf *key, struct m0_buf *val)
952 {
953  return M0_BE_OP_SYNC_RET(op,
954  m0_be_btree_update(tree, tx, &op, key, val),
955  bo_u.u_btree.t_rc);
956 }
957 
958 static int cob_table_insert(struct m0_be_btree *tree, struct m0_be_tx *tx,
959  struct m0_buf *key, struct m0_buf *val)
960 {
961  return M0_BE_OP_SYNC_RET(op,
962  m0_be_btree_insert(tree, tx, &op, key, val),
963  bo_u.u_btree.t_rc);
964 }
965 
966 static int cob_table_lookup(struct m0_be_btree *tree, struct m0_buf *key,
967  struct m0_buf *out)
968 {
969  return M0_BE_OP_SYNC_RET(op,
970  m0_be_btree_lookup(tree, &op, key, out),
971  bo_u.u_btree.t_rc);
972 }
973 
974 
980 M0_INTERNAL int m0_cob_domain_mkfs(struct m0_cob_domain *dom,
981  const struct m0_fid *rootfid,
982  struct m0_be_tx *tx)
983 {
984  struct m0_cob_nskey *nskey = NULL;
985  struct m0_cob_nsrec nsrec = {};
986  struct m0_cob_omgkey omgkey = {};
987  struct m0_cob_omgrec omgrec = {};
988  struct m0_cob_fabrec *fabrec = NULL;
989  struct m0_buf key;
990  struct m0_buf rec;
991  struct m0_cob *cob;
992  int rc;
993 
997  omgkey.cok_omgid = ~0ULL;
998 
999  m0_buf_init(&key, &omgkey, sizeof omgkey);
1000  m0_buf_init(&rec, &omgrec, sizeof omgrec);
1001  cob_table_insert(&dom->cd_fileattr_omg, tx, &key, &rec);
1002 
1006  rc = m0_cob_alloc(dom, &cob);
1007  if (rc != 0)
1008  return M0_RC(rc);
1009 
1011  strlen(M0_COB_ROOT_NAME));
1012  if (rc != 0) {
1013  m0_cob_put(cob);
1014  return M0_RC(rc);
1015  }
1016 
1017  m0_cob_nsrec_init(&nsrec);
1018  nsrec.cnr_omgid = 0;
1019  nsrec.cnr_fid = *rootfid;
1020 
1021  nsrec.cnr_nlink = 2;
1022  nsrec.cnr_size = MKFS_ROOT_SIZE;
1024  nsrec.cnr_blocks = MKFS_ROOT_BLOCKS;
1025  nsrec.cnr_atime = nsrec.cnr_mtime = nsrec.cnr_ctime =
1027 
1028  omgrec.cor_uid = 0;
1029  omgrec.cor_gid = 0;
1030  omgrec.cor_mode = S_IFDIR |
1031  S_IRUSR | S_IWUSR | S_IXUSR | /* rwx for owner */
1032  S_IRGRP | S_IXGRP | /* r-x for group */
1033  S_IROTH | S_IXOTH; /* r-x for others */
1034 
1035  rc = m0_cob_fabrec_make(&fabrec, NULL, 0);
1036  if (rc != 0) {
1037  m0_cob_put(cob);
1038  m0_free(nskey);
1039  return M0_RC(rc);
1040  }
1041 
1042  rc = m0_cob_create(cob, nskey, &nsrec, fabrec, &omgrec, tx);
1043  m0_cob_put(cob);
1044  if (rc == -EEXIST)
1045  rc = 0;
1046  if (rc != 0) {
1047  m0_free(nskey);
1048  m0_free(fabrec);
1049  return M0_RC(rc);
1050  }
1051 
1052  return 0;
1053 }
1054 
1055 static void cob_free_cb(struct m0_ref *ref);
1056 
1057 M0_INTERNAL void m0_cob_init(struct m0_cob_domain *dom, struct m0_cob *cob)
1058 {
1065  cob->co_nskey = NULL;
1066  cob->co_dom = dom;
1067  cob->co_flags = 0;
1068 }
1069 
1070 static void cob_fini(struct m0_cob *cob)
1071 {
1072  if (cob->co_flags & M0_CA_NSKEY_FREE)
1073  m0_free(cob->co_nskey);
1074  if (cob->co_flags & M0_CA_FABREC)
1075  m0_free(cob->co_fabrec);
1076 }
1077 
1081 static void cob_free_cb(struct m0_ref *ref)
1082 {
1083  struct m0_cob *cob;
1084 
1085  cob = container_of(ref, struct m0_cob, co_ref);
1086  cob_fini(cob);
1087  m0_free(cob);
1088 }
1089 
1090 M0_INTERNAL void m0_cob_get(struct m0_cob *cob)
1091 {
1092  m0_ref_get(&cob->co_ref);
1093 }
1094 
1095 M0_INTERNAL void m0_cob_put(struct m0_cob *cob)
1096 {
1097  m0_ref_put(&cob->co_ref);
1098 }
1099 
1100 M0_INTERNAL int m0_cob_alloc(struct m0_cob_domain *dom, struct m0_cob **out)
1101 {
1102  struct m0_cob *cob;
1103 
1104  M0_ALLOC_PTR(cob);
1105  if (cob == NULL) {
1106  *out = NULL;
1107  return M0_ERR(-ENOMEM);
1108  }
1109 
1110  m0_cob_init(dom, cob);
1111  *out = cob;
1112 
1113  return 0;
1114 }
1115 
1116 static int cob_ns_lookup(struct m0_cob *cob);
1117 static int cob_oi_lookup(struct m0_cob *cob);
1118 static int cob_fab_lookup(struct m0_cob *cob);
1119 
1120 M0_INTERNAL int m0_cob_bc_lookup(struct m0_cob *cob,
1121  struct m0_cob_bckey *bc_key,
1122  struct m0_cob_bcrec *bc_rec)
1123 {
1124  struct m0_buf key;
1125  struct m0_buf val;
1126  int rc;
1127 
1128  M0_PRE(bc_key != NULL &&
1129  m0_fid_is_set(&bc_key->cbk_pfid));
1130 
1131  m0_buf_init(&key, bc_key, m0_cob_bckey_size());
1132  m0_buf_init(&val, bc_rec, m0_cob_bcrec_size());
1133 
1135  if (rc == 0)
1136  cob->co_flags |= M0_CA_BCREC;
1137  return M0_RC(rc);
1138 }
1139 
1140 M0_INTERNAL int m0_cob_bc_insert(struct m0_cob *cob,
1141  struct m0_cob_bckey *bc_key,
1142  struct m0_cob_bcrec *bc_val,
1143  struct m0_be_tx *tx)
1144 {
1145  struct m0_buf key;
1146  struct m0_buf val;
1147  int rc;
1148 
1149  M0_PRE(bc_key != NULL && bc_val != NULL &&
1150  m0_fid_is_set(&bc_key->cbk_pfid));
1151 
1152  m0_buf_init(&key, bc_key, m0_cob_bckey_size());
1153  m0_buf_init(&val, bc_val, m0_cob_bcrec_size());
1154 
1156  if (rc == 0)
1157  cob->co_flags |= M0_CA_BCREC;
1158  return M0_RC(rc);
1159 }
1160 
1161 M0_INTERNAL int m0_cob_bc_update(struct m0_cob *cob,
1162  struct m0_cob_bckey *bc_key,
1163  struct m0_cob_bcrec *bc_val,
1164  struct m0_be_tx *tx)
1165 {
1166  struct m0_buf key;
1167  struct m0_buf val;
1168  int rc;
1169 
1170  M0_PRE(bc_key != NULL && bc_val != NULL &&
1171  m0_fid_is_set(&bc_key->cbk_pfid));
1172 
1173 
1174  m0_buf_init(&key, bc_key, m0_cob_bckey_size());
1175  m0_buf_init(&val, bc_val, m0_cob_bcrec_size());
1176 
1178  if (rc == 0)
1179  cob->co_flags |= M0_CA_BCREC;
1180  return M0_RC(rc);
1181 }
1182 
1191 static int cob_ns_lookup(struct m0_cob *cob)
1192 {
1193  struct m0_buf key;
1194  struct m0_buf val;
1195  int rc;
1196 
1197  M0_PRE(cob->co_nskey != NULL &&
1199 
1201  m0_buf_init(&val, &cob->co_nsrec, sizeof cob->co_nsrec);
1202 
1204  if (rc == 0) {
1205  cob->co_flags |= M0_CA_NSREC;
1207  cob->co_nsrec.cnr_nlink > 0);
1209  }
1210  return rc;
1211 }
1212 
1219 static int cob_oi_lookup(struct m0_cob *cob)
1220 {
1221  struct m0_be_btree_cursor cursor;
1222  struct m0_buf start;
1223  struct m0_buf key;
1224  struct m0_buf val;
1225  struct m0_cob_oikey oldkey;
1226  struct m0_cob_oikey *oikey;
1227  struct m0_cob_nskey *nskey;
1228  int rc;
1229 
1230  if (cob->co_flags & M0_CA_NSKEY)
1231  return 0;
1232 
1233  if (cob->co_flags & M0_CA_NSKEY_FREE) {
1234  m0_free(cob->co_nskey);
1236  }
1237 
1238  oldkey = cob->co_oikey;
1239 
1240  /*
1241  * Find the name from the object index table. Note the key buffer
1242  * is out of scope outside of this function, but the record is good
1243  * until m0_db_pair_fini.
1244  */
1245  m0_buf_init(&start, &cob->co_oikey, sizeof cob->co_oikey);
1246 
1247  /*
1248  * We use cursor here because in some situations we need
1249  * to find most suitable position instead of exact location.
1250  */
1252  rc = m0_be_btree_cursor_get_sync(&cursor, &start, true);
1253  if (rc != 0) {
1254  M0_LOG(M0_DEBUG, "btree_cursor_get_sync() failed with %d", rc);
1255  goto out;
1256  }
1257 
1258  m0_be_btree_cursor_kv_get(&cursor, &key, &val);
1259  nskey = (struct m0_cob_nskey *)val.b_addr;
1260  oikey = (struct m0_cob_oikey *)key.b_addr;
1261 
1262  M0_LOG(M0_DEBUG, "found: fid="FID_F" lno=%d pfid="FID_F" name='%s'",
1263  FID_P(&oikey->cok_fid), (int)oikey->cok_linkno,
1264  FID_P(&nskey->cnk_pfid), (char*)nskey->cnk_name.b_data);
1265 
1266  /*
1267  * Found position should have same fid.
1268  */
1269  if (!m0_fid_eq(&oldkey.cok_fid, &oikey->cok_fid)) {
1270  M0_LOG(M0_DEBUG, "old fid="FID_F" fid="FID_F,
1271  FID_P(&oldkey.cok_fid),
1272  FID_P(&oikey->cok_fid));
1273  rc = -ENOENT;
1274  goto out;
1275  }
1276 
1277  rc = m0_cob_nskey_make(&cob->co_nskey, &nskey->cnk_pfid,
1278  m0_bitstring_buf_get(&nskey->cnk_name),
1279  m0_bitstring_len_get(&nskey->cnk_name));
1281 out:
1282  m0_be_btree_cursor_fini(&cursor);
1283  return M0_RC(rc);
1284 }
1285 
1292 static int cob_fab_lookup(struct m0_cob *cob)
1293 {
1294  struct m0_cob_fabkey fabkey;
1295  struct m0_buf key;
1296  struct m0_buf val;
1297  int rc;
1298 
1299  if (cob->co_flags & M0_CA_FABREC)
1300  return 0;
1301 
1302  fabkey.cfb_fid = *m0_cob_fid(cob);
1304  if (rc != 0)
1305  return M0_RC(rc);
1306 
1307  m0_buf_init(&key, &fabkey, sizeof fabkey);
1309 
1311  if (rc == 0)
1313  else
1314  cob->co_flags &= ~M0_CA_FABREC;
1315 
1316  return M0_RC(rc);
1317 }
1318 
1323 static int cob_omg_lookup(struct m0_cob *cob)
1324 {
1325  struct m0_cob_omgkey omgkey;
1326  struct m0_buf key;
1327  struct m0_buf val;
1328  int rc;
1329 
1330  if (cob->co_flags & M0_CA_OMGREC)
1331  return 0;
1332 
1333  omgkey.cok_omgid = cob->co_nsrec.cnr_omgid;
1334 
1335  m0_buf_init(&key, &omgkey, sizeof omgkey);
1336  m0_buf_init(&val, &cob->co_omgrec, sizeof cob->co_omgrec);
1337 
1339  if (rc == 0)
1341  else
1342  cob->co_flags &= ~M0_CA_OMGREC;
1343 
1344  return rc;
1345 }
1346 
1350 static int cob_get_fabomg(struct m0_cob *cob, uint64_t flags)
1351 {
1352  int rc = 0;
1353 
1354  if (flags & M0_CA_FABREC) {
1355  rc = cob_fab_lookup(cob);
1356  if (rc != 0)
1357  return M0_RC(rc);
1358  }
1359 
1360  /*
1361  * Get omg attributes as well if we need it.
1362  */
1363  if (flags & M0_CA_OMGREC) {
1364  rc = cob_omg_lookup(cob);
1365  if (rc != 0)
1366  return M0_RC(rc);
1367  }
1368  return M0_RC(rc);
1369 }
1370 
1371 M0_INTERNAL int m0_cob_lookup(struct m0_cob_domain *dom,
1372  struct m0_cob_nskey *nskey, uint64_t flags,
1373  struct m0_cob **out)
1374 {
1375  struct m0_cob *cob;
1376  int rc;
1377 
1378  M0_ASSERT(out != NULL);
1379  *out = NULL;
1380 
1381  rc = m0_cob_alloc(dom, &cob);
1382  if (rc != 0)
1383  return M0_RC(rc);
1384 
1385  cob->co_nskey = nskey;
1386  cob->co_flags |= M0_CA_NSKEY;
1387 
1388  if (flags & M0_CA_NSKEY_FREE)
1390 
1391  rc = cob_ns_lookup(cob);
1392  if (rc != 0) {
1393  m0_cob_put(cob);
1394  return M0_RC(rc);
1395  }
1396 
1397  rc = cob_get_fabomg(cob, flags);
1398  if (rc != 0) {
1399  m0_cob_put(cob);
1400  return M0_RC(rc);
1401  }
1402 
1403  *out = cob;
1404  return M0_RC(rc);
1405 }
1406 
1407 M0_INTERNAL int m0_cob_locate(struct m0_cob_domain *dom,
1408  struct m0_cob_oikey *oikey, uint64_t flags,
1409  struct m0_cob **out)
1410 {
1411  struct m0_cob *cob;
1412  int rc;
1413 
1414  M0_PRE(m0_fid_is_set(&oikey->cok_fid));
1415 
1416  M0_ENTRY("dom=%p oikey=("FID_F", %d)", dom,
1417  FID_P(&oikey->cok_fid), (int)oikey->cok_linkno);
1418 
1419  /*
1420  * Zero out "out" just in case that if we fail here, it is
1421  * easier to find abnormal using of NULL cob.
1422  */
1423  M0_ASSERT(out != NULL);
1424  *out = NULL;
1425 
1426  /* Get cob memory. */
1427  rc = m0_cob_alloc(dom, &cob);
1428  if (rc != 0)
1429  return M0_RC(rc);
1430 
1431  cob->co_oikey = *oikey;
1432  rc = cob_oi_lookup(cob);
1433  if (rc != 0) {
1434  M0_LOG(M0_DEBUG, "cob_oi_lookup() failed with %d", rc);
1435  m0_cob_put(cob);
1436  return M0_RC(rc);
1437  }
1438 
1439  rc = cob_ns_lookup(cob);
1440  if (rc != 0) {
1441  M0_LOG(M0_DEBUG, "cob_ns_lookup() failed with %d", rc);
1442  m0_cob_put(cob);
1443  return M0_RC(rc);
1444  }
1445 
1446  rc = cob_get_fabomg(cob, flags);
1447  if (rc != 0) {
1448  M0_LOG(M0_DEBUG, "cob_get_fabomg() failed with %d", rc);
1449  m0_cob_put(cob);
1450  return M0_RC(rc);
1451  }
1452 
1453  *out = cob;
1454  return M0_RC(rc);
1455 }
1456 
1457 M0_INTERNAL int m0_cob_iterator_init(struct m0_cob *cob,
1458  struct m0_cob_iterator *it,
1459  struct m0_bitstring *name)
1460 {
1461  int rc;
1462 
1463  /*
1464  * Prepare entry key using passed started pos.
1465  */
1466  rc = m0_cob_max_nskey_make(&it->ci_key, m0_cob_fid(cob),
1469  if (rc != 0)
1470  return M0_RC(rc);
1471 
1473  it->ci_cob = cob;
1474  return M0_RC(rc);
1475 }
1476 
1477 M0_INTERNAL void m0_cob_iterator_fini(struct m0_cob_iterator *it)
1478 {
1479  m0_be_btree_cursor_fini(&it->ci_cursor);
1480  m0_free(it->ci_key);
1481 }
1482 
1483 M0_INTERNAL int m0_cob_iterator_get(struct m0_cob_iterator *it)
1484 {
1485  struct m0_cob_nskey *nskey;
1486  struct m0_buf key;
1487  int rc;
1488 
1489  M0_COB_NSKEY_LOG(ENTRY, "[%lx:%lx]/%.*s", it->ci_key);
1490  m0_buf_init(&key, it->ci_key, m0_cob_nskey_size(it->ci_key));
1491  rc = m0_be_btree_cursor_get_sync(&it->ci_cursor, &key, true);
1492  if (rc == 0) {
1493  m0_be_btree_cursor_kv_get(&it->ci_cursor, &key, NULL);
1494  nskey = (struct m0_cob_nskey *)key.b_addr;
1495 
1500  if (!m0_fid_eq(&nskey->cnk_pfid, m0_cob_fid(it->ci_cob)))
1501  rc = -ENOENT;
1502 
1503  if (rc == 0) {
1505  memcpy(it->ci_key, nskey, m0_cob_nskey_size(nskey));
1506  }
1507  }
1508  M0_COB_NSKEY_LOG(LEAVE, "[%lx:%lx]/%.*s rc: %d", it->ci_key, rc);
1509  return M0_RC(rc);
1510 }
1511 
1512 M0_INTERNAL int m0_cob_iterator_next(struct m0_cob_iterator *it)
1513 {
1514  struct m0_cob_nskey *nskey;
1515  struct m0_buf key;
1516  int rc;
1517 
1518  M0_COB_NSKEY_LOG(ENTRY, "[%lx:%lx]/%.*s", it->ci_key);
1519  rc = m0_be_btree_cursor_next_sync(&it->ci_cursor);
1520  if (rc == 0) {
1521  m0_be_btree_cursor_kv_get(&it->ci_cursor, &key, NULL);
1522  nskey = (struct m0_cob_nskey *)key.b_addr;
1523 
1528  if (!m0_fid_eq(&nskey->cnk_pfid, m0_cob_fid(it->ci_cob)))
1529  rc = -ENOENT;
1530  if (rc == 0) {
1532  memcpy(it->ci_key, nskey, m0_cob_nskey_size(nskey));
1533  }
1534  }
1535  M0_COB_NSKEY_LOG(LEAVE, "[%lx:%lx]/%.*s rc: %d", it->ci_key, rc);
1536  return M0_RC(rc);
1537 }
1538 
1539 M0_INTERNAL int m0_cob_ea_iterator_init(struct m0_cob *cob,
1540  struct m0_cob_ea_iterator *it,
1541  struct m0_bitstring *name)
1542 {
1543  int rc;
1544 
1545  /*
1546  * Prepare entry key using passed started pos.
1547  */
1548  rc = m0_cob_max_eakey_make(&it->ci_key, m0_cob_fid(cob),
1551  if (rc != 0)
1552  return M0_RC(rc);
1553 
1554  it->ci_rec = m0_alloc(m0_cob_max_earec_size());
1555  if (it->ci_rec == NULL) {
1556  m0_free(it->ci_key);
1557  return M0_RC(rc);
1558  }
1559 
1561  it->ci_cob = cob;
1562  return M0_RC(rc);
1563 }
1564 
1566 {
1567  int rc;
1568  struct m0_buf key;
1569  struct m0_cob_eakey *eakey;
1570 
1571  m0_buf_init(&key, it->ci_key, m0_cob_eakey_size(it->ci_key));
1572  rc = m0_be_btree_cursor_get_sync(&it->ci_cursor, &key, true);
1573  if (rc == 0) {
1574  m0_be_btree_cursor_kv_get(&it->ci_cursor, &key, NULL);
1575  eakey = (struct m0_cob_eakey *)key.b_addr;
1576 
1581  if (!m0_fid_eq(&eakey->cek_fid, m0_cob_fid(it->ci_cob)))
1582  rc = -ENOENT;
1583 
1584  if (rc == 0) {
1585  M0_ASSERT(m0_cob_eakey_size(eakey) <=
1587  memcpy(it->ci_key, eakey, m0_cob_eakey_size(eakey));
1588  }
1589  }
1590  return M0_RC(rc);
1591 }
1592 
1594 {
1595  int rc;
1596  struct m0_buf key;
1597  struct m0_cob_eakey *eakey;
1598 
1599  rc = m0_be_btree_cursor_next_sync(&it->ci_cursor);
1600  if (rc == 0) {
1601  m0_be_btree_cursor_kv_get(&it->ci_cursor, &key, NULL);
1602  eakey = (struct m0_cob_eakey *)key.b_addr;
1603 
1608  if (!m0_fid_eq(&eakey->cek_fid, m0_cob_fid(it->ci_cob)))
1609  rc = -ENOENT;
1610 
1611  if (rc == 0) {
1613  memcpy(it->ci_key, eakey, m0_cob_eakey_size(eakey));
1614  }
1615  }
1616 
1617  return M0_RC(rc);
1618 }
1619 
1621 {
1622  m0_free(it->ci_key);
1623  m0_free(it->ci_rec);
1624 }
1625 
1629 static bool m0_cob_is_valid(struct m0_cob *cob)
1630 {
1631  return m0_fid_is_set(m0_cob_fid(cob));
1632 }
1633 
1634 M0_INTERNAL int m0_cob_alloc_omgid(struct m0_cob_domain *dom, uint64_t *omgid)
1635 {
1636  struct m0_be_btree_cursor cursor;
1637  struct m0_cob_omgkey omgkey;
1638  struct m0_buf kbuf;
1639  int rc;
1640 
1641  M0_ENTRY();
1642 
1644 
1645  /*
1646  * Look for ~0ULL terminator record and do a step back to find last
1647  * allocated omgid. Terminator record should be prepared in storage
1648  * init time (mkfs or else).
1649  */
1650  omgkey.cok_omgid = ~0ULL;
1651  m0_buf_init(&kbuf, &omgkey, sizeof omgkey);
1652  rc = m0_be_btree_cursor_get_sync(&cursor, &kbuf, true);
1653 
1654  /*
1655  * In case of error, most probably due to no terminator record found,
1656  * one needs to run mkfs.
1657  */
1658  if (rc == 0) {
1659  rc = m0_be_btree_cursor_prev_sync(&cursor);
1660  if (omgid != NULL) {
1661  if (rc == 0) {
1662  /* We found last allocated omgid.
1663  * Bump it by one. */
1664  m0_be_btree_cursor_kv_get(&cursor, &kbuf, NULL);
1665  omgkey = *(struct m0_cob_omgkey*)kbuf.b_addr;
1666  *omgid = ++omgkey.cok_omgid;
1667  } else {
1668  /* No last allocated found, this alloc call is
1669  * the first one. */
1670  *omgid = 0;
1671  }
1672  }
1673  rc = 0;
1674  }
1675 
1676  m0_be_btree_cursor_fini(&cursor);
1677  return M0_RC(rc);
1678 }
1679 
1680 
1681 M0_INTERNAL int m0_cob_create(struct m0_cob *cob,
1682  struct m0_cob_nskey *nskey,
1683  struct m0_cob_nsrec *nsrec,
1684  struct m0_cob_fabrec *fabrec,
1685  struct m0_cob_omgrec *omgrec,
1686  struct m0_be_tx *tx)
1687 {
1688  struct m0_buf key;
1689  struct m0_buf val;
1690  struct m0_cob_omgkey omgkey;
1691  struct m0_cob_fabkey fabkey;
1692  int rc;
1693 
1694  M0_PRE(cob != NULL);
1695  M0_PRE(nskey != NULL);
1696  M0_PRE(nsrec != NULL);
1697  M0_PRE(m0_fid_is_set(&nsrec->cnr_fid));
1698  M0_PRE(m0_fid_is_set(&nskey->cnk_pfid));
1699 
1700  M0_ENTRY("nskey=("FID_F", '%s') nsrec=("FID_F", %d)",
1701  FID_P(&nskey->cnk_pfid), (char*)nskey->cnk_name.b_data,
1702  FID_P(&nsrec->cnr_fid), (int)nsrec->cnr_linkno);
1703 
1704  if (omgrec != NULL) {
1705  rc = m0_cob_alloc_omgid(cob->co_dom, &nsrec->cnr_omgid);
1706  if (rc != 0)
1707  goto out;
1708  }
1709 
1710  cob->co_nskey = nskey;
1711  cob->co_flags |= M0_CA_NSKEY;
1712 
1713  /*
1714  * This is what name_add will use to create new name.
1715  */
1716  cob->co_nsrec = *nsrec;
1717  cob->co_flags |= M0_CA_NSREC;
1718  cob->co_nsrec.cnr_cntr = 0;
1719 
1720  /*
1721  * Initialize counter with 1 which is what will be used
1722  * for adding second name. We do it this way to avoid
1723  * doing special m0_cob_update() solely for having
1724  * this field stored in db.
1725  */
1726  nsrec->cnr_cntr = 1;
1727 
1728  /*
1729  * Let's create name, statdata and object index.
1730  */
1731  rc = m0_cob_name_add(cob, nskey, nsrec, tx);
1732  if (rc != 0)
1733  goto out;
1735 
1736  if (fabrec != NULL) {
1737  /*
1738  * Prepare key for attribute tables.
1739  */
1740  fabkey.cfb_fid = *m0_cob_fid(cob);
1741 
1742  /*
1743  * Now let's update file attributes. Cache the fabrec.
1744  */
1745  cob->co_fabrec = fabrec;
1746 
1747  /*
1748  * Add to fileattr-basic table.
1749  */
1750  m0_buf_init(&key, &fabkey, sizeof fabkey);
1754  &val);
1756  }
1757 
1758  if (omgrec != NULL) {
1759  /*
1760  * Prepare omg key.
1761  */
1762  omgkey.cok_omgid = nsrec->cnr_omgid;
1763 
1764  /*
1765  * Now let's update omg attributes. Cache the omgrec.
1766  */
1767  cob->co_omgrec = *omgrec;
1769 
1770  /*
1771  * Add to fileattr-omg table.
1772  */
1773  m0_buf_init(&key, &omgkey, sizeof omgkey);
1774  m0_buf_init(&val, &cob->co_omgrec, sizeof cob->co_omgrec);
1776  &val);
1777  if (rc == -ENOENT)
1779  &key, &val);
1780  else
1781  M0_LOG(M0_DEBUG, "the same omgkey: %" PRIx64 " is being "
1782  "added multiple times", omgkey.cok_omgid);
1783  rc = 0;
1784  }
1785 out:
1786  return M0_RC(rc);
1787 }
1788 
1789 M0_INTERNAL int m0_cob_delete(struct m0_cob *cob, struct m0_be_tx *tx)
1790 {
1791  struct m0_cob_fabkey fabkey;
1792  struct m0_cob_omgkey omgkey;
1793  struct m0_cob_oikey oikey;
1794  struct m0_buf key;
1795  struct m0_cob *sdcob;
1796  bool sdname;
1797  int rc;
1798 
1801 
1802  m0_cob_oikey_make(&oikey, m0_cob_fid(cob), 0);
1803  rc = m0_cob_locate(cob->co_dom, &oikey, 0, &sdcob);
1804  if (rc != 0)
1805  goto out;
1806  sdname = (m0_cob_nskey_cmp(cob->co_nskey, sdcob->co_nskey) == 0);
1807  m0_cob_put(sdcob);
1808 
1809  /*
1810  * Delete last name from namespace and object index.
1811  */
1812  rc = m0_cob_name_del(cob, cob->co_nskey, tx);
1813  if (rc != 0)
1814  goto out;
1815 
1816  /*
1817  * Is this a statdata name?
1818  */
1819  if (sdname) {
1820  /*
1821  * Remove from the fileattr_basic table.
1822  */
1823  fabkey.cfb_fid = *m0_cob_fid(cob);
1824  m0_buf_init(&key, &fabkey, sizeof fabkey);
1825 
1826  /*
1827  * Ignore errors; it's a dangling table entry but causes
1828  * no harm.
1829  */
1831 
1832  /*
1833  * @todo: Omgrec may be shared between multiple objects.
1834  * Delete should take this into account as well as update.
1835  */
1836  omgkey.cok_omgid = cob->co_nsrec.cnr_omgid;
1837 
1838  /*
1839  * Remove from the fileattr_omg table.
1840  */
1841  m0_buf_init(&key, &omgkey, sizeof omgkey);
1842 
1843  /*
1844  * Ignore errors; it's a dangling table entry but causes
1845  * no harm.
1846  */
1848  }
1849 out:
1850  return M0_RC(rc);
1851 }
1852 
1853 M0_INTERNAL int m0_cob_delete_put(struct m0_cob *cob, struct m0_be_tx *tx)
1854 {
1855  int rc = m0_cob_delete(cob, tx);
1856  m0_cob_put(cob);
1857  return M0_RC(rc);
1858 }
1859 
1860 M0_INTERNAL int m0_cob_update(struct m0_cob *cob,
1861  struct m0_cob_nsrec *nsrec,
1862  struct m0_cob_fabrec *fabrec,
1863  struct m0_cob_omgrec *omgrec,
1864  struct m0_be_tx *tx)
1865 {
1866  struct m0_cob_omgkey omgkey;
1867  struct m0_cob_fabkey fabkey;
1868  struct m0_buf key;
1869  struct m0_buf val;
1870  int rc = 0;
1871 
1874 
1875  if (nsrec != NULL) {
1876  M0_ASSERT(nsrec->cnr_nlink > 0);
1877 
1878  cob->co_nsrec = *nsrec;
1879  cob->co_flags |= M0_CA_NSREC;
1880 
1882  /* Update footer before record becomes persistant */
1884  m0_buf_init(&val, &cob->co_nsrec, sizeof cob->co_nsrec);
1886  tx, &key, &val);
1887  }
1888 
1889  if (rc == 0 && fabrec != NULL) {
1890  fabkey.cfb_fid = *m0_cob_fid(cob);
1891  if (fabrec != cob->co_fabrec) {
1892  if (cob->co_flags & M0_CA_FABREC)
1893  m0_free(cob->co_fabrec);
1894  cob->co_fabrec = fabrec;
1895  }
1897 
1898 
1899  m0_buf_init(&key, &fabkey, sizeof fabkey);
1902  tx, &key, &val);
1903  }
1904 
1905  if (rc == 0 && omgrec != NULL) {
1906  /*
1907  * @todo: Omgrec may be shared between multiple objects.
1908  * We need to take this into account.
1909  */
1910  omgkey.cok_omgid = cob->co_nsrec.cnr_omgid;
1911 
1912  cob->co_omgrec = *omgrec;
1914 
1915  m0_buf_init(&key, &omgkey, sizeof omgkey);
1916  m0_buf_init(&val, &cob->co_omgrec, sizeof cob->co_omgrec);
1918  tx, &key, &val);
1919  }
1920 
1921  return M0_RC(rc);
1922 }
1923 
1924 M0_INTERNAL int m0_cob_name_add(struct m0_cob *cob,
1925  struct m0_cob_nskey *nskey,
1926  struct m0_cob_nsrec *nsrec,
1927  struct m0_be_tx *tx)
1928 {
1929  struct m0_cob_oikey oikey;
1930  struct m0_buf key;
1931  struct m0_buf val;
1932  int rc;
1933 
1934  M0_PRE(cob != NULL);
1935  M0_PRE(nskey != NULL);
1936  M0_PRE(m0_fid_is_set(&nskey->cnk_pfid));
1938 
1939  m0_cob_oikey_make(&oikey, &nsrec->cnr_fid, cob->co_nsrec.cnr_cntr);
1940 
1941  m0_buf_init(&key, &oikey, sizeof oikey);
1942  m0_buf_init(&val, nskey, m0_cob_nskey_size(nskey));
1944  if (rc != 0)
1945  return M0_RC_INFO(rc, "fid="FID_F" cntr=%u",
1946  FID_P(&nsrec->cnr_fid),
1947  (unsigned)cob->co_nsrec.cnr_cntr);
1948 
1949  m0_buf_init(&key, nskey, m0_cob_nskey_size(nskey));
1950  /* Update footer before record becomes persistant */
1951  m0_format_footer_update(nsrec);
1952  m0_buf_init(&val, nsrec, sizeof *nsrec);
1954  if (rc != 0) {
1955  m0_buf_init(&key, &oikey, sizeof oikey);
1957  return M0_RC_INFO(rc, "parent="FID_F" name='%*s'",
1958  FID_P(&nskey->cnk_pfid),
1959  nskey->cnk_name.b_len,
1960  (char*)nskey->cnk_name.b_data);
1961  }
1962 
1963  return rc;
1964 }
1965 
1966 M0_INTERNAL int m0_cob_name_del(struct m0_cob *cob,
1967  struct m0_cob_nskey *nskey,
1968  struct m0_be_tx *tx)
1969 {
1970  struct m0_cob_oikey oikey;
1971  struct m0_cob_nsrec nsrec;
1972  struct m0_buf key;
1973  struct m0_buf val;
1974  int rc;
1975 
1978 
1979  /*
1980  * Kill name from namespace.
1981  */
1982  m0_buf_init(&key, nskey, m0_cob_nskey_size(nskey));
1983  m0_buf_init(&val, &nsrec, sizeof nsrec);
1984 
1986  if (rc != 0)
1987  goto out;
1988 
1990  if (rc != 0)
1991  goto out;
1992 
1993  /*
1994  * Let's also kill object index entry.
1995  */
1996  m0_cob_oikey_make(&oikey, m0_cob_fid(cob), nsrec.cnr_linkno);
1997  m0_buf_init(&key, &oikey, sizeof oikey);
1999 
2000 out:
2001  return M0_RC(rc);
2002 }
2003 
2004 M0_INTERNAL int m0_cob_name_update(struct m0_cob *cob,
2005  struct m0_cob_nskey *srckey,
2006  struct m0_cob_nskey *tgtkey,
2007  struct m0_be_tx *tx)
2008 {
2009  struct m0_cob_oikey oikey;
2010  struct m0_buf key;
2011  struct m0_buf val;
2012  int rc;
2013 
2015  M0_PRE(srckey != NULL && tgtkey != NULL);
2016 
2017  /*
2018  * Insert new record with nsrec found with srckey.
2019  */
2020  m0_buf_init(&key, srckey, m0_cob_nskey_size(srckey));
2022  if (rc != 0)
2023  goto out;
2024 
2025  m0_buf_init(&key, tgtkey, m0_cob_nskey_size(tgtkey));
2026  /* here @val consists value to insert */
2028 
2029  /*
2030  * Kill old record. Error will be returned if
2031  * nothing found.
2032  */
2033  m0_buf_init(&key, srckey, m0_cob_nskey_size(srckey));
2035  if (rc != 0)
2036  goto out;
2037 
2038  /* Update object index */
2039  m0_buf_init(&key, &oikey, sizeof oikey);
2040  m0_buf_init(&val, tgtkey, m0_cob_nskey_size(tgtkey));
2042  if (rc != 0)
2043  goto out;
2044 
2045  /*
2046  * Update key to new one.
2047  */
2048  if (cob->co_flags & M0_CA_NSKEY_FREE)
2049  m0_free(cob->co_nskey);
2050  m0_cob_nskey_make(&cob->co_nskey, &tgtkey->cnk_pfid,
2051  m0_bitstring_buf_get(&tgtkey->cnk_name),
2052  m0_bitstring_len_get(&tgtkey->cnk_name));
2054 out:
2055  return M0_RC(rc);
2056 }
2057 
2058 M0_INTERNAL void m0_cob_nsrec_init(struct m0_cob_nsrec *nsrec)
2059 {
2060  m0_format_header_pack(&nsrec->cnr_header, &(struct m0_format_tag){
2061  .ot_version = M0_COB_NSREC_FORMAT_VERSION,
2062  .ot_type = M0_FORMAT_TYPE_COB_NSREC,
2063  .ot_footer_offset = offsetof(struct m0_cob_nsrec, cnr_footer)
2064  });
2065  m0_format_footer_update(nsrec);
2066 }
2067 
2068 M0_INTERNAL int m0_cob_setattr(struct m0_cob *cob, struct m0_cob_attr *attr,
2069  struct m0_be_tx *tx)
2070 {
2071  struct m0_cob_nsrec nsrec_prev;
2072  struct m0_cob_nsrec *nsrec = NULL;
2073  struct m0_cob_fabrec *fabrec = NULL;
2074  struct m0_cob_omgrec *omgrec = NULL;
2075  int rc;
2076 
2077  M0_ENTRY();
2078  M0_ASSERT(cob != NULL);
2079 
2080  /*
2081  * Handle basic stat fields update.
2082  */
2083  if (cob->co_flags & M0_CA_NSREC) {
2084  nsrec = &cob->co_nsrec;
2085  m0_cob_nsrec_init(nsrec);
2086  nsrec_prev = *nsrec;
2087  if (attr->ca_valid & M0_COB_ATIME)
2088  nsrec->cnr_atime = attr->ca_atime;
2089  if (attr->ca_valid & M0_COB_MTIME)
2090  nsrec->cnr_mtime = attr->ca_mtime;
2091  if (attr->ca_valid & M0_COB_CTIME)
2092  nsrec->cnr_ctime = attr->ca_ctime;
2093  if (attr->ca_valid & M0_COB_SIZE) {
2094  if (nsrec->cnr_size > attr->ca_size &&
2095  attr->ca_size != 0) {
2096  rc = -EINVAL;
2097  /* Restore older attributed. */
2098  *nsrec = nsrec_prev;
2099  goto out;
2100  }
2101  nsrec->cnr_size = attr->ca_size;
2102  }
2103  /*if (attr->ca_valid & M0_COB_RDEV)
2104  nsrec->cnr_rdev = attr->ca_rdev;*/
2105  if (attr->ca_valid & M0_COB_BLOCKS)
2106  nsrec->cnr_blocks = attr->ca_blocks;
2107  if (attr->ca_valid & M0_COB_BLKSIZE)
2108  nsrec->cnr_blksize = attr->ca_blksize;
2109  if (attr->ca_valid & M0_COB_LID)
2110  nsrec->cnr_lid = attr->ca_lid;
2111  if (attr->ca_valid & M0_COB_NLINK) {
2112  M0_ASSERT(attr->ca_nlink > 0);
2113  nsrec->cnr_nlink = attr->ca_nlink;
2114  }
2115  //nsrec->cnr_version = attr->ca_version;
2116  }
2117 
2118  /*
2119  * Handle uid/gid/mode update.
2120  */
2121  if (cob->co_flags & M0_CA_OMGREC) {
2122  omgrec = &cob->co_omgrec;
2123  if (attr->ca_valid & M0_COB_UID)
2124  omgrec->cor_uid = attr->ca_uid;
2125  if (attr->ca_valid & M0_COB_GID)
2126  omgrec->cor_gid = attr->ca_gid;
2127  if (attr->ca_valid & M0_COB_MODE)
2128  omgrec->cor_mode = attr->ca_mode;
2129  }
2130 
2131  /*
2132  * @todo: update fabrec.
2133  */
2134  if (cob->co_flags & M0_CA_FABREC)
2135  fabrec = cob->co_fabrec;
2136 
2137  rc = m0_cob_update(cob, nsrec, fabrec, omgrec, tx);
2138 out:
2139  M0_LEAVE("rc: %d", rc);
2140  return M0_RC(rc);
2141 
2142 }
2143 
2144 M0_INTERNAL int m0_cob_size_update(struct m0_cob *cob, uint64_t size,
2145  struct m0_be_tx *tx)
2146 {
2147  int rc;
2148 
2150  rc = m0_cob_update(cob, &cob->co_nsrec, NULL, NULL, tx);
2151 
2152  return rc != 0 ? M0_ERR(rc) : M0_RC(rc);
2153 }
2154 
2155 M0_INTERNAL int m0_cob_ea_get(struct m0_cob *cob,
2156  struct m0_cob_eakey *eakey,
2157  struct m0_cob_earec *out,
2158  struct m0_be_tx *tx)
2159 {
2160  struct m0_buf key;
2161  struct m0_buf val;
2162  int rc;
2163 
2164  m0_buf_init(&key, eakey, m0_cob_eakey_size(eakey));
2167 
2168  return M0_RC(rc);
2169 }
2170 
2171 M0_INTERNAL int m0_cob_ea_set(struct m0_cob *cob,
2172  struct m0_cob_eakey *eakey,
2173  struct m0_cob_earec *earec,
2174  struct m0_be_tx *tx)
2175 {
2176  struct m0_buf key;
2177  struct m0_buf val;
2178 
2179  M0_PRE(cob != NULL);
2180  M0_PRE(eakey != NULL);
2181  M0_PRE(m0_fid_is_set(&eakey->cek_fid));
2183 
2184  m0_cob_ea_del(cob, eakey, tx);
2185 
2186  m0_buf_init(&key, eakey, m0_cob_eakey_size(eakey));
2187  m0_buf_init(&val, earec, m0_cob_earec_size(earec));
2189 
2190  return 0;
2191 }
2192 
2193 M0_INTERNAL int m0_cob_ea_del(struct m0_cob *cob,
2194  struct m0_cob_eakey *eakey,
2195  struct m0_be_tx *tx)
2196 {
2197  struct m0_buf key;
2198  int rc;
2199 
2201 
2202  m0_buf_init(&key, eakey, m0_cob_eakey_size(eakey));
2204  return M0_RC(rc);
2205 }
2206 
2211 };
2212 
2220 };
2221 
2222 static void cob_table_tx_credit(struct m0_be_btree *tree,
2223  enum cob_table_optype t_optype,
2224  enum cob_table_kvtype t_kvtype,
2225  struct m0_be_tx_credit *accum)
2226 {
2227  const struct {
2229  m0_bcount_t s_rec;
2230  } kv_size[] = {
2231  [COB_KVTYPE_OMG] = {
2232  .s_key = sizeof(struct m0_cob_omgkey),
2233  .s_rec = sizeof(struct m0_cob_omgrec),
2234  },
2235  [COB_KVTYPE_FAB] = {
2236  .s_key = sizeof(struct m0_cob_fabkey),
2237  .s_rec = m0_cob_max_fabrec_size(),
2238  },
2239  [COB_KVTYPE_FEA] = {
2240  .s_key = m0_cob_max_eakey_size(),
2241  .s_rec = m0_cob_max_earec_size(),
2242  },
2243  [COB_KVTYPE_NS] = {
2244  .s_key = m0_cob_max_nskey_size(),
2245  .s_rec = sizeof(struct m0_cob_nsrec),
2246  },
2247  [COB_KVTYPE_OI] = {
2248  .s_key = sizeof(struct m0_cob_oikey),
2249  .s_rec = m0_cob_max_nskey_size(),
2250  /* XXX ^^^^^ is it right? */
2251  },
2252  [COB_KVTYPE_BC] = {
2253  .s_key = m0_cob_bckey_size(),
2254  .s_rec = m0_cob_bcrec_size(),
2255  },
2256  };
2257  m0_bcount_t ksize;
2258  m0_bcount_t vsize;
2259 
2262 
2263  ksize = kv_size[t_kvtype].s_key;
2264  vsize = kv_size[t_kvtype].s_rec;
2265 
2266  switch (t_optype) {
2267  case COB_TABLE_DELETE:
2268  m0_be_btree_delete_credit(tree, 1, ksize, vsize, accum);
2269  break;
2270  case COB_TABLE_UPDATE:
2271  m0_be_btree_update_credit(tree, 1, vsize, accum);
2272  break;
2273  case COB_TABLE_INSERT:
2274  m0_be_btree_insert_credit(tree, 1, ksize, vsize, accum);
2275  break;
2276  default:
2277  M0_IMPOSSIBLE("Impossible cob btree optype");
2278  }
2279 }
2280 
2281 M0_INTERNAL void m0_cob_tx_credit(struct m0_cob_domain *dom,
2282  enum m0_cob_op optype,
2283  struct m0_be_tx_credit *accum)
2284 {
2285  int i;
2286 
2287 #define TCREDIT(table, t_optype, t_kvtype, accum) \
2288  cob_table_tx_credit((table), COB_TABLE_##t_optype, \
2289  COB_KVTYPE_##t_kvtype, (accum))
2290 
2291  switch (optype) {
2292  case M0_COB_OP_DOMAIN_MKFS:
2293  TCREDIT(&dom->cd_fileattr_omg, INSERT, OMG, accum);
2294  for (i = 0; i < 2; ++i)
2296  break;
2297  case M0_COB_OP_TRUNCATE:
2298  case M0_COB_OP_LOOKUP:
2299  case M0_COB_OP_LOCATE:
2300  break;
2301  case M0_COB_OP_CREATE:
2303  TCREDIT(&dom->cd_fileattr_basic, INSERT, FAB, accum);
2304  TCREDIT(&dom->cd_fileattr_omg, INSERT, OMG, accum);
2305  break;
2306  case M0_COB_OP_DELETE:
2307  case M0_COB_OP_DELETE_PUT:
2310  TCREDIT(&dom->cd_fileattr_basic, DELETE, FAB, accum);
2311  TCREDIT(&dom->cd_fileattr_omg, DELETE, FAB, accum);
2312  break;
2313  case M0_COB_OP_UPDATE:
2314  TCREDIT(&dom->cd_namespace, UPDATE, NS, accum);
2315  TCREDIT(&dom->cd_fileattr_basic, UPDATE, FAB, accum);
2316  TCREDIT(&dom->cd_fileattr_omg, UPDATE, OMG, accum);
2317  break;
2318  case M0_COB_OP_FEA_SET:
2319  TCREDIT(&dom->cd_fileattr_ea, DELETE, FEA, accum);
2320  TCREDIT(&dom->cd_fileattr_ea, INSERT, FEA, accum);
2321  break;
2322  case M0_COB_OP_FEA_DEL:
2323  TCREDIT(&dom->cd_fileattr_ea, DELETE, FEA, accum);
2324  break;
2325  case M0_COB_OP_NAME_ADD:
2326  TCREDIT(&dom->cd_object_index, INSERT, OI, accum);
2327  TCREDIT(&dom->cd_object_index, DELETE, OI, accum);
2328  TCREDIT(&dom->cd_namespace, INSERT, NS, accum);
2329  break;
2330  case M0_COB_OP_NAME_DEL:
2331  TCREDIT(&dom->cd_namespace, DELETE, NS, accum);
2332  TCREDIT(&dom->cd_object_index, DELETE, OI, accum);
2333  break;
2334  case M0_COB_OP_NAME_UPDATE:
2335  TCREDIT(&dom->cd_namespace, INSERT, NS, accum);
2336  TCREDIT(&dom->cd_namespace, DELETE, NS, accum);
2337  TCREDIT(&dom->cd_object_index, UPDATE, OI, accum);
2338  break;
2340  TCREDIT(&dom->cd_bytecount, INSERT, BC, accum);
2341  break;
2343  TCREDIT(&dom->cd_bytecount, DELETE, BC, accum);
2344  break;
2346  TCREDIT(&dom->cd_bytecount, INSERT, BC, accum);
2347  TCREDIT(&dom->cd_bytecount, DELETE, BC, accum);
2348  TCREDIT(&dom->cd_bytecount, UPDATE, BC, accum);
2349  break;
2350  default:
2351  M0_IMPOSSIBLE("Impossible cob optype");
2352  }
2353 #undef TCREDIT
2354 }
2355 
2356 M0_INTERNAL void m0_cob_ea_get_credit(struct m0_cob *cob,
2357  struct m0_cob_eakey *eakey,
2358  struct m0_cob_earec *out,
2359  struct m0_be_tx_credit *accum)
2360 {
2361  M0_IMPOSSIBLE("-ENOSYS");
2362 }
2363 
2364 M0_INTERNAL void m0_cob_ea_set_credit(struct m0_cob *cob,
2365  struct m0_cob_eakey *eakey,
2366  struct m0_cob_earec *earec,
2367  struct m0_be_tx_credit *accum)
2368 {
2369  M0_IMPOSSIBLE("-ENOSYS");
2370 }
2371 
2372 M0_INTERNAL void m0_cob_ea_del_credit(struct m0_cob *cob,
2373  struct m0_cob_eakey *eakey,
2374  struct m0_be_tx_credit *accum)
2375 {
2376  M0_IMPOSSIBLE("-ENOSYS");
2377 }
2378 
2379 M0_INTERNAL void m0_cob_ea_iterator_init_credit(struct m0_cob *cob,
2380  struct m0_cob_ea_iterator *it,
2381  struct m0_bitstring *name,
2382  struct m0_be_tx_credit *accum)
2383 {
2384  M0_IMPOSSIBLE("-ENOSYS");
2385 }
2386 #endif
2387 
2389 #undef M0_TRACE_SUBSYSTEM
2390 
2391 /*
2392  * Local variables:
2393  * c-indentation-style: "K&R"
2394  * c-basic-offset: 8
2395  * tab-width: 8
2396  * fill-column: 80
2397  * scroll-step: 1
2398  * End:
2399  */
struct m0_cob_nsrec co_nsrec
Definition: cob.h:590
static size_t m0_cob_bckey_size(void)
Definition: cob.c:358
static int m0_cob_max_nskey_make(struct m0_cob_nskey **keyh, const struct m0_fid *pfid, const char *name, int namelen)
Definition: cob.c:303
uint64_t id
Definition: cob.h:240
#define MKFS_ROOT_SIZE
Definition: cob.c:938
static int ea_cmp(const void *key0, const void *key1)
Definition: cob.c:646
#define M0_BE_ALLOC_CREDIT_PTR(ptr, seg, accum)
Definition: alloc.h:355
uint64_t cnr_mtime
Definition: cob.h:435
#define M0_PRE(cond)
static struct m0_be_active_record_domain dummy
Definition: active_record.c:35
#define M0_BE_ALLOC_PTR_SYNC(ptr, seg, tx)
Definition: alloc.h:339
uint32_t cnr_nlink
Definition: cob.h:426
M0_INTERNAL void m0_be_btree_delete_credit(const struct m0_be_btree *tree, m0_bcount_t nr, m0_bcount_t ksize, m0_bcount_t vsize, struct m0_be_tx_credit *accum)
Definition: btree.c:1740
Definition: cob.h:581
static void cob_domain_id2str(char **s, const struct m0_cob_domain_id *cdid)
Definition: cob.c:737
M0_INTERNAL int m0_cob_ea_del(struct m0_cob *cob, struct m0_cob_eakey *eakey, struct m0_be_tx *tx)
Definition: cob.c:2193
M0_INTERNAL int m0_cob_bc_iterator_next(struct m0_cob_bc_iterator *it)
Definition: cob.c:467
static size_t m0_cob_fabrec_size(const struct m0_cob_fabrec *rec)
Definition: cob.c:257
static const struct m0_be_btree_kv_ops cob_ns_ops
Definition: cob.c:348
uint64_t ko_type
Definition: btree.h:97
M0_INTERNAL void m0_format_header_pack(struct m0_format_header *dest, const struct m0_format_tag *src)
Definition: format.c:40
uint64_t cnr_size
Definition: cob.h:430
static const struct m0_be_btree_kv_ops cob_bc_ops
Definition: cob.c:577
int const char const void size_t int flags
Definition: dir.c:328
M0_INTERNAL int m0_cob_domain_mkfs(struct m0_cob_domain *dom, const struct m0_fid *rootfid, struct m0_be_tx *tx)
Definition: cob.c:980
static const uint64_t k1
Definition: hash_fnc.c:34
void m0_be_0type_add_credit(struct m0_be_domain *dom, const struct m0_be_0type *zt, const char *suffix, const struct m0_buf *data, struct m0_be_tx_credit *credit)
Definition: seg0.c:139
#define NULL
Definition: misc.h:38
const char * b0_name
Definition: seg0.h:44
M0_INTERNAL size_t m0_cob_max_earec_size(void)
Definition: cob.c:241
Definition: idx_mock.c:52
uint64_t co_flags
Definition: cob.h:585
struct m0_file co_file
Definition: cob.h:586
#define M0_3WAY(v0, v1)
Definition: arith.h:199
uint64_t cnr_blocks
Definition: cob.h:433
char b_data[0]
Definition: bitstring.h:37
struct m0_be_btree cd_object_index
Definition: cob.h:270
union m0_be_rwlock::@198 bl_u
M0_INTERNAL int m0_cob_ea_get(struct m0_cob *cob, struct m0_cob_eakey *eakey, struct m0_cob_earec *out, struct m0_be_tx *tx)
Definition: cob.c:2155
static M0_UNUSED char * cob_dom_id_make(char *buf, const struct m0_cob_domain_id *id, const char *prefix)
Definition: cob.c:695
struct m0_be_bnode * bb_root
Definition: btree.h:68
static size_t m0_cob_max_fabrec_size(void)
Definition: cob.c:280
void * b_addr
Definition: buf.h:39
M0_INTERNAL void m0_be_btree_lookup(struct m0_be_btree *tree, struct m0_be_op *op, const struct m0_buf *key, struct m0_buf *value)
Definition: btree.c:2033
M0_INTERNAL void m0_cob_iterator_fini(struct m0_cob_iterator *it)
Definition: cob.c:1477
M0_INTERNAL int m0_cob_alloc_omgid(struct m0_cob_domain *dom, uint64_t *omgid)
Definition: cob.c:1634
M0_INTERNAL int m0_cob_mod_init(void)
Definition: cob.c:129
M0_INTERNAL int m0_cob_nskey_cmp(const struct m0_cob_nskey *k0, const struct m0_cob_nskey *k1)
Definition: cob.c:163
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
uint8_t ft_id
Definition: fid.h:101
struct m0_cob_domain * co_dom
Definition: cob.h:582
uint64_t cnr_blksize
Definition: cob.h:432
void m0_be_0type_del_credit(struct m0_be_domain *dom, const struct m0_be_0type *zt, const char *suffix, struct m0_be_tx_credit *credit)
Definition: seg0.c:156
M0_INTERNAL void m0_be_tx_fini(struct m0_be_tx *tx)
Definition: stubs.c:163
M0_INTERNAL int m0_cob_ea_iterator_next(struct m0_cob_ea_iterator *it)
Definition: cob.c:1593
static m0_bcount_t fb_ksize(const void *key)
Definition: cob.c:626
const struct m0_fid * fi_fid
Definition: file.h:88
static struct m0_uint128 prefix
Definition: extmap.c:45
void m0_cob_domain_fini(struct m0_cob_domain *dom)
Definition: cob.c:726
#define M0_BE_OP_SYNC(op_obj, action)
Definition: op.h:190
M0_INTERNAL uint32_t m0_bitstring_len_get(const struct m0_bitstring *c)
Definition: bitstring.c:38
static int cob_table_insert(struct m0_be_btree *tree, struct m0_be_tx *tx, struct m0_buf *key, struct m0_buf *val)
Definition: cob.c:958
M0_INTERNAL void m0_buf_init(struct m0_buf *buf, void *data, uint32_t nob)
Definition: buf.c:37
struct m0_bufvec data
Definition: di.c:40
const struct m0_fid_type m0_cob_fid_type
Definition: cob.c:117
static m0_bcount_t omg_vsize(const void *val)
Definition: cob.c:683
cob_table_kvtype
Definition: cob.c:2213
M0_INTERNAL void m0_cob_put(struct m0_cob *cob)
Definition: cob.c:1095
struct m0_rwlock rwlock
Definition: format.h:208
static struct m0_be_emap_cursor it
Definition: extmap.c:46
M0_INTERNAL void m0_be_tx_prep(struct m0_be_tx *tx, const struct m0_be_tx_credit *credit)
Definition: stubs.c:175
uint64_t cnr_atime
Definition: cob.h:434
#define M0_BE_TX_CAPTURE_PTR(seg, tx, ptr)
Definition: tx.h:505
static m0_bcount_t oi_ksize(const void *key)
Definition: cob.c:600
#define BC(x)
Definition: service_ut.c:1099
M0_INTERNAL int m0_cob_bc_insert(struct m0_cob *cob, struct m0_cob_bckey *bc_key, struct m0_cob_bcrec *bc_val, struct m0_be_tx *tx)
Definition: cob.c:1140
static int oi_cmp(const void *key0, const void *key1)
Definition: cob.c:587
unsigned i_ios_cdom_key
Definition: instance.h:135
uint64_t m0_bcount_t
Definition: types.h:77
M0_INTERNAL int m0_cob_domain_credit_add(struct m0_cob_domain *dom, struct m0_be_domain *bedom, struct m0_be_seg *seg, const struct m0_cob_domain_id *cdid, struct m0_be_tx_credit *cred)
Definition: cob.c:742
M0_INTERNAL struct m0 * m0_get(void)
Definition: instance.c:41
int m0_cob_domain_create(struct m0_cob_domain **dom, struct m0_sm_group *grp, const struct m0_cob_domain_id *cdid, struct m0_be_domain *bedom, struct m0_be_seg *seg)
Definition: cob.c:840
M0_INTERNAL int m0_cob_fabrec_make(struct m0_cob_fabrec **rech, const char *link, size_t linklen)
Definition: cob.c:262
static int void * buf
Definition: dir.c:1019
uint64_t cok_omgid
Definition: cob.h:490
M0_INTERNAL void m0_be_btree_create(struct m0_be_btree *tree, struct m0_be_tx *tx, struct m0_be_op *op, const struct m0_fid *btree_fid)
Definition: btree.c:1512
#define container_of(ptr, type, member)
Definition: misc.h:33
M0_INTERNAL void m0_cob_bc_iterator_fini(struct m0_cob_bc_iterator *it)
Definition: cob.c:489
struct m0_fid cek_fid
Definition: cob.h:504
M0_INTERNAL void m0_be_btree_destroy_credit(struct m0_be_btree *tree, struct m0_be_tx_credit *accum)
Definition: btree.c:1831
M0_INTERNAL int m0_fid_cmp(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:170
struct m0_be_btree cd_fileattr_basic
Definition: cob.h:272
static int cob_omg_lookup(struct m0_cob *cob)
Definition: cob.c:1323
struct m0_be_btree cd_fileattr_ea
Definition: cob.h:274
M0_INTERNAL bool m0_fid_is_set(const struct m0_fid *fid)
Definition: fid.c:106
M0_INTERNAL int m0_cob_name_update(struct m0_cob *cob, struct m0_cob_nskey *srckey, struct m0_cob_nskey *tgtkey, struct m0_be_tx *tx)
Definition: cob.c:2004
static struct m0_cob_domain * cdom
Definition: xform.c:55
m0_cob_op
Definition: cob.h:1068
M0_INTERNAL int m0_cob_size_update(struct m0_cob *cob, uint64_t size, struct m0_be_tx *tx)
Definition: cob.c:2144
#define PRIx64
Definition: types.h:61
M0_INTERNAL int m0_cob_bckey_cmp(const struct m0_cob_bckey *k0, const struct m0_cob_bckey *k1)
Definition: cob.c:399
Definition: sock.c:887
M0_INTERNAL void m0_cob_init(struct m0_cob_domain *dom, struct m0_cob *cob)
Definition: cob.c:1057
static void cob_table_tx_credit(struct m0_be_btree *tree, enum cob_table_optype t_optype, enum cob_table_kvtype t_kvtype, struct m0_be_tx_credit *accum)
Definition: cob.c:2222
uint32_t cnr_cntr
Definition: cob.h:427
M0_INTERNAL void m0_be_btree_delete(struct m0_be_btree *tree, struct m0_be_tx *tx, struct m0_be_op *op, const struct m0_buf *key)
Definition: btree.c:1958
M0_INTERNAL void m0_be_btree_cursor_fini(struct m0_be_btree_cursor *cursor)
Definition: btree.c:2290
M0_INTERNAL void m0_rwlock_init(struct m0_rwlock *lock)
Definition: rwlock.c:32
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 int m0_cob_max_eakey_make(struct m0_cob_eakey **keyh, const struct m0_fid *fid, const char *name, int namelen)
Definition: cob.c:199
struct m0_fid fid
Definition: di.c:46
return M0_RC(rc)
static size_t m0_cob_earec_size(const struct m0_cob_earec *rec)
Definition: cob.c:233
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
op
Definition: libdemo.c:64
static void cob_free_cb(struct m0_ref *ref)
Definition: cob.c:1081
M0_INTERNAL int m0_be_btree_cursor_next_sync(struct m0_be_btree_cursor *cur)
Definition: btree.c:2464
#define M0_ENTRY(...)
Definition: trace.h:170
M0_INTERNAL int m0_cob_ea_set(struct m0_cob *cob, struct m0_cob_eakey *eakey, struct m0_cob_earec *earec, struct m0_be_tx *tx)
Definition: cob.c:2171
static const uint64_t k0
Definition: hash_fnc.c:33
struct m0_cob_nskey * co_nskey
Definition: cob.h:588
Definition: buf.h:37
uint32_t cnr_linkno
Definition: cob.h:420
static int m0_cob_bckey_make(struct m0_cob_bckey **keyh, const struct m0_fid *pver_fid, uint64_t user_id)
Definition: cob.c:384
int i
Definition: dir.c:1033
#define M0_RC_INFO(rc, fmt,...)
Definition: trace.h:209
struct m0_fid cbk_pfid
Definition: cob.h:516
struct m0_cob_fabrec * co_fabrec
Definition: cob.h:591
static int cob_fab_lookup(struct m0_cob *cob)
Definition: cob.c:1292
static int cob_oi_lookup(struct m0_cob *cob)
Definition: cob.c:1219
M0_INTERNAL void m0_ref_put(struct m0_ref *ref)
Definition: refs.c:38
void m0_ref_init(struct m0_ref *ref, int init_num, void(*release)(struct m0_ref *ref))
Definition: refs.c:24
M0_INTERNAL int m0_cob_delete_put(struct m0_cob *cob, struct m0_be_tx *tx)
Definition: cob.c:1853
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL void m0_ref_get(struct m0_ref *ref)
Definition: refs.c:32
M0_INTERNAL void m0_be_btree_update_credit(const struct m0_be_btree *tree, m0_bcount_t nr, m0_bcount_t vsize, struct m0_be_tx_credit *accum)
Definition: btree.c:1750
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
M0_INTERNAL void m0_fid_type_register(const struct m0_fid_type *fidt)
Definition: fid.c:46
#define M0_BE_OP_SYNC_RET(op_obj, action, member)
Definition: op.h:243
M0_INTERNAL void m0_cob_ea_del_credit(struct m0_cob *cob, struct m0_cob_eakey *eakey, struct m0_be_tx_credit *accum)
Definition: cob.c:2372
uint32_t cok_linkno
Definition: cob.h:458
M0_INTERNAL int m0_cob_iterator_next(struct m0_cob_iterator *it)
Definition: cob.c:1512
M0_INTERNAL int m0_cob_ea_iterator_init(struct m0_cob *cob, struct m0_cob_ea_iterator *it, struct m0_bitstring *name)
Definition: cob.c:1539
static int key
Definition: locality.c:283
const char * name
Definition: trace.c:110
M0_INTERNAL void m0_be_btree_create_credit(const struct m0_be_btree *tree, m0_bcount_t nr, struct m0_be_tx_credit *accum)
Definition: btree.c:1783
M0_INTERNAL void m0_be_btree_insert(struct m0_be_btree *tree, struct m0_be_tx *tx, struct m0_be_op *op, const struct m0_buf *key, const struct m0_buf *val)
Definition: btree.c:1932
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
struct m0_be_0type m0_be_cob0
Definition: cob.c:111
Definition: refs.h:34
static void attr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:949
M0_INTERNAL void m0_bitstring_copy(struct m0_bitstring *dst, const char *src, size_t count)
Definition: bitstring.c:63
if(value==NULL)
Definition: dir.c:350
uint64_t cnr_omgid
Definition: cob.h:429
M0_INTERNAL int m0_cob_name_add(struct m0_cob *cob, struct m0_cob_nskey *nskey, struct m0_cob_nsrec *nsrec, struct m0_be_tx *tx)
Definition: cob.c:1924
M0_INTERNAL void m0_be_btree_insert_credit(const struct m0_be_btree *tree, m0_bcount_t nr, m0_bcount_t ksize, m0_bcount_t vsize, struct m0_be_tx_credit *accum)
Definition: btree.c:1720
static size_t m0_cob_bcrec_size(void)
Definition: cob.c:366
struct m0_format_header cnr_header
Definition: cob.h:418
m0_bcount_t b_nob
Definition: buf.h:38
M0_INTERNAL int m0_cob_domain_create_prepared(struct m0_cob_domain **out, struct m0_sm_group *grp, const struct m0_cob_domain_id *cdid, struct m0_be_domain *bedom, struct m0_be_seg *seg, struct m0_be_tx *tx)
Definition: cob.c:763
#define M0_ASSERT(cond)
M0_INTERNAL void m0_be_btree_destroy(struct m0_be_btree *tree, struct m0_be_tx *tx, struct m0_be_op *op)
Definition: btree.c:1538
struct m0_ref co_ref
Definition: cob.h:584
struct m0_bitstring cnk_name
Definition: cob.h:392
static m0_bcount_t bc_ksize(const void *key)
Definition: cob.c:371
struct m0_fid cok_fid
Definition: cob.h:457
static struct m0_cob_domain * dom
Definition: cob.c:40
m0_time_t m0_time_now(void)
Definition: time.c:134
M0_INTERNAL void m0_cob_nsrec_init(struct m0_cob_nsrec *nsrec)
Definition: cob.c:2058
int m0_cob_domain_destroy(struct m0_cob_domain *dom, struct m0_sm_group *grp, struct m0_be_domain *bedom)
Definition: cob.c:871
static const struct m0_be_btree_kv_ops cob_fab_ops
Definition: cob.c:636
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_cob_mod_fini(void)
Definition: cob.c:135
static int key0
Definition: locality.c:282
struct m0_fid cfb_fid
Definition: cob.h:474
static const struct m0_be_btree_kv_ops cob_ea_ops
Definition: cob.c:661
M0_INTERNAL struct m0_be_seg * m0_be_domain_seg(const struct m0_be_domain *dom, const void *addr)
Definition: domain.c:476
unsigned i_mds_cdom_key
Definition: instance.h:137
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
M0_INTERNAL int m0_be_btree_cursor_prev_sync(struct m0_be_btree_cursor *cur)
Definition: btree.c:2472
struct m0_be_rwlock cd_lock
Definition: cob.h:276
M0_INTERNAL void m0_cob_ea_iterator_fini(struct m0_cob_ea_iterator *it)
Definition: cob.c:1620
struct m0_cob_bckey bckey[KEY_VAL_NR]
Definition: bytecount.c:41
uint32_t cor_mode
Definition: cob.h:498
M0_INTERNAL int m0_buf_alloc(struct m0_buf *buf, size_t size)
Definition: buf.c:43
void * m0_alloc(size_t size)
Definition: memory.c:126
uint32_t cor_uid
Definition: cob.h:497
M0_INTERNAL void m0_be_btree_fini(struct m0_be_btree *tree)
Definition: btree.c:1503
M0_INTERNAL int m0_be_tx_exclusive_open_sync(struct m0_be_tx *tx)
Definition: tx.c:594
struct m0_cob_oikey co_oikey
Definition: cob.h:589
#define M0_POST(cond)
M0_INTERNAL int m0_cob_lookup(struct m0_cob_domain *dom, struct m0_cob_nskey *nskey, uint64_t flags, struct m0_cob **out)
Definition: cob.c:1371
cob_table_optype
Definition: cob.c:2207
M0_INTERNAL int m0_bitstring_cmp(const struct m0_bitstring *s1, const struct m0_bitstring *s2)
Definition: bitstring.c:75
Definition: reqh.h:94
M0_INTERNAL int m0_cob_eakey_cmp(const struct m0_cob_eakey *k0, const struct m0_cob_eakey *k1)
Definition: cob.c:215
static m0_bcount_t ns_vsize(const void *val)
Definition: cob.c:343
M0_INTERNAL void m0_fid_type_unregister(const struct m0_fid_type *fidt)
Definition: fid.c:55
M0_INTERNAL void m0_buf_free(struct m0_buf *buf)
Definition: buf.c:55
static void cob_fini(struct m0_cob *cob)
Definition: cob.c:1070
static size_t m0_cob_max_eakey_size(void)
Definition: cob.c:249
uint32_t b_len
Definition: bitstring.h:36
M0_INTERNAL int m0_be_btree_cursor_first_sync(struct m0_be_btree_cursor *cur)
Definition: btree.c:2348
M0_INTERNAL void m0_cob_get(struct m0_cob *cob)
Definition: cob.c:1090
M0_INTERNAL int m0_cob_bc_iterator_init(struct m0_cob *cob, struct m0_cob_bc_iterator *it, const struct m0_fid *pver_fid, uint64_t user_id)
Definition: cob.c:420
M0_INTERNAL void m0_cob_ea_iterator_init_credit(struct m0_cob *cob, struct m0_cob_ea_iterator *it, struct m0_bitstring *name, struct m0_be_tx_credit *accum)
Definition: cob.c:2379
#define M0_BE_FREE_PTR_SYNC(ptr, seg, tx)
Definition: alloc.h:345
Definition: seg.h:66
#define FID_P(f)
Definition: fid.h:77
uint64_t m0_time_seconds(const m0_time_t time)
Definition: time.c:83
static int omg_cmp(const void *key0, const void *key1)
Definition: cob.c:671
int m0_cob_domain_init(struct m0_cob_domain *dom, struct m0_be_seg *seg)
Definition: cob.c:708
static int cob_table_lookup(struct m0_be_btree *tree, struct m0_buf *key, struct m0_buf *out)
Definition: cob.c:966
static const struct m0_be_btree_kv_ops cob_oi_ops
Definition: cob.c:605
M0_INTERNAL void m0_be_btree_cursor_kv_get(struct m0_be_btree_cursor *cur, struct m0_buf *key, struct m0_buf *val)
Definition: btree.c:2485
static m0_bcount_t ea_vsize(const void *val)
Definition: cob.c:656
int m0_be_0type_add(struct m0_be_0type *zt, struct m0_be_domain *dom, struct m0_be_tx *tx, const char *suffix, const struct m0_buf *data)
Definition: seg0.c:79
M0_INTERNAL void m0_be_tx_init(struct m0_be_tx *tx, uint64_t tid, struct m0_be_domain *dom, struct m0_sm_group *sm_group, m0_be_tx_cb_t persistent, m0_be_tx_cb_t discarded, void(*filler)(struct m0_be_tx *tx, void *payload), void *datum)
Definition: stubs.c:150
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
#define M0_COB_NSKEY_LOG(logger, fmt, key,...)
Definition: cob.c:33
M0_INTERNAL void m0_be_btree_update(struct m0_be_btree *tree, struct m0_be_tx *tx, struct m0_be_op *op, const struct m0_buf *key, const struct m0_buf *val)
Definition: btree.c:1941
#define PRIu32
Definition: types.h:66
struct m0_format_header cd_header
Definition: cob.h:263
static m0_bcount_t ns_ksize(const void *key)
Definition: cob.c:338
struct m0_reqh reqh
Definition: rm_foms.c:48
#define M0_BUF_INIT_PTR(p)
Definition: buf.h:69
static int cob_table_delete(struct m0_be_btree *tree, struct m0_be_tx *tx, struct m0_buf *key)
Definition: cob.c:942
#define TCREDIT(table, t_optype, t_kvtype, accum)
static m0_bcount_t fb_vsize(const void *val)
Definition: cob.c:631
Definition: fid.h:38
M0_INTERNAL void m0_format_footer_update(const void *buffer)
Definition: format.c:95
M0_INTERNAL int m0_cob_eakey_make(struct m0_cob_eakey **keyh, const struct m0_fid *fid, const char *name, size_t namelen)
Definition: cob.c:181
#define MKFS_ROOT_BLKSIZE
Definition: cob.c:939
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 void m0_cob_ea_get_credit(struct m0_cob *cob, struct m0_cob_eakey *eakey, struct m0_cob_earec *out, struct m0_be_tx_credit *accum)
Definition: cob.c:2356
int m0_be_0type_del(struct m0_be_0type *zt, struct m0_be_domain *dom, struct m0_be_tx *tx, const char *suffix)
Definition: seg0.c:112
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
uint32_t cer_size
Definition: cob.h:510
#define m0_asprintf(s, fmt,...)
Definition: string.h:44
static int cob_table_update(struct m0_be_btree *tree, struct m0_be_tx *tx, struct m0_buf *key, struct m0_buf *val)
Definition: cob.c:950
static m0_bcount_t omg_ksize(const void *key)
Definition: cob.c:678
struct m0_fop_str s_key
Definition: md_fops.h:398
struct m0_cob_bcrec bcrec[KEY_VAL_NR]
Definition: bytecount.c:42
M0_INTERNAL int m0_cob_bc_iterator_get(struct m0_cob_bc_iterator *it)
Definition: cob.c:443
M0_INTERNAL void * m0_bitstring_buf_get(struct m0_bitstring *c)
Definition: bitstring.c:33
static m0_bcount_t bc_vsize(const void *val)
Definition: cob.c:376
M0_INTERNAL const char M0_COB_ROOT_NAME[]
Definition: md_fid.c:44
m0_bcount_t size
Definition: di.c:39
static int start(struct m0_fom *fom)
Definition: trigger_fom.c:321
struct m0_cob_omgrec co_omgrec
Definition: cob.h:592
M0_INTERNAL int m0_cob_update(struct m0_cob *cob, struct m0_cob_nsrec *nsrec, struct m0_cob_fabrec *fabrec, struct m0_cob_omgrec *omgrec, struct m0_be_tx *tx)
Definition: cob.c:1860
M0_INTERNAL void m0_rwlock_fini(struct m0_rwlock *lock)
Definition: rwlock.c:37
M0_INTERNAL void m0_be_btree_init(struct m0_be_btree *tree, struct m0_be_seg *seg, const struct m0_be_btree_kv_ops *ops)
Definition: btree.c:1487
M0_INTERNAL void m0_be_btree_cursor_init(struct m0_be_btree_cursor *cur, struct m0_be_btree *btree)
Definition: btree.c:2281
M0_INTERNAL int m0_cob_delete(struct m0_cob *cob, struct m0_be_tx *tx)
Definition: cob.c:1789
M0_INTERNAL int m0_cob_iterator_get(struct m0_cob_iterator *it)
Definition: cob.c:1483
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
static struct m0_be_seg * seg
Definition: btree.c:40
static int ns_cmp(const void *key0, const void *key1)
Definition: cob.c:332
#define ENTRY
Definition: m0hsm_api.c:75
M0_INTERNAL int m0_be_btree_cursor_get_sync(struct m0_be_btree_cursor *cur, const struct m0_buf *key, bool slant)
Definition: btree.c:2331
M0_INTERNAL int m0_cob_name_del(struct m0_cob *cob, struct m0_cob_nskey *nskey, struct m0_be_tx *tx)
Definition: cob.c:1966
static int bc_cmp(const void *key0, const void *key1)
Definition: cob.c:414
M0_INTERNAL void m0_cob_ea_set_credit(struct m0_cob *cob, struct m0_cob_eakey *eakey, struct m0_cob_earec *earec, struct m0_be_tx_credit *accum)
Definition: cob.c:2364
static size_t m0_cob_max_nskey_size(void)
Definition: cob.c:324
static m0_bcount_t ea_ksize(const void *key)
Definition: cob.c:651
M0_INTERNAL int m0_cob_alloc(struct m0_cob_domain *dom, struct m0_cob **out)
Definition: cob.c:1100
M0_INTERNAL size_t m0_cob_nskey_size(const struct m0_cob_nskey *cnk)
Definition: cob.c:175
M0_INTERNAL int m0_cob_bc_entries_dump(struct m0_cob_domain *cdom, struct m0_buf **out_keys, struct m0_buf **out_recs, uint32_t *out_count)
Definition: cob.c:496
static int cob0_init(struct m0_be_domain *dom, const char *suffix, const struct m0_buf *data)
Definition: cob.c:72
M0_INTERNAL size_t m0_cob_eakey_size(const struct m0_cob_eakey *cek)
Definition: cob.c:227
#define out(...)
Definition: gen.c:41
struct m0_be_btree cd_fileattr_omg
Definition: cob.h:273
uint32_t cor_gid
Definition: cob.h:499
#define MKFS_ROOT_BLOCKS
Definition: cob.c:940
M0_INTERNAL const struct m0_fid * m0_cob_fid(const struct m0_cob *cob)
Definition: cob.c:122
static bool m0_cob_is_valid(struct m0_cob *cob)
Definition: cob.c:1629
static int m0_cob_max_fabrec_make(struct m0_cob_fabrec **rech)
Definition: cob.c:288
static int cob_ns_lookup(struct m0_cob *cob)
Definition: cob.c:1191
struct m0_bitstring cek_name
Definition: cob.h:505
uint64_t cnr_ctime
Definition: cob.h:436
void m0_free(void *data)
Definition: memory.c:146
uint32_t cfb_linklen
Definition: cob.h:481
static struct m0_addb2_source * s
Definition: consumer.c:39
static int cob_get_fabomg(struct m0_cob *cob, uint64_t flags)
Definition: cob.c:1350
struct m0_be_btree cd_bytecount
Definition: cob.h:275
int32_t rc
Definition: trigger_fop.h:47
struct m0_fid cnk_pfid
Definition: cob.h:391
static struct m0_cob * cob
Definition: cob.c:41
M0_INTERNAL int m0_cob_iterator_init(struct m0_cob *cob, struct m0_cob_iterator *it, struct m0_bitstring *name)
Definition: cob.c:1457
#define M0_BE_FREE_CREDIT_PTR(ptr, seg, accum)
Definition: alloc.h:359
M0_INTERNAL const struct m0_fid M0_COB_ROOT_FID
Definition: md_fid.c:39
struct m0_cob_domain_id cd_id
Definition: cob.h:264
uint64_t cnr_lid
Definition: cob.h:437
static int fb_cmp(const void *key0, const void *key1)
Definition: cob.c:615
static struct m0_sm_group * grp
Definition: cob.c:39
#define FID_F
Definition: fid.h:75
M0_INTERNAL void m0_file_init(struct m0_file *file, const struct m0_fid *fid, struct m0_rm_domain *dom, enum m0_di_types di_type)
Definition: file.c:477
M0_INTERNAL void m0_be_tx_close_sync(struct m0_be_tx *tx)
Definition: stubs.c:205
Definition: tx.h:280
Definition: idx_mock.c:47
M0_INTERNAL int m0_cob_ea_iterator_get(struct m0_cob_ea_iterator *it)
Definition: cob.c:1565
static const struct m0_be_btree_kv_ops cob_omg_ops
Definition: cob.c:688
struct m0_be_btree cd_namespace
Definition: cob.h:271
#define M0_IMPOSSIBLE(fmt,...)
static void cob0_fini(struct m0_be_domain *dom, const char *suffix, const struct m0_buf *data)
Definition: cob.c:104
struct m0_fid cnr_fid
Definition: cob.h:419
char cfb_link[0]
Definition: cob.h:482
#define M0_UNUSED
Definition: misc.h:380